sdc_client 0.158.0 → 0.158.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/ugly.index.js +1 -1
- package/package.json +1 -1
- package/src/simpleDomControl/sdc_model.js +7 -4
package/dist/index.js
CHANGED
|
@@ -74,7 +74,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
74
74
|
\*******************************************/
|
|
75
75
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
76
76
|
|
|
77
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SdcQuerySet: () => (/* binding */ SdcQuerySet),\n/* harmony export */ \"default\": () => (/* binding */ SdcModel)\n/* harmony export */ });\n/* harmony import */ var _sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sdc_utils.js */ \"./src/simpleDomControl/sdc_utils.js\");\n/* harmony import */ var _sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sdc_socket.js */ \"./src/simpleDomControl/sdc_socket.js\");\n/* harmony import */ var _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sdc_main.js */ \"./src/simpleDomControl/sdc_main.js\");\n/* harmony import */ var _sdc_events_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sdc_events.js */ \"./src/simpleDomControl/sdc_events.js\");\n\n\n\n\nconst MAX_FILE_UPLOAD = 25000;\nconst CONNECTING_REQUEST_ID = \"_connecting_process\";\nclass SdcModelError extends Error {\n constructor(props) {\n if (typeof props === 'string') {\n props = {\n msg: props,\n is_error: true,\n header: 'Error'\n };\n }\n super(props.msg);\n this.msg = props.msg;\n this.header = props.header;\n this.is_error = props.is_error;\n this.html = props.html;\n }\n}\nclass FileLoaded {\n constructor({\n name,\n url\n }) {\n this.name = name;\n this.url = url;\n this.content = null;\n }\n async load(force = false) {\n if (force || !this.content) {\n this.content = await new Promise((resolve, reject) => {\n $.get(this.url).then(resolve).catch(() => {\n resolve('');\n });\n });\n }\n return this.content;\n }\n async text() {\n return this.load();\n }\n static isValid(value) {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof File) && typeof value.url === \"string\" && typeof value.name === \"string\";\n }\n}\n\n/**\n * Normalize an incoming primary key value.\n *\n * `-1` is used throughout this module as the sentinel for \"new object / no pk\".\n *\n * @param {*} pk\n * @returns {number}\n */\nfunction normalizePk(pk) {\n const normalizedPk = parseInt(pk ?? -1, 10);\n return Number.isNaN(normalizedPk) ? -1 : normalizedPk;\n}\nclass SdcQuerySet {\n /**\n * Lightweight client-side collection wrapper around the SDC model websocket.\n *\n * The queryset exposes array-like access through a proxy while also keeping\n * track of socket state and outstanding requests for that model.\n *\n * @param {string} modelName\n * @param {object} modelQuery\n */\n constructor(modelName, modelQuery = {}) {\n this.valuesList = [];\n this.loaded = false;\n this.modelName = modelName;\n this.modelQuery = modelQuery ?? {};\n this._onNoOpenRequests = [];\n this._isConnected = false;\n this._isConnectingProcess = false;\n this._autoReconnect = true;\n this.socket = null;\n // Request resolvers are stored by websocket event id until the server responds.\n this.openRequest = {};\n this.modelId = 0;\n this.onUpdate = () => {};\n this.onCreate = () => {};\n return new Proxy(this, {\n get(target, prop) {\n if (typeof prop !== \"symbol\" && !isNaN(prop)) {\n return target.valuesList[prop];\n }\n return target[prop];\n },\n set(target, prop, value) {\n if (!isNaN(prop)) {\n target.valuesList[prop] = value;\n return true;\n }\n target[prop] = value;\n return true;\n }\n });\n }\n [Symbol.iterator]() {\n let idx = -1;\n return {\n next: () => {\n ++idx;\n if (idx < this.valuesList.length) {\n return {\n value: this.valuesList[idx],\n done: false\n };\n }\n return {\n value: null,\n done: true\n };\n }\n };\n }\n set on_create(handler) {\n this.onCreate = handler;\n }\n set on_update(handler) {\n this.onUpdate = handler;\n }\n\n /**\n *\n *\n * @param {Array<integr|string>|integer|SdcModel|SdcQuerySet|string} ids\n */\n setIds(ids) {\n if (ids === null || Array.isArray(ids) && ids.length === 0) {\n this.valuesList = [];\n return this.valuesList;\n } else if (ids instanceof SdcQuerySet) {\n this.valuesList = structuredClone(ids.valuesList);\n this.valuesList.forEach(value => value._setQuerySet(this, true));\n return this.valuesList;\n } else if (ids instanceof SdcModel) {\n this.valuesList = [structuredClone(ids)];\n this.valuesList.forEach(value => value._setQuerySet(this, true));\n return this.valuesList;\n }\n let numList,\n numId = Number.NaN;\n if (Number.isInteger(ids)) {\n numId = ids;\n } else if (ids instanceof Array) {\n const tempNumList = ids.map(x => parseInt(x));\n if (!tempNumList.some(Number.isNaN)) {\n numList = tempNumList;\n }\n } else if (ids instanceof String) {\n const tempNumList = ids.split(',').map(x => parseInt(x));\n if (!tempNumList.some(Number.isNaN)) {\n numList = tempNumList;\n } else {\n numId = parseInt(ids);\n }\n }\n if (!Number.isNaN(numId)) {\n const newModel = this.new();\n newModel.id = numId;\n } else if (numList) {\n this.valuesList = this.valuesList.filter(item => numList.includes(item.id));\n const valueIds = this.getIds();\n numList.filter(x => !valueIds.includes(x)).forEach(id => {\n this.valuesList.push(new ((0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName))({\n id\n }));\n });\n }\n return this.valuesList;\n }\n getIds() {\n return this.valuesList.map(x => x.id);\n }\n\n /**\n * Number of model instances currently present in the queryset cache.\n *\n * @returns {number}\n */\n get length() {\n return this.valuesList.length;\n }\n\n /**\n * Resolve a model instance by id, loading the queryset first if needed.\n *\n * @param {*} id\n * @returns {SdcModel|null}\n */\n byId(id) {\n if (id !== null) {\n const normalizedId = normalizePk(id);\n return this.valuesList.find(elm => elm.id === normalizedId) ?? null;\n }\n return null;\n }\n\n /**\n * Merge additional query constraints into the current queryset.\n *\n * @param {object} modelQuery\n * @returns {SdcQuerySet}\n */\n setFilter(modelQuery) {\n this.modelQuery = modelQuery;\n return this;\n }\n addFilter(modelQuery) {\n this.modelQuery = Object.assign({}, this.modelQuery, modelQuery);\n return this;\n }\n\n /**\n * @param {?object} values\n * @returns {SdcModel}\n */\n new(values = {}) {\n const newModel = new ((0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName))(values);\n newModel._setQuerySet(this, false);\n this.valuesList.push(newModel);\n return newModel;\n }\n\n /**\n * Load model instances matching the current query into the queryset cache.\n *\n * @param {?object} modelQuery\n * @returns {Promise<SdcQuerySet>}\n */\n load(modelQuery = null) {\n this.valuesList = [];\n this.modelQuery = modelQuery ?? this.modelQuery;\n return this._sendLoad();\n }\n\n /**\n * Load model instances matching the current query into the queryset cache.\n *\n * @param {?object} modelQuery\n * @param {?SdcModel} item\n * @returns {Promise<SdcQuerySet>}\n */\n update({\n modelQuery = null,\n item = null\n }) {\n this.modelQuery = modelQuery ?? this.modelQuery;\n let loadQuery = item ? {\n pk: item.id\n } : this.modelQuery;\n return this._sendLoad(loadQuery);\n }\n\n /**\n *\n * @param pk {integr}\n * @param elem {SdcModel}\n * @returns {Promise<unknown>}\n */\n delete({\n pk = null,\n elem = null\n }) {\n pk = !elem ? pk : elem.id;\n if (pk === null) {\n throw new Error(\"pk or elem must be set\");\n }\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return this.isConnected().then(() => {\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"delete\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n pk\n }\n }));\n this.openRequest[id] = [resolve, reject];\n });\n });\n }\n\n /**\n * Request the server-side queryset data over the model websocket.\n *\n * @returns {Promise<*>}\n */\n _sendLoad(loadQuery = null) {\n return this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"load\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: loadQuery ?? this.modelQuery\n }\n }));\n this.openRequest[id] = [data => {\n this.loaded = true;\n resolve(data);\n }, reject];\n });\n });\n }\n\n /**\n * Render the list-view endpoint for the current model.\n *\n * @param {object} options\n * @returns {*}\n */\n _sendListView({\n modelQuery = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this.view({\n modelQuery,\n cbResolve,\n cbReject,\n templateContext,\n eventType: \"list_view\"\n });\n }\n\n /**\n * Render a named model view and append its HTML to a container element.\n *\n * @param {object} options\n * @returns {*}\n */\n view({\n viewName = \"html_list_template\",\n modelQuery = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {},\n eventType = \"named_view\"\n }) {\n let $divList = $('<div class=\"container-fluid\">');\n this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: eventType,\n event_id: id,\n args: {\n view_name: viewName,\n model_name: this.modelName,\n model_query: modelQuery,\n template_context: templateContext\n }\n }));\n this.openRequest[id] = [data => {\n $divList.append(data.html);\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divList);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n });\n return $divList;\n }\n\n /**\n * Render the detail-view endpoint for a single model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _sendDetailView({\n pk = null,\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n pk = normalizePk(pk);\n let $divList = $('<div class=\"container-fluid\">');\n this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"detail_view\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n pk,\n template_context: templateContext\n }\n }));\n this.openRequest[id] = [data => {\n $divList.append(data.html);\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divList);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n });\n return $divList;\n }\n\n /**\n * Fetch a model form fragment and attach the SDC form metadata expected by\n * the rest of the client.\n *\n * @param {string} eventType\n * @param {SdcModel} modelObj\n */\n getForm({\n modelObj,\n eventType,\n formName,\n $divForm,\n cbResolve,\n cbReject,\n formId\n }) {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n const pk = modelObj.id ?? -1;\n this.isConnected().then(() => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: eventType,\n event_id: id,\n args: {\n model_name: this.modelName,\n pk,\n form_name: formName\n }\n }));\n });\n const className = pk === null || pk === -1 ? \"create\" : \"edit\";\n this.openRequest[id] = [data => {\n $divForm.append(data.html);\n let $form = $divForm.closest(\"form\").addClass(`sdc-model-${className}-form sdc-model-form ${formId}`).data(\"model\", modelObj).data(\"model_pk\", pk).data(\"form_name\", formName);\n modelObj.addForm($form);\n if ($form.length > 0 && !$form[0].hasAttribute(\"sdc_submit\")) {\n $form.attr(\"sdc_submit\", \"submitModelFormDistributor\");\n }\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divForm).then(() => null);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n }\n\n /**\n * Fetch a single model instance matching the current query.\n *\n * @param {?object} modelQuery\n * @param {?boolean} doNotLoad true if modelQuery contains id or pk and object does not need to be loaded.\n * @returns {Promise<SdcModel>}\n */\n async get(modelQuery = null, doNotLoad = false) {\n if (doNotLoad) {\n const id = modelQuery?.id ?? modelQuery?.pk;\n return this.byId(id) ?? this.new(modelQuery || this.modelQuery);\n }\n await this.load(modelQuery);\n if (this.length !== 1) {\n throw new Error(`model query returns ${this.length} but only 1 expected.`);\n }\n return this.valuesList[0];\n }\n detailView({\n pk,\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._sendDetailView({\n pk,\n cbResolve,\n cbReject,\n templateContext\n });\n }\n listView({\n modelQuery = {},\n searchValues = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._sendListView({\n modelQuery: Object.assign({}, this.modelQuery, modelQuery, {\n '__search_values': searchValues\n }),\n cbResolve,\n cbReject,\n templateContext\n });\n }\n save({\n pk = null,\n formName = \"edit_form\",\n data = null\n } = {}) {\n const normPk = normalizePk(pk);\n return this.isConnected().then(() => {\n let elemList;\n if (normPk > -1) {\n const elem = this.byId(normPk);\n if (!elem) {\n return Promise.reject(new SdcModelError(`Element not found with ID: ${normPk}`));\n }\n elemList = [elem];\n } else {\n elemList = this.valuesList;\n }\n let pList = [];\n elemList.forEach(elem => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n pList.push(new Promise((resolve, reject) => {\n this._readFiles(elem).then(files => {\n const sendData = data ? {\n ...data\n } : elem.serialize();\n sendData.pk = elem.id;\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"save\",\n event_id: id,\n args: {\n form_name: formName,\n model_name: this.modelName,\n model_query: this.modelQuery,\n data: sendData,\n pk: sendData.pk,\n files: files\n }\n }));\n this.openRequest[id] = [res => {\n let data = typeof res.data.instance === \"string\" ? JSON.parse(res.data.instance) : res.data.instance;\n res.data.instance = this._parseServerRes(data);\n resolve(res);\n }, reject];\n });\n }));\n });\n return Promise.all(pList);\n });\n }\n\n /**\n *\n * @param elem {?SdcModel}\n * @param data {?object}\n * @returns {Promise<unknown>}\n */\n create({\n elem = null,\n data = null\n } = {}) {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n if (!elem) {\n elem = this.new(data);\n }\n return this.isConnected().then(() => {\n return new Promise((resolve, reject) => {\n this._readFiles(elem).then(files => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"create\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n data: data ?? elem?.serialize() ?? {},\n files: files\n }\n }));\n this.openRequest[id] = [res => {\n let data = typeof res.data.instance === \"string\" ? JSON.parse(res.data.instance) : res.data.instance;\n if (elem) {\n elem.id = data[0]?.pk || data[0]?.id;\n }\n res.data.instance = this._parseServerRes(data)[0];\n resolve(res);\n }, reject];\n });\n });\n });\n }\n\n /**\n * Ensure the websocket is open and has completed the server-side connect\n * handshake before issuing model requests.\n *\n * Multiple callers can arrive while a connection attempt is already in\n * progress. In that case they are queued behind the same synthetic request id.\n *\n * @returns {Promise<void>}\n */\n isConnected() {\n return new Promise((resolve, reject) => {\n if (this._isConnected) {\n resolve();\n } else if (!this._isConnectingProcess || !this.openRequest[CONNECTING_REQUEST_ID]) {\n this._isConnectingProcess = true;\n this.openRequest[CONNECTING_REQUEST_ID] = [() => {}, () => {}];\n this._connectToServer().then(() => {\n resolve(this._checkConnection());\n });\n } else {\n const [resolveOrigin, rejectOrigin] = this.openRequest[CONNECTING_REQUEST_ID];\n this.openRequest[CONNECTING_REQUEST_ID] = [() => {\n resolveOrigin();\n resolve();\n }, () => {\n rejectOrigin();\n reject();\n }];\n }\n });\n }\n\n /**\n * Close the websocket and disable automatic reconnect for this queryset.\n */\n close() {\n if (this.socket) {\n this._autoReconnect = false;\n this.socket.onclose = () => {};\n this.socket.close();\n delete this[\"socket\"];\n }\n this.valuesList.forEach(elem => {\n elem._onClose();\n });\n }\n\n /**\n * Upload attached `File` values in fixed-size chunks before save/create calls.\n *\n * @param {SdcModel} elem\n * @returns {Promise<object>}\n */\n _readFiles(elem) {\n let toSolve = [];\n let files = {};\n if (!elem) {\n return Promise.resolve(files);\n }\n Object.keys(elem.constructor.fields).forEach(key => {\n const value = elem[key];\n if (value instanceof File) {\n toSolve.push(new Promise(async (resolve, reject) => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.openRequest[id] = [resolve, reject];\n const buffer = await value.arrayBuffer();\n let result = new Uint8Array(buffer);\n let numberOfChunks = Math.ceil(result.length / MAX_FILE_UPLOAD);\n files[key] = {\n id: id,\n file_name: value.name,\n field_name: key,\n content_length: value.size\n };\n for (let i = 0; i < numberOfChunks; ++i) {\n const chunk = Array.from(result.slice(MAX_FILE_UPLOAD * i, MAX_FILE_UPLOAD * (i + 1)));\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"upload\",\n event_id: id,\n args: {\n chunk,\n idx: i,\n number_of_chunks: numberOfChunks,\n file_name: value.name,\n field_name: key,\n content_length: value.size,\n content_type: value.type,\n model_name: this.modelName,\n model_query: this.modelQuery\n }\n }));\n }\n }));\n }\n });\n return Promise.all(toSolve).then(() => {\n return files;\n });\n }\n\n /**\n * Route websocket responses to the matching pending request and update local\n * state when the server sends model payloads.\n *\n * @param {MessageEvent} e\n */\n async _onMessage(e) {\n let data = JSON.parse(e.data);\n if (data.is_error) {\n if (this.openRequest.hasOwnProperty(data.event_id)) {\n this.openRequest[data.event_id][1](new SdcModelError(data));\n this._closeOpenRequest(data.event_id);\n }\n if (data.msg || data.header) {\n (0,_sdc_events_js__WEBPACK_IMPORTED_MODULE_3__.trigger)(\"pushErrorMsg\", data.header || \"\", data.msg || \"\");\n }\n if (data.type === \"connect\") {\n this.openRequest[CONNECTING_REQUEST_ID][1](new SdcModelError(data));\n this._closeOpenRequest(CONNECTING_REQUEST_ID);\n this._autoReconnect = false;\n this.socket.close();\n }\n } else {\n if (data.msg || data.header) {\n (0,_sdc_events_js__WEBPACK_IMPORTED_MODULE_3__.trigger)(\"pushMsg\", data.header || \"\", data.msg || \"\");\n }\n if (data.type === \"connect\") {\n this._isConnected = true;\n this._isConnectingProcess = false;\n this.openRequest[CONNECTING_REQUEST_ID][0](data);\n this._closeOpenRequest(CONNECTING_REQUEST_ID);\n } else if ([\"load\", \"named_view\", \"detail_view\"].includes(data.type)) {\n const jsonRes = JSON.parse(data.args.data);\n data.args.data = await this._parseServerRes(jsonRes);\n } else if (data.type === \"on_update\" || data.type === \"on_create\") {\n const jsonRes = JSON.parse(data.args.data);\n let obj = await this._parseServerRes(jsonRes);\n let cb;\n if (data.type === \"on_create\") {\n cb = this.onCreate;\n } else {\n cb = this.onUpdate;\n }\n cb(obj);\n data.args.data = obj;\n }\n let instance = data.data?.instance;\n if (instance) {\n data.data.instance = JSON.parse(data.data.instance);\n }\n if (this.openRequest.hasOwnProperty(data.event_id)) {\n this.openRequest[data.event_id][0](data);\n this._closeOpenRequest(data.event_id);\n }\n }\n }\n\n /**\n * Wait until all in-flight websocket requests for this queryset are resolved.\n *\n * @returns {Promise<void>}\n */\n noOpenRequests() {\n return new Promise(resolve => {\n if (Object.keys(this.openRequest).length === 0) {\n return resolve();\n }\n this._onNoOpenRequests.push(resolve);\n });\n }\n\n /**\n * Remove a completed request and wake any `noOpenRequests()` waiters when the\n * request map becomes empty.\n *\n * @param {string} eventId\n */\n _closeOpenRequest(eventId) {\n delete this.openRequest[eventId];\n if (Object.keys(this.openRequest).length === 0) {\n this._onNoOpenRequests.forEach(x => x());\n this._onNoOpenRequests = [];\n }\n }\n\n /**\n * Establish the raw websocket connection for this queryset.\n *\n * @returns {Promise<void>}\n */\n _connectToServer() {\n return new Promise(resolve => {\n const modelIdentifier = `${this.modelName}` + (this.modelId > 0 ? `/${this.modelId}` : \"\");\n if (window.location.protocol === \"https:\") {\n this.socket = new WebSocket(`wss://${window.location.host}/sdc_ws/model/${modelIdentifier}`);\n } else {\n this.socket = new WebSocket(`ws://${window.location.host}/sdc_ws/model/${modelIdentifier}`);\n }\n this.socket.onmessage = this._onMessage.bind(this);\n this.socket.onclose = e => {\n console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`);\n this._isConnected = false;\n for (const [_key, value] of Object.entries(this.openRequest)) {\n value[1](e);\n }\n this.openRequest = {};\n setTimeout(() => {\n if (this._autoReconnect) {\n this._connectToServer().then(() => {});\n }\n }, 1000);\n };\n this.socket.onerror = err => {\n console.error(`Model Socket encountered error: ${err} Closing socket`);\n if (this._isConnected) {\n try {\n this.socket.close();\n } catch (e) {}\n }\n };\n this.socket.onopen = () => {\n resolve();\n };\n });\n }\n\n /**\n * Perform the application-level connect handshake once the websocket opens.\n *\n * @returns {Promise<*>}\n */\n _checkConnection() {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"connect\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery\n }\n }));\n this.openRequest[id] = [resolve, reject];\n });\n }\n\n /**\n * Convert the backend model payload into locally tracked model objects.\n *\n * @param {Array<object>} results\n */\n _parseServerRes(results) {\n const newModels = [];\n for (const x of results) {\n const ModelClass = (0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName);\n const newModel = new ModelClass({\n 'id': x.pk ?? x.id,\n ...x.fields\n });\n const currentModel = this.byId(newModel.id);\n if (currentModel) {\n currentModel.setValues(newModel);\n newModels.push(currentModel);\n } else {\n this.valuesList.push(newModel);\n newModel._setQuerySet(this, true);\n newModels.push(newModel);\n }\n }\n this.valuesList.sort((a, b) => a._id - b._id);\n return newModels;\n }\n}\nclass SdcModel {\n static fields = {};\n\n /**\n * Base model wrapper used by SDC model registrations.\n *\n * @param {string} modelName\n */\n constructor(modelName) {\n this._id = null;\n this._forms = [];\n this.loaded = false;\n this.formId = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.modelName = modelName;\n }\n\n /**\n *\n * @param {object?} modelQuerySet\n * @param {AbstractSDC} parent\n * @returns {SdcQuerySet}\n */\n static querySet(modelQuerySet = null, parent = null) {\n if (!parent) {\n return new SdcQuerySet(this.modeName, modelQuerySet);\n }\n return parent.querySet(this.modeName, modelQuerySet);\n }\n addForm($form) {\n // Remove old listeners if form already set\n const onChange = this._onChange.bind(this);\n this._forms.push($form);\n if ($form) {\n // Attach delegated event handler to all inputs\n $form.on(\"input.formWatcher change.formWatcher\", \"input, select, textarea\", onChange);\n }\n }\n _onChange(event) {\n const {\n name\n } = event.target;\n if (this.constructor.fields[name]) {\n this[`set${name}`]((0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.getValueFromField)(event.target));\n }\n }\n _updateForm(fieldName) {\n const self = this;\n this._forms.forEach($form => {\n $form.find(`[name=\"${fieldName}\"]`).each(function () {\n (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.setValueInField)(this, self[fieldName]);\n });\n });\n }\n setValues(data = {}) {\n throw new Error(\"setValues() must be implemented by subclass\");\n }\n\n /**\n * Attach the queryset that owns this model instance.\n *\n * @param {SdcQuerySet} querySet\n * @param {boolean} isLoaded\n */\n _setQuerySet(querySet, isLoaded) {\n this._querySet = new WeakRef(querySet);\n this.loaded = isLoaded;\n }\n save({\n formName = \"edit_form\",\n data = null\n } = {}) {\n return this._querySet.deref().save({\n pk: this.id,\n formName,\n data\n });\n }\n create({\n data = null\n } = {}) {\n return this._querySet.deref().create({\n elem: this,\n data\n });\n }\n delete() {\n return this._querySet.deref().delete({\n elem: this\n });\n }\n load() {\n return this._querySet.deref().update({\n item: this\n });\n }\n get id() {\n return this._id;\n }\n set pk(data) {\n this._id = data;\n }\n get pk() {\n return this._id;\n }\n close() {\n return this._querySet.deref().close();\n }\n _onClose() {\n Object.keys(this.constructor.fields).filter(x => this[`_${x}`] instanceof SdcQuerySet).forEach(x => this[`_${x}`].close());\n }\n\n /**\n * Request the server-rendered detail view for this model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n detailView({\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._querySet.deref().detailView({\n pk: this.id,\n cbResolve,\n cbReject,\n templateContext\n });\n }\n serialize() {\n return Object.entries(this.constructor.fields).reduce((acc, [key, val]) => {\n const value = this[key];\n if (value instanceof SdcQuerySet) {\n if (val.many_to_many || val.one_to_many) {\n acc[key] = value.getIds();\n } else {\n const allIds = value.getIds();\n if (allIds.length > 0) {\n acc[key] = allIds[0];\n } else {\n acc[key] = null;\n }\n }\n } else if (val.is_relation && value instanceof SdcModel) {\n acc[key] = value.id ?? null;\n } else {\n acc[key] = value;\n }\n return acc;\n }, {});\n }\n toJson() {\n const res = {};\n for (let key in this.constructor.fields) {\n const value = this[key];\n if (value instanceof File) {\n res[key] = value.name;\n } else if (value instanceof SdcModel) {\n res[key] = value.id;\n } else if (value instanceof SdcQuerySet) {\n res[key] = value.getIds();\n } else {\n res[key] = value;\n }\n }\n return res;\n }\n\n /**\n * Backwards-compatible alias for syncing values from a form into the model.\n *\n * @param {*} $forms\n * @returns {*}\n */\n syncFormToModel($forms) {\n return this.syncForm($forms);\n }\n\n /**\n * Resolve the form collection associated with this model instance.\n *\n * @param {*} $forms\n * @returns {*}\n */\n _resolveForms($forms) {\n if (!$forms || !$forms.hasClass(this.formId)) {\n return $(`.${this.formId}`);\n }\n return $forms;\n }\n\n /**\n * Copy the current model state into matching form fields.\n *\n * @param {*} $forms\n */\n syncModelToForm($forms) {\n $forms = this._resolveForms($forms);\n const self = this;\n const fields = this.constructor.fields;\n $forms.each(function () {\n const pk = normalizePk($(this).data(\"model_pk\"));\n if (self.id !== pk) {\n return;\n }\n for (let formItem of this.elements) {\n let name = formItem.name;\n if (name && name !== \"\" && !!fields[name]) {\n (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.setValueInField)(formItem, self[name]);\n }\n }\n });\n }\n\n /**\n * Copy matching form values back onto the current model instance.\n *\n * Hidden inputs are parsed to their original primitive type when possible.\n *\n * @param {*} $forms\n * @returns {*}\n */\n syncForm($forms) {\n $forms = this._resolveForms($forms);\n const self = this;\n const fields = this.constructor.fields;\n const returnValue = {};\n function setValueInForm(name, value) {\n if (!!fields[name]) {\n self[name] = value;\n }\n returnValue[name] = value;\n }\n $forms.each(function () {\n const pk = normalizePk($(this).data(\"model_pk\"));\n if (self.id !== pk && (self.id !== null || pk !== -1)) {\n return;\n }\n for (let formItem of this.elements) {\n setValueInForm(formItem.name, (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.getValueFromField)(formItem));\n }\n return self;\n });\n return returnValue;\n }\n\n /**\n * Render the correct server-side form for this model state.\n *\n * @param {object} options\n * @returns {*}\n */\n form({\n cbResolve = null,\n cbReject = null\n }) {\n if (this.id === null || this.id === -1) {\n return this._createForm({\n cbReject,\n cbResolve\n });\n }\n return this._editForm({\n cbReject,\n cbResolve\n });\n }\n\n /**\n * Render the create form for a new model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _createForm({\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $(\"<div>\");\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"create_form\",\n formName: null,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Render the edit form for an existing model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _editForm({\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $(\"<div>\");\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"edit_form\",\n formName: null,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Render a named server-side form for this model.\n *\n * @param {object} options\n * @returns {*}\n */\n namedForm({\n formName,\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $('<div class=\"container-fluid\">');\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"named_form\",\n formName,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Validate a field value using the supplied field config.\n *\n * @param {*} value\n * @param {object} config\n */\n validate(value, config) {\n const err = validateField(value, config);\n if (err) throw new Error(err);\n }\n\n /**\n * Convert a raw input value into the shape expected by the field config.\n *\n * @param {*} value\n * @param {object} config\n * @returns {*}\n */\n parseValue(value, config) {\n const {\n type\n } = config;\n switch (type) {\n case \"CharField\":\n case \"TeextField\":\n case \"UUIDField\":\n case \"EmailField\":\n return `${value}`;\n case \"IntegerField\":\n case \"AutoField\":\n case \"BigIntegerField\":\n return parseInt(value, 10);\n case \"FloatField\":\n case \"DecimalField\":\n if (typeof value !== \"number\") {\n return \"Must be a number\";\n }\n break;\n case \"BooleanField\":\n return !!value;\n case \"DateField\":\n case \"DateTimeField\":\n return Date.parse(value);\n case \"URLField\":\n return new URL(value);\n case \"FileField\":\n if (value == null) {\n return null;\n }\n if (typeof value === \"string\") {\n return null;\n }\n if (FileLoaded.isValid(value)) {\n return new FileLoaded(value);\n }\n if (value instanceof FileLoaded) {\n return new FileLoaded(value);\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n if (config.max_size && value.size > config.max_size) {\n return `File too large (max ${config.max_size} bytes)`;\n }\n if (config.allowed_types && !config.allowed_types.includes(value.type)) {\n return `Invalid file type (${value.type})`;\n }\n return value;\n }\n break;\n case \"JSONField\":\n if (typeof value === \"object\") {\n return value;\n }\n if (typeof value === \"string\") {\n return JSON.parse(value);\n }\n break;\n default:\n break;\n }\n return value;\n }\n}\n\n/**\n * Validate a field value against the field metadata received from the backend.\n *\n * @param {*} value\n * @param {object} config\n * @returns {?string}\n */\nfunction validateField(value, config) {\n const {\n type,\n required,\n max_length: maxLength,\n is_relation: isRelation,\n many_to_many: manyToMany,\n one_to_many: oneToMany,\n many_to_one: manyToOne,\n one_to_one: oneToOne,\n related_model: relatedModel\n } = config;\n void isRelation;\n if (required) {\n if (value === null || value === undefined || value === \"\") {\n return \"This field is required\";\n }\n }\n if (value === null || value === undefined) {\n return null;\n }\n if (manyToMany || oneToMany || manyToOne || oneToOne) {\n if (!(value instanceof SdcQuerySet) || value.modelName !== relatedModel) {\n if (typeof value !== \"object\" && Number.isNaN(parseInt(value))) {\n return \"Must be object or ID\";\n }\n return null;\n }\n }\n switch (type) {\n case \"CharField\":\n case \"TextField\":\n if (typeof value !== \"string\") {\n return \"Must be a string\";\n }\n if (maxLength && value.length > maxLength) {\n return `Max length is ${maxLength}`;\n }\n break;\n case \"IntegerField\":\n case \"AutoField\":\n case \"BigIntegerField\":\n if (!Number.isInteger(value)) {\n return \"Must be an integer\";\n }\n break;\n case \"FloatField\":\n case \"DecimalField\":\n if (typeof value !== \"number\") {\n return \"Must be a number\";\n }\n break;\n case \"BooleanField\":\n if (typeof value !== \"boolean\") {\n return \"Must be a boolean\";\n }\n break;\n case \"DateField\":\n case \"DateTimeField\":\n if (isNaN(Date.parse(value))) {\n return \"Must be a valid date\";\n }\n break;\n case \"EmailField\":\n if (typeof value !== \"string\" || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n return \"Invalid email\";\n }\n break;\n case \"URLField\":\n try {\n new URL(value);\n } catch {\n return \"Invalid URL\";\n }\n break;\n case \"UUIDField\":\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value)) {\n return \"Invalid UUID\";\n }\n break;\n case \"JSONField\":\n if (typeof value !== \"object\") {\n return \"Must be JSON object\";\n }\n break;\n case \"FileField\":\n if (!FileLoaded.isValid(value) && !(value instanceof File) && !(value instanceof FileLoaded)) {\n return \"Must be a valid file\";\n }\n break;\n default:\n break;\n }\n return null;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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STZPLEdBQUcsQ0FBQzdPLEtBQUssQ0FBQztNQUNoQixDQUFDLENBQUMsTUFBTTtRQUNOLE9BQU8sYUFBYTtNQUN0QjtNQUNBO0lBRUYsS0FBSyxXQUFXO01BQ2QsSUFBSSxDQUFDLDJFQUEyRSxDQUFDNlAsSUFBSSxDQUFDN1AsS0FBSyxDQUFDLEVBQUU7UUFDNUYsT0FBTyxjQUFjO01BQ3ZCO01BQ0E7SUFFRixLQUFLLFdBQVc7TUFDZCxJQUFJLE9BQU9BLEtBQUssS0FBSyxRQUFRLEVBQUU7UUFDN0IsT0FBTyxxQkFBcUI7TUFDOUI7TUFDQTtJQUNGLEtBQUssV0FBVztNQUNkLElBQUksQ0FBQ2YsVUFBVSxDQUFDYyxPQUFPLENBQUNDLEtBQUssQ0FBQyxJQUFJLEVBQUVBLEtBQUssWUFBWUcsSUFBSSxDQUFDLElBQUksRUFBRUgsS0FBSyxZQUFZZixVQUFVLENBQUMsRUFBRTtRQUM1RixPQUFPLHNCQUFzQjtNQUMvQjtNQUNBO0lBQ0Y7TUFDRTtFQUNKO0VBRUEsT0FBTyxJQUFJO0FBQ2IiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9zZGNfY2xpZW50Ly4vc3JjL3NpbXBsZURvbUNvbnRyb2wvc2RjX21vZGVsLmpzPzQ0MzYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtnZXRWYWx1ZUZyb21GaWVsZCwgc2V0VmFsdWVJbkZpZWxkLCB1dWlkdjR9IGZyb20gXCIuL3NkY191dGlscy5qc1wiO1xuaW1wb3J0IHtnZXRNb2RlbH0gZnJvbSBcIi4vc2RjX3NvY2tldC5qc1wiXG5pbXBvcnQge2FwcH0gZnJvbSBcIi4vc2RjX21haW4uanNcIjtcbmltcG9ydCB7dHJpZ2dlcn0gZnJvbSBcIi4vc2RjX2V2ZW50cy5qc1wiO1xuXG5jb25zdCBNQVhfRklMRV9VUExPQUQgPSAyNTAwMDtcbmNvbnN0IENPTk5FQ1RJTkdfUkVRVUVTVF9JRCA9IFwiX2Nvbm5lY3RpbmdfcHJvY2Vzc1wiO1xuXG5jbGFzcyBTZGNNb2RlbEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgIGlmICh0eXBlb2YgcHJvcHMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwcm9wcyA9IHtcbiAgICAgICAgbXNnOiBwcm9wcyxcbiAgICAgICAgaXNfZXJyb3I6IHRydWUsXG4gICAgICAgIGhlYWRlcjogJ0Vycm9yJ1xuICAgICAgfVxuICAgIH1cbiAgICBzdXBlcihwcm9wcy5tc2cpXG4gICAgdGhpcy5tc2cgPSBwcm9wcy5tc2c7XG4gICAgdGhpcy5oZWFkZXIgPSBwcm9wcy5oZWFkZXI7XG4gICAgdGhpcy5pc19lcnJvciA9IHByb3BzLmlzX2Vycm9yO1xuICAgIHRoaXMuaHRtbCA9IHByb3BzLmh0bWw7XG4gIH1cbn1cblxuY2xhc3MgRmlsZUxvYWRlZCB7XG4gIGNvbnN0cnVjdG9yKHtuYW1lLCB1cmx9KSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLmNvbnRlbnQgPSBudWxsO1xuICB9XG5cbiAgYXN5bmMgbG9hZChmb3JjZSA9IGZhbHNlKSB7XG4gICAgaWYgKGZvcmNlIHx8ICF0aGlzLmNvbnRlbnQpIHtcbiAgICAgIHRoaXMuY29udGVudCA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgJC5nZXQodGhpcy51cmwpLnRoZW4ocmVzb2x2ZSkuY2F0Y2goXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZSgnJyk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29udGVudDtcbiAgfVxuXG4gIGFzeW5jIHRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9hZCgpO1xuICB9XG5cbiAgc3RhdGljIGlzVmFsaWQodmFsdWUpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmXG4gICAgICAhKHZhbHVlIGluc3RhbmNlb2YgRmlsZSkgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZS51cmwgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgIHR5cGVvZiB2YWx1ZS5uYW1lID09PSBcInN0cmluZ1wiXG4gICAgKTtcbiAgfVxuXG5cbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgYW4gaW5jb21pbmcgcHJpbWFyeSBrZXkgdmFsdWUuXG4gKlxuICogYC0xYCBpcyB1c2VkIHRocm91Z2hvdXQgdGhpcyBtb2R1bGUgYXMgdGhlIHNlbnRpbmVsIGZvciBcIm5ldyBvYmplY3QgLyBubyBwa1wiLlxuICpcbiAqIEBwYXJhbSB7Kn0gcGtcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVBrKHBrKSB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRQayA9IHBhcnNlSW50KHBrID8/IC0xLCAxMCk7XG4gIHJldHVybiBOdW1iZXIuaXNOYU4obm9ybWFsaXplZFBrKSA/IC0xIDogbm9ybWFsaXplZFBrO1xufVxuXG5leHBvcnQgY2xhc3MgU2RjUXVlcnlTZXQge1xuICAvKipcbiAgICogTGlnaHR3ZWlnaHQgY2xpZW50LXNpZGUgY29sbGVjdGlvbiB3cmFwcGVyIGFyb3VuZCB0aGUgU0RDIG1vZGVsIHdlYnNvY2tldC5cbiAgICpcbiAgICogVGhlIHF1ZXJ5c2V0IGV4cG9zZXMgYXJyYXktbGlrZSBhY2Nlc3MgdGhyb3VnaCBhIHByb3h5IHdoaWxlIGFsc28ga2VlcGluZ1xuICAgKiB0cmFjayBvZiBzb2NrZXQgc3RhdGUgYW5kIG91dHN0YW5kaW5nIHJlcXVlc3RzIGZvciB0aGF0IG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbW9kZWxOYW1lXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtb2RlbFF1ZXJ5XG4gICAqL1xuICBjb25zdHJ1Y3Rvcihtb2RlbE5hbWUsIG1vZGVsUXVlcnkgPSB7fSkge1xuICAgIHRoaXMudmFsdWVzTGlzdCA9IFtdO1xuICAgIHRoaXMubG9hZGVkID0gZmFsc2U7XG4gICAgdGhpcy5tb2RlbE5hbWUgPSBtb2RlbE5hbWU7XG4gICAgdGhpcy5tb2RlbFF1ZXJ5ID0gbW9kZWxRdWVyeSA/PyB7fTtcbiAgICB0aGlzLl9vbk5vT3BlblJlcXVlc3RzID0gW107XG4gICAgdGhpcy5faXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9pc0Nvbm5lY3RpbmdQcm9jZXNzID0gZmFsc2U7XG4gICAgdGhpcy5fYXV0b1JlY29ubmVjdCA9IHRydWU7XG4gICAgdGhpcy5zb2NrZXQgPSBudWxsO1xuICAgIC8vIFJlcXVlc3QgcmVzb2x2ZXJzIGFyZSBzdG9yZWQgYnkgd2Vic29ja2V0IGV2ZW50IGlkIHVudGlsIHRoZSBzZXJ2ZXIgcmVzcG9uZHMuXG4gICAgdGhpcy5vcGVuUmVxdWVzdCA9IHt9O1xuICAgIHRoaXMubW9kZWxJZCA9IDA7XG4gICAgdGhpcy5vblVwZGF0ZSA9ICgpID0+IHtcbiAgICB9O1xuICAgIHRoaXMub25DcmVhdGUgPSAoKSA9PiB7XG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJveHkodGhpcywge1xuICAgICAgZ2V0KHRhcmdldCwgcHJvcCkge1xuICAgICAgICBpZiAodHlwZW9mIHByb3AgIT09IFwic3ltYm9sXCIgJiYgIWlzTmFOKHByb3ApKSB7XG4gICAgICAgICAgcmV0dXJuIHRhcmdldC52YWx1ZXNMaXN0W3Byb3BdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0YXJnZXRbcHJvcF07XG4gICAgICB9LFxuXG4gICAgICBzZXQodGFyZ2V0LCBwcm9wLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIWlzTmFOKHByb3ApKSB7XG4gICAgICAgICAgdGFyZ2V0LnZhbHVlc0xpc3RbcHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0YXJnZXRbcHJvcF0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICBsZXQgaWR4ID0gLTE7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgKytpZHg7XG4gICAgICAgIGlmIChpZHggPCB0aGlzLnZhbHVlc0xpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIHt2YWx1ZTogdGhpcy52YWx1ZXNMaXN0W2lkeF0sIGRvbmU6IGZhbHNlfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge3ZhbHVlOiBudWxsLCBkb25lOiB0cnVlfTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHNldCBvbl9jcmVhdGUoaGFuZGxlcikge1xuICAgIHRoaXMub25DcmVhdGUgPSBoYW5kbGVyO1xuICB9XG5cbiAgc2V0IG9uX3VwZGF0ZShoYW5kbGVyKSB7XG4gICAgdGhpcy5vblVwZGF0ZSA9IGhhbmRsZXI7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxpbnRlZ3J8c3RyaW5nPnxpbnRlZ2VyfFNkY01vZGVsfFNkY1F1ZXJ5U2V0fHN0cmluZ30gaWRzXG4gICAqL1xuICBzZXRJZHMoaWRzKSB7XG5cbiAgICBpZiAoaWRzID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkoaWRzKSAmJiBpZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnZhbHVlc0xpc3QgPSBbXTtcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3Q7XG4gICAgfSBlbHNlIGlmIChpZHMgaW5zdGFuY2VvZiBTZGNRdWVyeVNldCkge1xuICAgICAgdGhpcy52YWx1ZXNMaXN0ID0gc3RydWN0dXJlZENsb25lKGlkcy52YWx1ZXNMaXN0KTtcbiAgICAgIHRoaXMudmFsdWVzTGlzdC5mb3JFYWNoKHZhbHVlID0+IHZhbHVlLl9zZXRRdWVyeVNldCh0aGlzLCB0cnVlKSk7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNMaXN0O1xuICAgIH0gZWxzZSBpZiAoaWRzIGluc3RhbmNlb2YgU2RjTW9kZWwpIHtcbiAgICAgIHRoaXMudmFsdWVzTGlzdCA9IFtzdHJ1Y3R1cmVkQ2xvbmUoaWRzKV07XG4gICAgICB0aGlzLnZhbHVlc0xpc3QuZm9yRWFjaCh2YWx1ZSA9PiB2YWx1ZS5fc2V0UXVlcnlTZXQodGhpcywgdHJ1ZSkpO1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdDtcbiAgICB9XG5cbiAgICBsZXQgbnVtTGlzdCwgbnVtSWQgPSBOdW1iZXIuTmFOO1xuICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKGlkcykpIHtcbiAgICAgIG51bUlkID0gaWRzO1xuICAgIH0gZWxzZSBpZiAoaWRzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGNvbnN0IHRlbXBOdW1MaXN0ID0gaWRzLm1hcCgoeCkgPT4gcGFyc2VJbnQoeCkpO1xuICAgICAgaWYgKCF0ZW1wTnVtTGlzdC5zb21lKE51bWJlci5pc05hTikpIHtcbiAgICAgICAgbnVtTGlzdCA9IHRlbXBOdW1MaXN0O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaWRzIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICBjb25zdCB0ZW1wTnVtTGlzdCA9IGlkcy5zcGxpdCgnLCcpLm1hcCgoeCkgPT4gcGFyc2VJbnQoeCkpO1xuICAgICAgaWYgKCF0ZW1wTnVtTGlzdC5zb21lKE51bWJlci5pc05hTikpIHtcbiAgICAgICAgbnVtTGlzdCA9IHRlbXBOdW1MaXN0XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBudW1JZCA9IHBhcnNlSW50KGlkcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFOdW1iZXIuaXNOYU4obnVtSWQpKSB7XG4gICAgICBjb25zdCBuZXdNb2RlbCA9IHRoaXMubmV3KCk7XG4gICAgICBuZXdNb2RlbC5pZCA9IG51bUlkO1xuICAgIH0gZWxzZSBpZiAobnVtTGlzdCkge1xuICAgICAgdGhpcy52YWx1ZXNMaXN0ID0gdGhpcy52YWx1ZXNMaXN0LmZpbHRlcigoaXRlbSkgPT4gbnVtTGlzdC5pbmNsdWRlcyhpdGVtLmlkKSk7XG4gICAgICBjb25zdCB2YWx1ZUlkcyA9IHRoaXMuZ2V0SWRzKCk7XG4gICAgICBudW1MaXN0LmZpbHRlcih4ID0+ICF2YWx1ZUlkcy5pbmNsdWRlcyh4KSkuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgdGhpcy52YWx1ZXNMaXN0LnB1c2gobmV3IChnZXRNb2RlbCh0aGlzLm1vZGVsTmFtZSkpKHtpZH0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZXNMaXN0O1xuICB9XG5cbiAgZ2V0SWRzKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3QubWFwKHggPT4geC5pZCk7XG4gIH1cblxuICAvKipcbiAgICogTnVtYmVyIG9mIG1vZGVsIGluc3RhbmNlcyBjdXJyZW50bHkgcHJlc2VudCBpbiB0aGUgcXVlcnlzZXQgY2FjaGUuXG4gICAqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3QubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYSBtb2RlbCBpbnN0YW5jZSBieSBpZCwgbG9hZGluZyB0aGUgcXVlcnlzZXQgZmlyc3QgaWYgbmVlZGVkLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IGlkXG4gICAqIEByZXR1cm5zIHtTZGNNb2RlbHxudWxsfVxuICAgKi9cbiAgYnlJZChpZCkge1xuICAgIGlmIChpZCAhPT0gbnVsbCkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZElkID0gbm9ybWFsaXplUGsoaWQpO1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdC5maW5kKChlbG0pID0+IGVsbS5pZCA9PT0gbm9ybWFsaXplZElkKSA/PyBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlIGFkZGl0aW9uYWwgcXVlcnkgY29uc3RyYWludHMgaW50byB0aGUgY3VycmVudCBxdWVyeXNldC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHJldHVybnMge1NkY1F1ZXJ5U2V0fVxuICAgKi9cbiAgc2V0RmlsdGVyKG1vZGVsUXVlcnkpIHtcbiAgICB0aGlzLm1vZGVsUXVlcnkgPSBtb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkRmlsdGVyKG1vZGVsUXVlcnkpIHtcbiAgICB0aGlzLm1vZGVsUXVlcnkgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm1vZGVsUXVlcnksIG1vZGVsUXVlcnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7P29iamVjdH0gdmFsdWVzXG4gICAqIEByZXR1cm5zIHtTZGNNb2RlbH1cbiAgICovXG4gIG5ldyh2YWx1ZXMgPSB7fSkge1xuICAgIGNvbnN0IG5ld01vZGVsID0gbmV3IChnZXRNb2RlbCh0aGlzLm1vZGVsTmFtZSkpKHZhbHVlcyk7XG4gICAgbmV3TW9kZWwuX3NldFF1ZXJ5U2V0KHRoaXMsIGZhbHNlKTtcbiAgICB0aGlzLnZhbHVlc0xpc3QucHVzaChuZXdNb2RlbCk7XG4gICAgcmV0dXJuIG5ld01vZGVsO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbW9kZWwgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5IGludG8gdGhlIHF1ZXJ5c2V0IGNhY2hlLlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHJldHVybnMge1Byb21pc2U8U2RjUXVlcnlTZXQ+fVxuICAgKi9cbiAgbG9hZChtb2RlbFF1ZXJ5ID0gbnVsbCkge1xuICAgIHRoaXMudmFsdWVzTGlzdCA9IFtdO1xuICAgIHRoaXMubW9kZWxRdWVyeSA9IG1vZGVsUXVlcnkgPz8gdGhpcy5tb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzLl9zZW5kTG9hZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbW9kZWwgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5IGludG8gdGhlIHF1ZXJ5c2V0IGNhY2hlLlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHBhcmFtIHs/U2RjTW9kZWx9IGl0ZW1cbiAgICogQHJldHVybnMge1Byb21pc2U8U2RjUXVlcnlTZXQ+fVxuICAgKi9cbiAgdXBkYXRlKHttb2RlbFF1ZXJ5ID0gbnVsbCwgaXRlbSA9IG51bGx9KSB7XG4gICAgdGhpcy5tb2RlbFF1ZXJ5ID0gbW9kZWxRdWVyeSA/PyB0aGlzLm1vZGVsUXVlcnk7XG4gICAgbGV0IGxvYWRRdWVyeSA9IGl0ZW0gPyB7cGs6IGl0ZW0uaWR9IDogdGhpcy5tb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzLl9zZW5kTG9hZChsb2FkUXVlcnkpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBwayB7aW50ZWdyfVxuICAgKiBAcGFyYW0gZWxlbSB7U2RjTW9kZWx9XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHVua25vd24+fVxuICAgKi9cbiAgZGVsZXRlKHtwayA9IG51bGwsIGVsZW0gPSBudWxsfSkge1xuICAgIHBrID0gIWVsZW0gPyBwayA6IGVsZW0uaWQ7XG4gICAgaWYgKHBrID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwayBvciBlbGVtIG11c3QgYmUgc2V0XCIpO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGV2ZW50OiBcIm1vZGVsXCIsXG4gICAgICAgICAgICBldmVudF90eXBlOiBcImRlbGV0ZVwiLFxuICAgICAgICAgICAgZXZlbnRfaWQ6IGlkLFxuICAgICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgbW9kZWxfcXVlcnk6IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgICAgcGssXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW3Jlc29sdmUsIHJlamVjdF07XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRoZSBzZXJ2ZXItc2lkZSBxdWVyeXNldCBkYXRhIG92ZXIgdGhlIG1vZGVsIHdlYnNvY2tldC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAqL1xuICBfc2VuZExvYWQobG9hZFF1ZXJ5ID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJsb2FkXCIsXG4gICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogbG9hZFF1ZXJ5ID8/IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtpZF0gPSBbKGRhdGEpPT4ge1xuICAgICAgICAgIHRoaXMubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9LCByZWplY3RdO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSBsaXN0LXZpZXcgZW5kcG9pbnQgZm9yIHRoZSBjdXJyZW50IG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIF9zZW5kTGlzdFZpZXcoe1xuICAgICAgICAgICAgICAgICAgbW9kZWxRdWVyeSA9IHt9LFxuICAgICAgICAgICAgICAgICAgY2JSZXNvbHZlID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgIGNiUmVqZWN0ID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlQ29udGV4dCA9IHt9LFxuICAgICAgICAgICAgICAgIH0pIHtcbiAgICByZXR1cm4gdGhpcy52aWV3KHtcbiAgICAgIG1vZGVsUXVlcnksXG4gICAgICBjYlJlc29sdmUsXG4gICAgICBjYlJlamVjdCxcbiAgICAgIHRlbXBsYXRlQ29udGV4dCxcbiAgICAgIGV2ZW50VHlwZTogXCJsaXN0X3ZpZXdcIixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgYSBuYW1lZCBtb2RlbCB2aWV3IGFuZCBhcHBlbmQgaXRzIEhUTUwgdG8gYSBjb250YWluZXIgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICB2aWV3KHtcbiAgICAgICAgIHZpZXdOYW1lID0gXCJodG1sX2xpc3RfdGVtcGxhdGVcIixcbiAgICAgICAgIG1vZGVsUXVlcnkgPSB7fSxcbiAgICAgICAgIGNiUmVzb2x2ZSA9IG51bGwsXG4gICAgICAgICBjYlJlamVjdCA9IG51bGwsXG4gICAgICAgICB0ZW1wbGF0ZUNvbnRleHQgPSB7fSxcbiAgICAgICAgIGV2ZW50VHlwZSA9IFwibmFtZWRfdmlld1wiLFxuICAgICAgIH0pIHtcbiAgICBsZXQgJGRpdkxpc3QgPSAkKCc8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG4gICAgdGhpcy5pc0Nvbm5lY3RlZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaWQgPSB1dWlkdjQoKTtcbiAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgIGV2ZW50X3R5cGU6IGV2ZW50VHlwZSxcbiAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgdmlld19uYW1lOiB2aWV3TmFtZSxcbiAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgbW9kZWxfcXVlcnk6IG1vZGVsUXVlcnksXG4gICAgICAgICAgICB0ZW1wbGF0ZV9jb250ZXh0OiB0ZW1wbGF0ZUNvbnRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLm9wZW5SZXF1ZXN0W2lkXSA9IFtcbiAgICAgICAgKGRhdGEpID0+IHtcbiAgICAgICAgICAkZGl2TGlzdC5hcHBlbmQoZGF0YS5odG1sKTtcbiAgICAgICAgICBhcHAucmVmcmVzaCgkZGl2TGlzdCk7XG4gICAgICAgICAgY2JSZXNvbHZlICYmIGNiUmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfSxcbiAgICAgICAgKHJlcykgPT4ge1xuICAgICAgICAgIGNiUmVqZWN0ICYmIGNiUmVqZWN0KHJlcyk7XG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZMaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGV0YWlsLXZpZXcgZW5kcG9pbnQgZm9yIGEgc2luZ2xlIG1vZGVsIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIF9zZW5kRGV0YWlsVmlldyh7XG4gICAgICAgICAgICAgICAgICAgIHBrID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2JSZXNvbHZlID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2JSZWplY3QgPSBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUNvbnRleHQgPSB7fSxcbiAgICAgICAgICAgICAgICAgIH0pIHtcbiAgICBwayA9IG5vcm1hbGl6ZVBrKHBrKTtcbiAgICBsZXQgJGRpdkxpc3QgPSAkKCc8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG5cbiAgICB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIGV2ZW50OiBcIm1vZGVsXCIsXG4gICAgICAgICAgZXZlbnRfdHlwZTogXCJkZXRhaWxfdmlld1wiLFxuICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgIG1vZGVsX3F1ZXJ5OiB0aGlzLm1vZGVsUXVlcnksXG4gICAgICAgICAgICBwayxcbiAgICAgICAgICAgIHRlbXBsYXRlX2NvbnRleHQ6IHRlbXBsYXRlQ29udGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAoZGF0YSkgPT4ge1xuICAgICAgICAgICRkaXZMaXN0LmFwcGVuZChkYXRhLmh0bWwpO1xuICAgICAgICAgIGFwcC5yZWZyZXNoKCRkaXZMaXN0KTtcbiAgICAgICAgICBjYlJlc29sdmUgJiYgY2JSZXNvbHZlKGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICAocmVzKSA9PiB7XG4gICAgICAgICAgY2JSZWplY3QgJiYgY2JSZWplY3QocmVzKTtcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgfSk7XG5cbiAgICByZXR1cm4gJGRpdkxpc3Q7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYSBtb2RlbCBmb3JtIGZyYWdtZW50IGFuZCBhdHRhY2ggdGhlIFNEQyBmb3JtIG1ldGFkYXRhIGV4cGVjdGVkIGJ5XG4gICAqIHRoZSByZXN0IG9mIHRoZSBjbGllbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFR5cGVcbiAgICogQHBhcmFtIHtTZGNNb2RlbH0gbW9kZWxPYmpcbiAgICovXG4gIGdldEZvcm0oe21vZGVsT2JqLCBldmVudFR5cGUsIGZvcm1OYW1lLCAkZGl2Rm9ybSwgY2JSZXNvbHZlLCBjYlJlamVjdCwgZm9ybUlkfSkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgY29uc3QgcGsgPSBtb2RlbE9iai5pZCA/PyAtMTtcbiAgICB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgZXZlbnQ6IFwibW9kZWxcIixcbiAgICAgICAgICBldmVudF90eXBlOiBldmVudFR5cGUsXG4gICAgICAgICAgZXZlbnRfaWQ6IGlkLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgcGssXG4gICAgICAgICAgICBmb3JtX25hbWU6IGZvcm1OYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHBrID09PSBudWxsIHx8IHBrID09PSAtMSA/IFwiY3JlYXRlXCIgOiBcImVkaXRcIjtcblxuICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgKGRhdGEpID0+IHtcbiAgICAgICAgJGRpdkZvcm0uYXBwZW5kKGRhdGEuaHRtbCk7XG4gICAgICAgIGxldCAkZm9ybSA9ICRkaXZGb3JtXG4gICAgICAgICAgLmNsb3Nlc3QoXCJmb3JtXCIpXG4gICAgICAgICAgLmFkZENsYXNzKFxuICAgICAgICAgICAgYHNkYy1tb2RlbC0ke2NsYXNzTmFtZX0tZm9ybSBzZGMtbW9kZWwtZm9ybSAke2Zvcm1JZH1gLFxuICAgICAgICAgIClcbiAgICAgICAgICAuZGF0YShcIm1vZGVsXCIsIG1vZGVsT2JqKVxuICAgICAgICAgIC5kYXRhKFwibW9kZWxfcGtcIiwgcGspXG4gICAgICAgICAgLmRhdGEoXCJmb3JtX25hbWVcIiwgZm9ybU5hbWUpO1xuICAgICAgICBtb2RlbE9iai5hZGRGb3JtKCRmb3JtKTtcbiAgICAgICAgaWYgKCRmb3JtLmxlbmd0aCA+IDAgJiYgISRmb3JtWzBdLmhhc0F0dHJpYnV0ZShcInNkY19zdWJtaXRcIikpIHtcbiAgICAgICAgICAkZm9ybS5hdHRyKFwic2RjX3N1Ym1pdFwiLCBcInN1Ym1pdE1vZGVsRm9ybURpc3RyaWJ1dG9yXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXBwLnJlZnJlc2goJGRpdkZvcm0pLnRoZW4oKCkgPT4gbnVsbCk7XG4gICAgICAgIGNiUmVzb2x2ZSAmJiBjYlJlc29sdmUoZGF0YSk7XG4gICAgICB9LFxuICAgICAgKHJlcykgPT4ge1xuICAgICAgICBjYlJlamVjdCAmJiBjYlJlamVjdChyZXMpO1xuICAgICAgfSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGEgc2luZ2xlIG1vZGVsIGluc3RhbmNlIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5LlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHBhcmFtIHs/Ym9vbGVhbn0gZG9Ob3RMb2FkIHRydWUgaWYgbW9kZWxRdWVyeSBjb250YWlucyBpZCBvciBwayBhbmQgb2JqZWN0IGRvZXMgbm90IG5lZWQgdG8gYmUgbG9hZGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTZGNNb2RlbD59XG4gICAqL1xuICBhc3luYyBnZXQobW9kZWxRdWVyeSA9IG51bGwsIGRvTm90TG9hZCA9IGZhbHNlKSB7XG4gICAgaWYgKGRvTm90TG9hZCkge1xuICAgICAgY29uc3QgaWQgPSBtb2RlbFF1ZXJ5Py5pZCA/PyBtb2RlbFF1ZXJ5Py5waztcbiAgICAgIHJldHVybiB0aGlzLmJ5SWQoaWQpID8/IHRoaXMubmV3KG1vZGVsUXVlcnkgfHwgdGhpcy5tb2RlbFF1ZXJ5KTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5sb2FkKG1vZGVsUXVlcnkpO1xuICAgIGlmICh0aGlzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtb2RlbCBxdWVyeSByZXR1cm5zICR7dGhpcy5sZW5ndGh9IGJ1dCBvbmx5IDEgZXhwZWN0ZWQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdFswXTtcbiAgfVxuXG4gIGRldGFpbFZpZXcoe3BrLCBjYlJlc29sdmUgPSBudWxsLCBjYlJlamVjdCA9IG51bGwsIHRlbXBsYXRlQ29udGV4dCA9IHt9fSkge1xuICAgIHJldHVybiB0aGlzLl9zZW5kRGV0YWlsVmlldyh7XG4gICAgICBwayxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgdGVtcGxhdGVDb250ZXh0LFxuICAgIH0pO1xuICB9XG5cbiAgbGlzdFZpZXcoe21vZGVsUXVlcnkgPSB7fSwgc2VhcmNoVmFsdWVzID0ge30sIGNiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbCwgdGVtcGxhdGVDb250ZXh0ID0ge319KSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRMaXN0Vmlldyh7XG4gICAgICBtb2RlbFF1ZXJ5OiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm1vZGVsUXVlcnksIG1vZGVsUXVlcnksIHsgJ19fc2VhcmNoX3ZhbHVlcyc6IHNlYXJjaFZhbHVlcyB9KSxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgdGVtcGxhdGVDb250ZXh0LFxuICAgIH0pO1xuICB9XG5cbiAgc2F2ZSh7cGsgPSBudWxsLCBmb3JtTmFtZSA9IFwiZWRpdF9mb3JtXCIsIGRhdGEgPSBudWxsfSA9IHt9KSB7XG4gICAgY29uc3Qgbm9ybVBrID0gbm9ybWFsaXplUGsocGspO1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBsZXQgZWxlbUxpc3Q7XG4gICAgICBpZiAobm9ybVBrID4gLTEpIHtcbiAgICAgICAgY29uc3QgZWxlbSA9IHRoaXMuYnlJZChub3JtUGspO1xuICAgICAgICBpZiAoIWVsZW0pIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFNkY01vZGVsRXJyb3IoYEVsZW1lbnQgbm90IGZvdW5kIHdpdGggSUQ6ICR7bm9ybVBrfWApKTtcbiAgICAgICAgfVxuICAgICAgICBlbGVtTGlzdCA9IFtlbGVtXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1MaXN0ID0gdGhpcy52YWx1ZXNMaXN0O1xuICAgICAgfVxuICAgICAgbGV0IHBMaXN0ID0gW107XG4gICAgICBlbGVtTGlzdC5mb3JFYWNoKChlbGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgICAgIHBMaXN0LnB1c2goXG4gICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcmVhZEZpbGVzKGVsZW0pLnRoZW4oKGZpbGVzKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHNlbmREYXRhID0gZGF0YSA/IHsuLi5kYXRhfSA6IGVsZW0uc2VyaWFsaXplKCk7XG4gICAgICAgICAgICAgIHNlbmREYXRhLnBrID0gZWxlbS5pZDtcbiAgICAgICAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJzYXZlXCIsXG4gICAgICAgICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1fbmFtZTogZm9ybU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogdGhpcy5tb2RlbFF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiBzZW5kRGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGs6IHNlbmREYXRhLnBrLFxuICAgICAgICAgICAgICAgICAgICBmaWxlczogZmlsZXMsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAgICAgICAgIChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxldCBkYXRhID1cbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHJlcy5kYXRhLmluc3RhbmNlID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgPyBKU09OLnBhcnNlKHJlcy5kYXRhLmluc3RhbmNlKVxuICAgICAgICAgICAgICAgICAgICAgIDogcmVzLmRhdGEuaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgICByZXMuZGF0YS5pbnN0YW5jZSA9IHRoaXMuX3BhcnNlU2VydmVyUmVzKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVqZWN0LFxuICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHBMaXN0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gZWxlbSB7P1NkY01vZGVsfVxuICAgKiBAcGFyYW0gZGF0YSB7P29iamVjdH1cbiAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAqL1xuICBjcmVhdGUoe2VsZW0gPSBudWxsLCBkYXRhID0gbnVsbH0gPSB7fSkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgaWYgKCFlbGVtKSB7XG4gICAgICBlbGVtID0gdGhpcy5uZXcoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLl9yZWFkRmlsZXMoZWxlbSkudGhlbigoZmlsZXMpID0+IHtcbiAgICAgICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICBldmVudF90eXBlOiBcImNyZWF0ZVwiLFxuICAgICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogdGhpcy5tb2RlbFF1ZXJ5LFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgPz8gZWxlbT8uc2VyaWFsaXplKCkgPz8ge30sXG4gICAgICAgICAgICAgICAgZmlsZXM6IGZpbGVzLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAgICAgKHJlcykgPT4ge1xuICAgICAgICAgICAgICBsZXQgZGF0YSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHJlcy5kYXRhLmluc3RhbmNlID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICA/IEpTT04ucGFyc2UocmVzLmRhdGEuaW5zdGFuY2UpXG4gICAgICAgICAgICAgICAgICA6IHJlcy5kYXRhLmluc3RhbmNlO1xuICAgICAgICAgICAgICBpZiAoZWxlbSkge1xuICAgICAgICAgICAgICAgIGVsZW0uaWQgPSBkYXRhWzBdPy5wayB8fCBkYXRhWzBdPy5pZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXMuZGF0YS5pbnN0YW5jZSA9IHRoaXMuX3BhcnNlU2VydmVyUmVzKGRhdGEpWzBdO1xuICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVqZWN0LFxuICAgICAgICAgIF07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlIHRoZSB3ZWJzb2NrZXQgaXMgb3BlbiBhbmQgaGFzIGNvbXBsZXRlZCB0aGUgc2VydmVyLXNpZGUgY29ubmVjdFxuICAgKiBoYW5kc2hha2UgYmVmb3JlIGlzc3VpbmcgbW9kZWwgcmVxdWVzdHMuXG4gICAqXG4gICAqIE11bHRpcGxlIGNhbGxlcnMgY2FuIGFycml2ZSB3aGlsZSBhIGNvbm5lY3Rpb24gYXR0ZW1wdCBpcyBhbHJlYWR5IGluXG4gICAqIHByb2dyZXNzLiBJbiB0aGF0IGNhc2UgdGhleSBhcmUgcXVldWVkIGJlaGluZCB0aGUgc2FtZSBzeW50aGV0aWMgcmVxdWVzdCBpZC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2lzQ29ubmVjdGVkKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICF0aGlzLl9pc0Nvbm5lY3RpbmdQcm9jZXNzIHx8XG4gICAgICAgICF0aGlzLm9wZW5SZXF1ZXN0W0NPTk5FQ1RJTkdfUkVRVUVTVF9JRF1cbiAgICAgICkge1xuICAgICAgICB0aGlzLl9pc0Nvbm5lY3RpbmdQcm9jZXNzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtDT05ORUNUSU5HX1JFUVVFU1RfSURdID0gWygpID0+IHtcbiAgICAgICAgfSwgKCkgPT4ge1xuICAgICAgICB9XTtcbiAgICAgICAgdGhpcy5fY29ubmVjdFRvU2VydmVyKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVzb2x2ZSh0aGlzLl9jaGVja0Nvbm5lY3Rpb24oKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgW3Jlc29sdmVPcmlnaW4sIHJlamVjdE9yaWdpbl0gPVxuICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbQ09OTkVDVElOR19SRVFVRVNUX0lEXTtcbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtDT05ORUNUSU5HX1JFUVVFU1RfSURdID0gW1xuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVPcmlnaW4oKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlamVjdE9yaWdpbigpO1xuICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgd2Vic29ja2V0IGFuZCBkaXNhYmxlIGF1dG9tYXRpYyByZWNvbm5lY3QgZm9yIHRoaXMgcXVlcnlzZXQuXG4gICAqL1xuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5zb2NrZXQpIHtcbiAgICAgIHRoaXMuX2F1dG9SZWNvbm5lY3QgPSBmYWxzZTtcbiAgICAgIHRoaXMuc29ja2V0Lm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5zb2NrZXQuY2xvc2UoKTtcbiAgICAgIGRlbGV0ZSB0aGlzW1wic29ja2V0XCJdO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWVzTGlzdC5mb3JFYWNoKChlbGVtKSA9PiB7XG4gICAgICBlbGVtLl9vbkNsb3NlKClcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGxvYWQgYXR0YWNoZWQgYEZpbGVgIHZhbHVlcyBpbiBmaXhlZC1zaXplIGNodW5rcyBiZWZvcmUgc2F2ZS9jcmVhdGUgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U2RjTW9kZWx9IGVsZW1cbiAgICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn1cbiAgICovXG4gIF9yZWFkRmlsZXMoZWxlbSkge1xuICAgIGxldCB0b1NvbHZlID0gW107XG4gICAgbGV0IGZpbGVzID0ge307XG4gICAgaWYgKCFlbGVtKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZpbGVzKTtcbiAgICB9XG4gICAgT2JqZWN0LmtleXMoZWxlbS5jb25zdHJ1Y3Rvci5maWVsZHMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBlbGVtW2tleV07XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgIHRvU29sdmUucHVzaChcbiAgICAgICAgICBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtpZF0gPSBbcmVzb2x2ZSwgcmVqZWN0XTtcblxuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgdmFsdWUuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICAgICAgICAgICAgbGV0IG51bWJlck9mQ2h1bmtzID0gTWF0aC5jZWlsKHJlc3VsdC5sZW5ndGggLyBNQVhfRklMRV9VUExPQUQpO1xuICAgICAgICAgICAgZmlsZXNba2V5XSA9IHtcbiAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICBmaWxlX25hbWU6IHZhbHVlLm5hbWUsXG4gICAgICAgICAgICAgIGZpZWxkX25hbWU6IGtleSxcbiAgICAgICAgICAgICAgY29udGVudF9sZW5ndGg6IHZhbHVlLnNpemUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNodW5rczsgKytpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNodW5rID0gQXJyYXkuZnJvbShyZXN1bHQuc2xpY2UoXG4gICAgICAgICAgICAgICAgTUFYX0ZJTEVfVVBMT0FEICogaSxcbiAgICAgICAgICAgICAgICBNQVhfRklMRV9VUExPQUQgKiAoaSArIDEpLFxuICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJ1cGxvYWRcIixcbiAgICAgICAgICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmssXG4gICAgICAgICAgICAgICAgICAgIGlkeDogaSxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyX29mX2NodW5rczogbnVtYmVyT2ZDaHVua3MsXG4gICAgICAgICAgICAgICAgICAgIGZpbGVfbmFtZTogdmFsdWUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmllbGRfbmFtZToga2V5LFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50X2xlbmd0aDogdmFsdWUuc2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudF90eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxfcXVlcnk6IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwodG9Tb2x2ZSkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZmlsZXM7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUm91dGUgd2Vic29ja2V0IHJlc3BvbnNlcyB0byB0aGUgbWF0Y2hpbmcgcGVuZGluZyByZXF1ZXN0IGFuZCB1cGRhdGUgbG9jYWxcbiAgICogc3RhdGUgd2hlbiB0aGUgc2VydmVyIHNlbmRzIG1vZGVsIHBheWxvYWRzLlxuICAgKlxuICAgKiBAcGFyYW0ge01lc3NhZ2VFdmVudH0gZVxuICAgKi9cbiAgYXN5bmMgX29uTWVzc2FnZShlKSB7XG4gICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGUuZGF0YSk7XG4gICAgaWYgKGRhdGEuaXNfZXJyb3IpIHtcbiAgICAgIGlmICh0aGlzLm9wZW5SZXF1ZXN0Lmhhc093blByb3BlcnR5KGRhdGEuZXZlbnRfaWQpKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbZGF0YS5ldmVudF9pZF1bMV0obmV3IFNkY01vZGVsRXJyb3IoZGF0YSkpO1xuICAgICAgICB0aGlzLl9jbG9zZU9wZW5SZXF1ZXN0KGRhdGEuZXZlbnRfaWQpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGEubXNnIHx8IGRhdGEuaGVhZGVyKSB7XG4gICAgICAgIHRyaWdnZXIoXCJwdXNoRXJyb3JNc2dcIiwgZGF0YS5oZWFkZXIgfHwgXCJcIiwgZGF0YS5tc2cgfHwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLnR5cGUgPT09IFwiY29ubmVjdFwiKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbQ09OTkVDVElOR19SRVFVRVNUX0lEXVsxXShuZXcgU2RjTW9kZWxFcnJvcihkYXRhKSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoQ09OTkVDVElOR19SRVFVRVNUX0lEKTtcbiAgICAgICAgdGhpcy5fYXV0b1JlY29ubmVjdCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNvY2tldC5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGF0YS5tc2cgfHwgZGF0YS5oZWFkZXIpIHtcbiAgICAgICAgdHJpZ2dlcihcInB1c2hNc2dcIiwgZGF0YS5oZWFkZXIgfHwgXCJcIiwgZGF0YS5tc2cgfHwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLnR5cGUgPT09IFwiY29ubmVjdFwiKSB7XG4gICAgICAgIHRoaXMuX2lzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5faXNDb25uZWN0aW5nUHJvY2VzcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9wZW5SZXF1ZXN0W0NPTk5FQ1RJTkdfUkVRVUVTVF9JRF1bMF0oZGF0YSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoQ09OTkVDVElOR19SRVFVRVNUX0lEKTtcbiAgICAgIH0gZWxzZSBpZiAoW1wibG9hZFwiLCBcIm5hbWVkX3ZpZXdcIiwgXCJkZXRhaWxfdmlld1wiXS5pbmNsdWRlcyhkYXRhLnR5cGUpKSB7XG4gICAgICAgIGNvbnN0IGpzb25SZXMgPSBKU09OLnBhcnNlKGRhdGEuYXJncy5kYXRhKTtcbiAgICAgICAgZGF0YS5hcmdzLmRhdGEgPSBhd2FpdCB0aGlzLl9wYXJzZVNlcnZlclJlcyhqc29uUmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09PSBcIm9uX3VwZGF0ZVwiIHx8IGRhdGEudHlwZSA9PT0gXCJvbl9jcmVhdGVcIikge1xuICAgICAgICBjb25zdCBqc29uUmVzID0gSlNPTi5wYXJzZShkYXRhLmFyZ3MuZGF0YSk7XG5cbiAgICAgICAgbGV0IG9iaiA9IGF3YWl0IHRoaXMuX3BhcnNlU2VydmVyUmVzKGpzb25SZXMpO1xuICAgICAgICBsZXQgY2I7XG5cbiAgICAgICAgaWYgKGRhdGEudHlwZSA9PT0gXCJvbl9jcmVhdGVcIikge1xuICAgICAgICAgIGNiID0gdGhpcy5vbkNyZWF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYiA9IHRoaXMub25VcGRhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjYihvYmopO1xuICAgICAgICBkYXRhLmFyZ3MuZGF0YSA9IG9iajtcbiAgICAgIH1cblxuICAgICAgbGV0IGluc3RhbmNlID0gZGF0YS5kYXRhPy5pbnN0YW5jZTtcbiAgICAgIGlmIChpbnN0YW5jZSkge1xuICAgICAgICBkYXRhLmRhdGEuaW5zdGFuY2UgPSBKU09OLnBhcnNlKGRhdGEuZGF0YS5pbnN0YW5jZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9wZW5SZXF1ZXN0Lmhhc093blByb3BlcnR5KGRhdGEuZXZlbnRfaWQpKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbZGF0YS5ldmVudF9pZF1bMF0oZGF0YSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoZGF0YS5ldmVudF9pZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdhaXQgdW50aWwgYWxsIGluLWZsaWdodCB3ZWJzb2NrZXQgcmVxdWVzdHMgZm9yIHRoaXMgcXVlcnlzZXQgYXJlIHJlc29sdmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIG5vT3BlblJlcXVlc3RzKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMub3BlblJlcXVlc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9vbk5vT3BlblJlcXVlc3RzLnB1c2gocmVzb2x2ZSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgY29tcGxldGVkIHJlcXVlc3QgYW5kIHdha2UgYW55IGBub09wZW5SZXF1ZXN0cygpYCB3YWl0ZXJzIHdoZW4gdGhlXG4gICAqIHJlcXVlc3QgbWFwIGJlY29tZXMgZW1wdHkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudElkXG4gICAqL1xuICBfY2xvc2VPcGVuUmVxdWVzdChldmVudElkKSB7XG4gICAgZGVsZXRlIHRoaXMub3BlblJlcXVlc3RbZXZlbnRJZF07XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMub3BlblJlcXVlc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5fb25Ob09wZW5SZXF1ZXN0cy5mb3JFYWNoKCh4KSA9PiB4KCkpO1xuICAgICAgdGhpcy5fb25Ob09wZW5SZXF1ZXN0cyA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFc3RhYmxpc2ggdGhlIHJhdyB3ZWJzb2NrZXQgY29ubmVjdGlvbiBmb3IgdGhpcyBxdWVyeXNldC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBfY29ubmVjdFRvU2VydmVyKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgbW9kZWxJZGVudGlmaWVyID1cbiAgICAgICAgYCR7dGhpcy5tb2RlbE5hbWV9YCArICh0aGlzLm1vZGVsSWQgPiAwID8gYC8ke3RoaXMubW9kZWxJZH1gIDogXCJcIik7XG4gICAgICBpZiAod2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSBcImh0dHBzOlwiKSB7XG4gICAgICAgIHRoaXMuc29ja2V0ID0gbmV3IFdlYlNvY2tldChcbiAgICAgICAgICBgd3NzOi8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0vc2RjX3dzL21vZGVsLyR7bW9kZWxJZGVudGlmaWVyfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQoXG4gICAgICAgICAgYHdzOi8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0vc2RjX3dzL21vZGVsLyR7bW9kZWxJZGVudGlmaWVyfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc29ja2V0Lm9ubWVzc2FnZSA9IHRoaXMuX29uTWVzc2FnZS5iaW5kKHRoaXMpO1xuXG4gICAgICB0aGlzLnNvY2tldC5vbmNsb3NlID0gKGUpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgU0RDIE1vZGVsICgke3RoaXMubW9kZWxOYW1lfSwgJHt0aGlzLm1vZGVsSWR9KSBTb2NrZXQgY2xvc2VkIHVuZXhwZWN0ZWRseWAsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX2lzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgW19rZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLm9wZW5SZXF1ZXN0KSkge1xuICAgICAgICAgIHZhbHVlWzFdKGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3QgPSB7fTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5fYXV0b1JlY29ubmVjdCkge1xuICAgICAgICAgICAgdGhpcy5fY29ubmVjdFRvU2VydmVyKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDEwMDApO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5zb2NrZXQub25lcnJvciA9IChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgTW9kZWwgU29ja2V0IGVuY291bnRlcmVkIGVycm9yOiAke2Vycn0gQ2xvc2luZyBzb2NrZXRgKTtcbiAgICAgICAgaWYgKHRoaXMuX2lzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuc29ja2V0LmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgdGhpcy5zb2NrZXQub25vcGVuID0gKCkgPT4ge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gdGhlIGFwcGxpY2F0aW9uLWxldmVsIGNvbm5lY3QgaGFuZHNoYWtlIG9uY2UgdGhlIHdlYnNvY2tldCBvcGVucy5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAqL1xuICBfY2hlY2tDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgIGV2ZW50X3R5cGU6IFwiY29ubmVjdFwiLFxuICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgIG1vZGVsX3F1ZXJ5OiB0aGlzLm1vZGVsUXVlcnksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLm9wZW5SZXF1ZXN0W2lkXSA9IFtyZXNvbHZlLCByZWplY3RdO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdGhlIGJhY2tlbmQgbW9kZWwgcGF5bG9hZCBpbnRvIGxvY2FsbHkgdHJhY2tlZCBtb2RlbCBvYmplY3RzLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5PG9iamVjdD59IHJlc3VsdHNcbiAgICovXG4gIF9wYXJzZVNlcnZlclJlcyhyZXN1bHRzKSB7XG4gICAgY29uc3QgbmV3TW9kZWxzID0gW11cbiAgICBmb3IgKGNvbnN0IHggb2YgcmVzdWx0cykge1xuICAgICAgY29uc3QgTW9kZWxDbGFzcyA9IGdldE1vZGVsKHRoaXMubW9kZWxOYW1lKTtcbiAgICAgIGNvbnN0IG5ld01vZGVsID0gbmV3IE1vZGVsQ2xhc3MoeydpZCc6IHgucGsgPz8geC5pZCwgLi4ueC5maWVsZHN9KTtcbiAgICAgIGNvbnN0IGN1cnJlbnRNb2RlbCA9IHRoaXMuYnlJZChuZXdNb2RlbC5pZCk7XG4gICAgICBpZiAoY3VycmVudE1vZGVsKSB7XG4gICAgICAgIGN1cnJlbnRNb2RlbC5zZXRWYWx1ZXMobmV3TW9kZWwpO1xuICAgICAgICBuZXdNb2RlbHMucHVzaChjdXJyZW50TW9kZWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52YWx1ZXNMaXN0LnB1c2gobmV3TW9kZWwpO1xuICAgICAgICBuZXdNb2RlbC5fc2V0UXVlcnlTZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIG5ld01vZGVscy5wdXNoKG5ld01vZGVsKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy52YWx1ZXNMaXN0LnNvcnQoKGEsIGIpID0+IGEuX2lkIC0gYi5faWQpO1xuICAgIHJldHVybiBuZXdNb2RlbHM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2RjTW9kZWwge1xuICBzdGF0aWMgZmllbGRzID0ge307XG5cbiAgLyoqXG4gICAqIEJhc2UgbW9kZWwgd3JhcHBlciB1c2VkIGJ5IFNEQyBtb2RlbCByZWdpc3RyYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbW9kZWxOYW1lXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihtb2RlbE5hbWUpIHtcbiAgICB0aGlzLl9pZCA9IG51bGw7XG4gICAgdGhpcy5fZm9ybXMgPSBbXTtcbiAgICB0aGlzLmxvYWRlZCA9IGZhbHNlO1xuICAgIHRoaXMuZm9ybUlkID0gdXVpZHY0KCk7XG4gICAgdGhpcy5tb2RlbE5hbWUgPSBtb2RlbE5hbWU7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3Q/fSBtb2RlbFF1ZXJ5U2V0XG4gICAqIEBwYXJhbSB7QWJzdHJhY3RTREN9IHBhcmVudFxuICAgKiBAcmV0dXJucyB7U2RjUXVlcnlTZXR9XG4gICAqL1xuICBzdGF0aWMgcXVlcnlTZXQobW9kZWxRdWVyeVNldCA9IG51bGwsIHBhcmVudCA9IG51bGwpIHtcbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgcmV0dXJuIG5ldyBTZGNRdWVyeVNldCh0aGlzLm1vZGVOYW1lLCBtb2RlbFF1ZXJ5U2V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyZW50LnF1ZXJ5U2V0KHRoaXMubW9kZU5hbWUsIG1vZGVsUXVlcnlTZXQpO1xuICB9XG5cbiAgYWRkRm9ybSgkZm9ybSkge1xuICAgIC8vIFJlbW92ZSBvbGQgbGlzdGVuZXJzIGlmIGZvcm0gYWxyZWFkeSBzZXRcbiAgICBjb25zdCBvbkNoYW5nZSA9IHRoaXMuX29uQ2hhbmdlLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLl9mb3Jtcy5wdXNoKCRmb3JtKTtcblxuICAgIGlmICgkZm9ybSkge1xuICAgICAgLy8gQXR0YWNoIGRlbGVnYXRlZCBldmVudCBoYW5kbGVyIHRvIGFsbCBpbnB1dHNcbiAgICAgICRmb3JtLm9uKFxuICAgICAgICBcImlucHV0LmZvcm1XYXRjaGVyIGNoYW5nZS5mb3JtV2F0Y2hlclwiLFxuICAgICAgICBcImlucHV0LCBzZWxlY3QsIHRleHRhcmVhXCIsXG4gICAgICAgIG9uQ2hhbmdlXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIF9vbkNoYW5nZShldmVudCkge1xuICAgIGNvbnN0IHtuYW1lfSA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAodGhpcy5jb25zdHJ1Y3Rvci5maWVsZHNbbmFtZV0pIHtcbiAgICAgIHRoaXNbYHNldCR7bmFtZX1gXShnZXRWYWx1ZUZyb21GaWVsZChldmVudC50YXJnZXQpKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlRm9ybShmaWVsZE5hbWUpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICB0aGlzLl9mb3Jtcy5mb3JFYWNoKCgkZm9ybSkgPT4ge1xuICAgICAgJGZvcm0uZmluZChgW25hbWU9XCIke2ZpZWxkTmFtZX1cIl1gKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2V0VmFsdWVJbkZpZWxkKHRoaXMsIHNlbGZbZmllbGROYW1lXSlcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0VmFsdWVzKGRhdGEgPSB7fSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInNldFZhbHVlcygpIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3NcIik7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoIHRoZSBxdWVyeXNldCB0aGF0IG93bnMgdGhpcyBtb2RlbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtTZGNRdWVyeVNldH0gcXVlcnlTZXRcbiAgICogQHBhcmFtIHtib29sZWFufSBpc0xvYWRlZFxuICAgKi9cbiAgX3NldFF1ZXJ5U2V0KHF1ZXJ5U2V0LCBpc0xvYWRlZCkge1xuICAgIHRoaXMuX3F1ZXJ5U2V0ID0gbmV3IFdlYWtSZWYocXVlcnlTZXQpO1xuICAgIHRoaXMubG9hZGVkID0gaXNMb2FkZWQ7XG4gIH1cblxuICBzYXZlKHtmb3JtTmFtZSA9IFwiZWRpdF9mb3JtXCIsIGRhdGEgPSBudWxsfSA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuX3F1ZXJ5U2V0LmRlcmVmKCkuc2F2ZSh7cGs6IHRoaXMuaWQsIGZvcm1OYW1lLCBkYXRhfSk7XG4gIH1cblxuICBjcmVhdGUoe2RhdGEgPSBudWxsfSA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuX3F1ZXJ5U2V0LmRlcmVmKCkuY3JlYXRlKHtlbGVtOiB0aGlzLCBkYXRhfSk7XG4gIH1cblxuICBkZWxldGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3F1ZXJ5U2V0LmRlcmVmKCkuZGVsZXRlKHtlbGVtOiB0aGlzfSk7XG4gIH1cblxuICBsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLnVwZGF0ZSh7aXRlbTogdGhpc30pO1xuICB9XG5cbiAgZ2V0IGlkKCkge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuXG4gIHNldCBwayhkYXRhKSB7XG4gICAgdGhpcy5faWQgPSBkYXRhO1xuICB9XG5cbiAgZ2V0IHBrKCkge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuXG4gIGNsb3NlKCkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmNsb3NlKCk7XG4gIH1cblxuICBfb25DbG9zZSgpIHtcbiAgICBPYmplY3Qua2V5cyh0aGlzLmNvbnN0cnVjdG9yLmZpZWxkcylcbiAgICAgIC5maWx0ZXIoKHgpID0+IHRoaXNbYF8ke3h9YF0gaW5zdGFuY2VvZiBTZGNRdWVyeVNldClcbiAgICAgIC5mb3JFYWNoKCh4KSA9PiB0aGlzW2BfJHt4fWBdLmNsb3NlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVlc3QgdGhlIHNlcnZlci1yZW5kZXJlZCBkZXRhaWwgdmlldyBmb3IgdGhpcyBtb2RlbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBkZXRhaWxWaWV3KHtjYlJlc29sdmUgPSBudWxsLCBjYlJlamVjdCA9IG51bGwsIHRlbXBsYXRlQ29udGV4dCA9IHt9fSkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmRldGFpbFZpZXcoe3BrOiB0aGlzLmlkLCBjYlJlc29sdmUsIGNiUmVqZWN0LCB0ZW1wbGF0ZUNvbnRleHR9KTtcbiAgfVxuXG4gIHNlcmlhbGl6ZSgpIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModGhpcy5jb25zdHJ1Y3Rvci5maWVsZHMpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XTtcbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNkY1F1ZXJ5U2V0KSB7XG4gICAgICAgIGlmICh2YWwubWFueV90b19tYW55IHx8IHZhbC5vbmVfdG9fbWFueSkge1xuICAgICAgICAgIGFjY1trZXldID0gdmFsdWUuZ2V0SWRzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYWxsSWRzID0gdmFsdWUuZ2V0SWRzKCk7XG4gICAgICAgICAgaWYgKGFsbElkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBhY2Nba2V5XSA9IGFsbElkc1swXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWNjW2tleV0gPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHZhbC5pc19yZWxhdGlvbiAmJiB2YWx1ZSBpbnN0YW5jZW9mIFNkY01vZGVsKSB7XG4gICAgICAgIGFjY1trZXldID0gdmFsdWUuaWQgPz8gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhY2NcbiAgICB9LCB7fSk7XG4gIH1cblxuICB0b0pzb24oKSB7XG4gICAgY29uc3QgcmVzID0ge31cbiAgICBmb3IgKGxldCBrZXkgaW4gdGhpcy5jb25zdHJ1Y3Rvci5maWVsZHMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpc1trZXldO1xuXG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgIHJlc1trZXldID0gdmFsdWUubmFtZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZGNNb2RlbCkge1xuICAgICAgICByZXNba2V5XSA9IHZhbHVlLmlkO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNkY1F1ZXJ5U2V0KSB7XG4gICAgICAgIHJlc1trZXldID0gdmFsdWUuZ2V0SWRzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogQmFja3dhcmRzLWNvbXBhdGlibGUgYWxpYXMgZm9yIHN5bmNpbmcgdmFsdWVzIGZyb20gYSBmb3JtIGludG8gdGhlIG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0geyp9ICRmb3Jtc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIHN5bmNGb3JtVG9Nb2RlbCgkZm9ybXMpIHtcbiAgICByZXR1cm4gdGhpcy5zeW5jRm9ybSgkZm9ybXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIGZvcm0gY29sbGVjdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBtb2RlbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHsqfSAkZm9ybXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBfcmVzb2x2ZUZvcm1zKCRmb3Jtcykge1xuICAgIGlmICghJGZvcm1zIHx8ICEkZm9ybXMuaGFzQ2xhc3ModGhpcy5mb3JtSWQpKSB7XG4gICAgICByZXR1cm4gJChgLiR7dGhpcy5mb3JtSWR9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuICRmb3JtcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3B5IHRoZSBjdXJyZW50IG1vZGVsIHN0YXRlIGludG8gbWF0Y2hpbmcgZm9ybSBmaWVsZHMuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gJGZvcm1zXG4gICAqL1xuICBzeW5jTW9kZWxUb0Zvcm0oJGZvcm1zKSB7XG4gICAgJGZvcm1zID0gdGhpcy5fcmVzb2x2ZUZvcm1zKCRmb3Jtcyk7XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBmaWVsZHMgPSB0aGlzLmNvbnN0cnVjdG9yLmZpZWxkcztcbiAgICAkZm9ybXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwayA9IG5vcm1hbGl6ZVBrKCQodGhpcykuZGF0YShcIm1vZGVsX3BrXCIpKTtcbiAgICAgIGlmIChzZWxmLmlkICE9PSBwaykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGZvcm1JdGVtIG9mIHRoaXMuZWxlbWVudHMpIHtcbiAgICAgICAgbGV0IG5hbWUgPSBmb3JtSXRlbS5uYW1lO1xuICAgICAgICBpZiAobmFtZSAmJiBuYW1lICE9PSBcIlwiICYmICEhZmllbGRzW25hbWVdKSB7XG4gICAgICAgICAgc2V0VmFsdWVJbkZpZWxkKGZvcm1JdGVtLCBzZWxmW25hbWVdKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ29weSBtYXRjaGluZyBmb3JtIHZhbHVlcyBiYWNrIG9udG8gdGhlIGN1cnJlbnQgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEhpZGRlbiBpbnB1dHMgYXJlIHBhcnNlZCB0byB0aGVpciBvcmlnaW5hbCBwcmltaXRpdmUgdHlwZSB3aGVuIHBvc3NpYmxlLlxuICAgKlxuICAgKiBAcGFyYW0geyp9ICRmb3Jtc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIHN5bmNGb3JtKCRmb3Jtcykge1xuICAgICRmb3JtcyA9IHRoaXMuX3Jlc29sdmVGb3JtcygkZm9ybXMpO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgZmllbGRzID0gdGhpcy5jb25zdHJ1Y3Rvci5maWVsZHM7XG4gICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fVxuXG4gICAgZnVuY3Rpb24gc2V0VmFsdWVJbkZvcm0obmFtZSwgdmFsdWUpIHtcbiAgICAgIGlmICghIWZpZWxkc1tuYW1lXSkge1xuICAgICAgICBzZWxmW25hbWVdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm5WYWx1ZVtuYW1lXSA9IHZhbHVlO1xuICAgIH1cblxuICAgICRmb3Jtcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBrID0gbm9ybWFsaXplUGsoJCh0aGlzKS5kYXRhKFwibW9kZWxfcGtcIikpO1xuICAgICAgaWYgKHNlbGYuaWQgIT09IHBrICYmIChzZWxmLmlkICE9PSBudWxsIHx8IHBrICE9PSAtMSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBmb3JtSXRlbSBvZiB0aGlzLmVsZW1lbnRzKSB7XG4gICAgICAgIHNldFZhbHVlSW5Gb3JtKGZvcm1JdGVtLm5hbWUsIGdldFZhbHVlRnJvbUZpZWxkKGZvcm1JdGVtKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgY29ycmVjdCBzZXJ2ZXItc2lkZSBmb3JtIGZvciB0aGlzIG1vZGVsIHN0YXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGZvcm0oe2NiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbH0pIHtcbiAgICBpZiAodGhpcy5pZCA9PT0gbnVsbCB8fCB0aGlzLmlkID09PSAtMSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUZvcm0oe2NiUmVqZWN0LCBjYlJlc29sdmV9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRGb3JtKHtjYlJlamVjdCwgY2JSZXNvbHZlfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSBjcmVhdGUgZm9ybSBmb3IgYSBuZXcgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgX2NyZWF0ZUZvcm0oe2NiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbH0pIHtcbiAgICBsZXQgJGRpdkZvcm0gPSAkKFwiPGRpdj5cIik7XG4gICAgdGhpcy5fcXVlcnlTZXQuZGVyZWYoKS5nZXRGb3JtKHtcbiAgICAgIG1vZGVsT2JqOiB0aGlzLFxuICAgICAgZXZlbnRUeXBlOiBcImNyZWF0ZV9mb3JtXCIsXG4gICAgICBmb3JtTmFtZTogbnVsbCxcbiAgICAgICRkaXZGb3JtLFxuICAgICAgY2JSZXNvbHZlLFxuICAgICAgY2JSZWplY3QsXG4gICAgICBmb3JtSWQ6IHRoaXMuZm9ybUlkLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZWRpdCBmb3JtIGZvciBhbiBleGlzdGluZyBtb2RlbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBfZWRpdEZvcm0oe2NiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbH0pIHtcbiAgICBsZXQgJGRpdkZvcm0gPSAkKFwiPGRpdj5cIik7XG5cbiAgICB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmdldEZvcm0oe1xuICAgICAgbW9kZWxPYmo6IHRoaXMsXG4gICAgICBldmVudFR5cGU6IFwiZWRpdF9mb3JtXCIsXG4gICAgICBmb3JtTmFtZTogbnVsbCxcbiAgICAgICRkaXZGb3JtLFxuICAgICAgY2JSZXNvbHZlLFxuICAgICAgY2JSZWplY3QsXG4gICAgICBmb3JtSWQ6IHRoaXMuZm9ybUlkLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciBhIG5hbWVkIHNlcnZlci1zaWRlIGZvcm0gZm9yIHRoaXMgbW9kZWwuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgbmFtZWRGb3JtKHtmb3JtTmFtZSwgY2JSZXNvbHZlID0gbnVsbCwgY2JSZWplY3QgPSBudWxsfSkge1xuICAgIGxldCAkZGl2Rm9ybSA9ICQoJzxkaXYgIGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG5cbiAgICB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmdldEZvcm0oe1xuICAgICAgbW9kZWxPYmo6IHRoaXMsXG4gICAgICBldmVudFR5cGU6IFwibmFtZWRfZm9ybVwiLFxuICAgICAgZm9ybU5hbWUsXG4gICAgICAkZGl2Rm9ybSxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgZm9ybUlkOiB0aGlzLmZvcm1JZCxcbiAgICB9KTtcblxuICAgIHJldHVybiAkZGl2Rm9ybTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIGZpZWxkIHZhbHVlIHVzaW5nIHRoZSBzdXBwbGllZCBmaWVsZCBjb25maWcuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICAgKi9cbiAgdmFsaWRhdGUodmFsdWUsIGNvbmZpZykge1xuICAgIGNvbnN0IGVyciA9IHZhbGlkYXRlRmllbGQodmFsdWUsIGNvbmZpZyk7XG4gICAgaWYgKGVycikgdGhyb3cgbmV3IEVycm9yKGVycik7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhIHJhdyBpbnB1dCB2YWx1ZSBpbnRvIHRoZSBzaGFwZSBleHBlY3RlZCBieSB0aGUgZmllbGQgY29uZmlnLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWdcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBwYXJzZVZhbHVlKHZhbHVlLCBjb25maWcpIHtcbiAgICBjb25zdCB7XG4gICAgICB0eXBlXG4gICAgfSA9IGNvbmZpZztcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBcIkNoYXJGaWVsZFwiOlxuICAgICAgY2FzZSBcIlRlZXh0RmllbGRcIjpcbiAgICAgIGNhc2UgXCJVVUlERmllbGRcIjpcbiAgICAgIGNhc2UgXCJFbWFpbEZpZWxkXCI6XG4gICAgICAgIHJldHVybiBgJHt2YWx1ZX1gO1xuXG4gICAgICBjYXNlIFwiSW50ZWdlckZpZWxkXCI6XG4gICAgICBjYXNlIFwiQXV0b0ZpZWxkXCI6XG4gICAgICBjYXNlIFwiQmlnSW50ZWdlckZpZWxkXCI6XG4gICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApO1xuXG4gICAgICBjYXNlIFwiRmxvYXRGaWVsZFwiOlxuICAgICAgY2FzZSBcIkRlY2ltYWxGaWVsZFwiOlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIG51bWJlclwiO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiQm9vbGVhbkZpZWxkXCI6XG4gICAgICAgIHJldHVybiAhIXZhbHVlO1xuXG4gICAgICBjYXNlIFwiRGF0ZUZpZWxkXCI6XG4gICAgICBjYXNlIFwiRGF0ZVRpbWVGaWVsZFwiOlxuICAgICAgICByZXR1cm4gRGF0ZS5wYXJzZSh2YWx1ZSk7XG5cbiAgICAgIGNhc2UgXCJVUkxGaWVsZFwiOlxuICAgICAgICByZXR1cm4gbmV3IFVSTCh2YWx1ZSk7XG5cbiAgICAgIGNhc2UgXCJGaWxlRmllbGRcIjpcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChGaWxlTG9hZGVkLmlzVmFsaWQodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGaWxlTG9hZGVkKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZpbGVMb2FkZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZpbGVMb2FkZWQodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBGaWxlICE9PSBcInVuZGVmaW5lZFwiICYmIHZhbHVlIGluc3RhbmNlb2YgRmlsZSkge1xuICAgICAgICAgIGlmIChjb25maWcubWF4X3NpemUgJiYgdmFsdWUuc2l6ZSA+IGNvbmZpZy5tYXhfc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGBGaWxlIHRvbyBsYXJnZSAobWF4ICR7Y29uZmlnLm1heF9zaXplfSBieXRlcylgO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjb25maWcuYWxsb3dlZF90eXBlcyAmJiAhY29uZmlnLmFsbG93ZWRfdHlwZXMuaW5jbHVkZXModmFsdWUudHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBgSW52YWxpZCBmaWxlIHR5cGUgKCR7dmFsdWUudHlwZX0pYDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJKU09ORmllbGRcIjpcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhIGZpZWxkIHZhbHVlIGFnYWluc3QgdGhlIGZpZWxkIG1ldGFkYXRhIHJlY2VpdmVkIGZyb20gdGhlIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICogQHJldHVybnMgez9zdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRmllbGQodmFsdWUsIGNvbmZpZykge1xuICBjb25zdCB7XG4gICAgdHlwZSxcbiAgICByZXF1aXJlZCxcbiAgICBtYXhfbGVuZ3RoOiBtYXhMZW5ndGgsXG4gICAgaXNfcmVsYXRpb246IGlzUmVsYXRpb24sXG4gICAgbWFueV90b19tYW55OiBtYW55VG9NYW55LFxuICAgIG9uZV90b19tYW55OiBvbmVUb01hbnksXG4gICAgbWFueV90b19vbmU6IG1hbnlUb09uZSxcbiAgICBvbmVfdG9fb25lOiBvbmVUb09uZSxcbiAgICByZWxhdGVkX21vZGVsOiByZWxhdGVkTW9kZWwsXG4gIH0gPSBjb25maWc7XG5cbiAgdm9pZCBpc1JlbGF0aW9uO1xuXG4gIGlmIChyZXF1aXJlZCkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBcIlwiKSB7XG4gICAgICByZXR1cm4gXCJUaGlzIGZpZWxkIGlzIHJlcXVpcmVkXCI7XG4gICAgfVxuICB9XG5cbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChtYW55VG9NYW55IHx8IG9uZVRvTWFueSB8fCBtYW55VG9PbmUgfHwgb25lVG9PbmUpIHtcbiAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIFNkY1F1ZXJ5U2V0KSB8fCB2YWx1ZS5tb2RlbE5hbWUgIT09IHJlbGF0ZWRNb2RlbCkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiBOdW1iZXIuaXNOYU4ocGFyc2VJbnQodmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gXCJNdXN0IGJlIG9iamVjdCBvciBJRFwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBcIkNoYXJGaWVsZFwiOlxuICAgIGNhc2UgXCJUZXh0RmllbGRcIjpcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIHN0cmluZ1wiO1xuICAgICAgfVxuICAgICAgaWYgKG1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiBtYXhMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGBNYXggbGVuZ3RoIGlzICR7bWF4TGVuZ3RofWA7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJJbnRlZ2VyRmllbGRcIjpcbiAgICBjYXNlIFwiQXV0b0ZpZWxkXCI6XG4gICAgY2FzZSBcIkJpZ0ludGVnZXJGaWVsZFwiOlxuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gXCJNdXN0IGJlIGFuIGludGVnZXJcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkZsb2F0RmllbGRcIjpcbiAgICBjYXNlIFwiRGVjaW1hbEZpZWxkXCI6XG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHJldHVybiBcIk11c3QgYmUgYSBudW1iZXJcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkJvb2xlYW5GaWVsZFwiOlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIGJvb2xlYW5cIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkRhdGVGaWVsZFwiOlxuICAgIGNhc2UgXCJEYXRlVGltZUZpZWxkXCI6XG4gICAgICBpZiAoaXNOYU4oRGF0ZS5wYXJzZSh2YWx1ZSkpKSB7XG4gICAgICAgIHJldHVybiBcIk11c3QgYmUgYSB2YWxpZCBkYXRlXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJFbWFpbEZpZWxkXCI6XG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiIHx8ICEvXlteXFxzQF0rQFteXFxzQF0rXFwuW15cXHNAXSskLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gXCJJbnZhbGlkIGVtYWlsXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJVUkxGaWVsZFwiOlxuICAgICAgdHJ5IHtcbiAgICAgICAgbmV3IFVSTCh2YWx1ZSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiSW52YWxpZCBVUkxcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIlVVSURGaWVsZFwiOlxuICAgICAgaWYgKCEvXlswLTlhLWZdezh9LVswLTlhLWZdezR9LVsxLTVdWzAtOWEtZl17M30tWzg5YWJdWzAtOWEtZl17M30tWzAtOWEtZl17MTJ9JC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIFwiSW52YWxpZCBVVUlEXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJKU09ORmllbGRcIjpcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBKU09OIG9iamVjdFwiO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcIkZpbGVGaWVsZFwiOlxuICAgICAgaWYgKCFGaWxlTG9hZGVkLmlzVmFsaWQodmFsdWUpICYmICEodmFsdWUgaW5zdGFuY2VvZiBGaWxlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRmlsZUxvYWRlZCkpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIHZhbGlkIGZpbGVcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl0sIm5hbWVzIjpbImdldFZhbHVlRnJvbUZpZWxkIiwic2V0VmFsdWVJbkZpZWxkIiwidXVpZHY0IiwiZ2V0TW9kZWwiLCJhcHAiLCJ0cmlnZ2VyIiwiTUFYX0ZJTEVfVVBMT0FEIiwiQ09OTkVDVElOR19SRVFVRVNUX0lEIiwiU2RjTW9kZWxFcnJvciIsIkVycm9yIiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIm1zZyIsImlzX2Vycm9yIiwiaGVhZGVyIiwiaHRtbCIsIkZpbGVMb2FkZWQiLCJuYW1lIiwidXJsIiwiY29udGVudCIsImxvYWQiLCJmb3JjZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiJCIsImdldCIsInRoZW4iLCJjYXRjaCIsInRleHQiLCJpc1ZhbGlkIiwidmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJGaWxlIiwibm9ybWFsaXplUGsiLCJwayIsIm5vcm1hbGl6ZWRQayIsInBhcnNlSW50IiwiTnVtYmVyIiwiaXNOYU4iLCJTZGNRdWVyeVNldCIsIm1vZGVsTmFtZSIsIm1vZGVsUXVlcnkiLCJ2YWx1ZXNMaXN0IiwibG9hZGVkIiwiX29uTm9PcGVuUmVxdWVzdHMiLCJfaXNDb25uZWN0ZWQiLCJfaXNDb25uZWN0aW5nUHJvY2VzcyIsIl9hdXRvUmVjb25uZWN0Iiwic29ja2V0Iiwib3BlblJlcXVlc3QiLCJtb2RlbElkIiwib25VcGRhdGUiLCJvbkNyZWF0ZSIsIlByb3h5IiwidGFyZ2V0IiwicHJvcCIsInNldCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiaWR4IiwibmV4dCIsImxlbmd0aCIsImRvbmUiLCJvbl9jcmVhdGUiLCJoYW5kbGVyIiwib25fdXBkYXRlIiwic2V0SWRzIiwiaWRzIiwic3RydWN0dXJlZENsb25lIiwiZm9yRWFjaCIsIl9zZXRRdWVyeVNldCIsIlNkY01vZGVsIiwibnVtTGlzdCIsIm51bUlkIiwiTmFOIiwiaXNJbnRlZ2VyIiwidGVtcE51bUxpc3QiLCJtYXAiLCJ4Iiwic29tZSIsIlN0cmluZyIsInNwbGl0IiwibmV3TW9kZWwiLCJuZXciLCJpZCIsImZpbHRlciIsIml0ZW0iLCJpbmNsdWRlcyIsInZhbHVlSWRzIiwiZ2V0SWRzIiwicHVzaCIsImJ5SWQiLCJub3JtYWxpemVkSWQiLCJmaW5kIiwiZWxtIiwic2V0RmlsdGVyIiwiYWRkRmlsdGVyIiwiT2JqZWN0IiwiYXNzaWduIiwidmFsdWVzIiwiX3NlbmRMb2FkIiwidXBkYXRlIiwibG9hZFF1ZXJ5IiwiZGVsZXRlIiwiZWxlbSIsImlzQ29ubmVjdGVkIiwic2VuZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJldmVudCIsImV2ZW50X3R5cGUiLCJldmVudF9pZCIsImFyZ3MiLCJtb2RlbF9uYW1lIiwibW9kZWxfcXVlcnkiLCJkYXRhIiwiX3NlbmRMaXN0VmlldyIsImNiUmVzb2x2ZSIsImNiUmVqZWN0IiwidGVtcGxhdGVDb250ZXh0IiwidmlldyIsImV2ZW50VHlwZSIsInZpZXdOYW1lIiwiJGRpdkxpc3QiLCJ2aWV3X25hbWUiLCJ0ZW1wbGF0ZV9jb250ZXh0IiwiYXBwZW5kIiwicmVmcmVzaCIsInJlcyIsIl9zZW5kRGV0YWlsVmlldyIsImdldEZvcm0iLCJtb2RlbE9iaiIsImZvcm1OYW1lIiwiJGRpdkZvcm0iLCJmb3JtSWQiLCJmb3JtX25hbWUiLCJjbGFzc05hbWUiLCIkZm9ybSIsImNsb3Nlc3QiLCJhZGRDbGFzcyIsImFkZEZvcm0iLCJoYXNBdHRyaWJ1dGUiLCJhdHRyIiwiZG9Ob3RMb2FkIiwiZGV0YWlsVmlldyIsImxpc3RWaWV3Iiwic2VhcmNoVmFsdWVzIiwic2F2ZSIsIm5vcm1QayIsImVsZW1MaXN0IiwicExpc3QiLCJfcmVhZEZpbGVzIiwiZmlsZXMiLCJzZW5kRGF0YSIsInNlcmlhbGl6ZSIsImluc3RhbmNlIiwicGFyc2UiLCJfcGFyc2VTZXJ2ZXJSZXMiLCJhbGwiLCJjcmVhdGUiLCJfY29ubmVjdFRvU2VydmVyIiwiX2NoZWNrQ29ubmVjdGlvbiIsInJlc29sdmVPcmlnaW4iLCJyZWplY3RPcmlnaW4iLCJjbG9zZSIsIm9uY2xvc2UiLCJfb25DbG9zZSIsInRvU29sdmUiLCJrZXlzIiwiZmllbGRzIiwia2V5IiwiYnVmZmVyIiwiYXJyYXlCdWZmZXIiLCJyZXN1bHQiLCJVaW50OEFycmF5IiwibnVtYmVyT2ZDaHVua3MiLCJNYXRoIiwiY2VpbCIsImZpbGVfbmFtZSIsImZpZWxkX25hbWUiLCJjb250ZW50X2xlbmd0aCIsInNpemUiLCJpIiwiY2h1bmsiLCJmcm9tIiwic2xpY2UiLCJudW1iZXJfb2ZfY2h1bmtzIiwiY29udGVudF90eXBlIiwidHlwZSIsIl9vbk1lc3NhZ2UiLCJlIiwiaGFzT3duUHJvcGVydHkiLCJfY2xvc2VPcGVuUmVxdWVzdCIsImpzb25SZXMiLCJvYmoiLCJjYiIsIm5vT3BlblJlcXVlc3RzIiwiZXZlbnRJZCIsIm1vZGVsSWRlbnRpZmllciIsIndpbmRvdyIsImxvY2F0aW9uIiwicHJvdG9jb2wiLCJXZWJTb2NrZXQiLCJob3N0Iiwib25tZXNzYWdlIiwiYmluZCIsImNvbnNvbGUiLCJlcnJvciIsIl9rZXkiLCJlbnRyaWVzIiwic2V0VGltZW91dCIsIm9uZXJyb3IiLCJlcnIiLCJvbm9wZW4iLCJyZXN1bHRzIiwibmV3TW9kZWxzIiwiTW9kZWxDbGFzcyIsImN1cnJlbnRNb2RlbCIsInNldFZhbHVlcyIsInNvcnQiLCJhIiwiYiIsIl9pZCIsIl9mb3JtcyIsInF1ZXJ5U2V0IiwibW9kZWxRdWVyeVNldCIsInBhcmVudCIsIm1vZGVOYW1lIiwib25DaGFuZ2UiLCJfb25DaGFuZ2UiLCJvbiIsIl91cGRhdGVGb3JtIiwiZmllbGROYW1lIiwic2VsZiIsImVhY2giLCJpc0xvYWRlZCIsIl9xdWVyeVNldCIsIldlYWtSZWYiLCJkZXJlZiIsInJlZHVjZSIsImFjYyIsInZhbCIsIm1hbnlfdG9fbWFueSIsIm9uZV90b19tYW55IiwiYWxsSWRzIiwiaXNfcmVsYXRpb24iLCJ0b0pzb24iLCJzeW5jRm9ybVRvTW9kZWwiLCIkZm9ybXMiLCJzeW5jRm9ybSIsIl9yZXNvbHZlRm9ybXMiLCJoYXNDbGFzcyIsInN5bmNNb2RlbFRvRm9ybSIsImZvcm1JdGVtIiwiZWxlbWVudHMiLCJyZXR1cm5WYWx1ZSIsInNldFZhbHVlSW5Gb3JtIiwiZm9ybSIsIl9jcmVhdGVGb3JtIiwiX2VkaXRGb3JtIiwibmFtZWRGb3JtIiwidmFsaWRhdGUiLCJjb25maWciLCJ2YWxpZGF0ZUZpZWxkIiwicGFyc2VWYWx1ZSIsIkRhdGUiLCJVUkwiLCJtYXhfc2l6ZSIsImFsbG93ZWRfdHlwZXMiLCJyZXF1aXJlZCIsIm1heF9sZW5ndGgiLCJtYXhMZW5ndGgiLCJpc1JlbGF0aW9uIiwibWFueVRvTWFueSIsIm9uZVRvTWFueSIsIm1hbnlfdG9fb25lIiwibWFueVRvT25lIiwib25lX3RvX29uZSIsIm9uZVRvT25lIiwicmVsYXRlZF9tb2RlbCIsInJlbGF0ZWRNb2RlbCIsInVuZGVmaW5lZCIsInRlc3QiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/simpleDomControl/sdc_model.js\n\n}");
|
|
77
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SdcQuerySet: () => (/* binding */ SdcQuerySet),\n/* harmony export */ \"default\": () => (/* binding */ SdcModel)\n/* harmony export */ });\n/* harmony import */ var _sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sdc_utils.js */ \"./src/simpleDomControl/sdc_utils.js\");\n/* harmony import */ var _sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sdc_socket.js */ \"./src/simpleDomControl/sdc_socket.js\");\n/* harmony import */ var _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sdc_main.js */ \"./src/simpleDomControl/sdc_main.js\");\n/* harmony import */ var _sdc_events_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sdc_events.js */ \"./src/simpleDomControl/sdc_events.js\");\n\n\n\n\nconst MAX_FILE_UPLOAD = 25000;\nconst CONNECTING_REQUEST_ID = \"_connecting_process\";\nclass SdcModelError extends Error {\n constructor(props) {\n if (typeof props === 'string') {\n props = {\n msg: props,\n is_error: true,\n header: 'Error'\n };\n }\n super(props.msg);\n this.msg = props.msg;\n this.header = props.header;\n this.is_error = props.is_error;\n this.html = props.html;\n }\n}\nclass FileLoaded {\n constructor({\n name,\n url\n }) {\n this.name = name;\n this.url = url;\n this.content = null;\n }\n async load(force = false) {\n if (force || !this.content) {\n this.content = await new Promise((resolve, reject) => {\n $.get(this.url).then(resolve).catch(() => {\n resolve('');\n });\n });\n }\n return this.content;\n }\n async text() {\n return this.load();\n }\n static isValid(value) {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof File) && typeof value.url === \"string\" && typeof value.name === \"string\";\n }\n}\n\n/**\n * Normalize an incoming primary key value.\n *\n * `-1` is used throughout this module as the sentinel for \"new object / no pk\".\n *\n * @param {*} pk\n * @returns {number}\n */\nfunction normalizePk(pk) {\n const normalizedPk = parseInt(pk ?? -1, 10);\n return Number.isNaN(normalizedPk) ? -1 : normalizedPk;\n}\nclass SdcQuerySet {\n /**\n * Lightweight client-side collection wrapper around the SDC model websocket.\n *\n * The queryset exposes array-like access through a proxy while also keeping\n * track of socket state and outstanding requests for that model.\n *\n * @param {string} modelName\n * @param {object} modelQuery\n */\n constructor(modelName, modelQuery = {}) {\n this.valuesList = [];\n this.loaded = false;\n this.modelName = modelName;\n this.modelQuery = modelQuery ?? {};\n this._onNoOpenRequests = [];\n this._isConnected = false;\n this._isConnectingProcess = false;\n this._autoReconnect = true;\n this.socket = null;\n // Request resolvers are stored by websocket event id until the server responds.\n this.openRequest = {};\n this.modelId = 0;\n this.onUpdate = () => {};\n this.onCreate = () => {};\n return new Proxy(this, {\n get(target, prop) {\n if (typeof prop !== \"symbol\" && !isNaN(prop)) {\n return target.valuesList[prop];\n }\n return target[prop];\n },\n set(target, prop, value) {\n if (!isNaN(prop)) {\n target.valuesList[prop] = value;\n return true;\n }\n target[prop] = value;\n return true;\n }\n });\n }\n [Symbol.iterator]() {\n let idx = -1;\n return {\n next: () => {\n ++idx;\n if (idx < this.valuesList.length) {\n return {\n value: this.valuesList[idx],\n done: false\n };\n }\n return {\n value: null,\n done: true\n };\n }\n };\n }\n set on_create(handler) {\n this.onCreate = handler;\n }\n set on_update(handler) {\n this.onUpdate = handler;\n }\n\n /**\n *\n *\n * @param {Array<integr|string>|integer|SdcModel|SdcQuerySet|string} ids\n */\n setIds(ids) {\n if (ids === null || ids === \"\" || Array.isArray(ids) && ids.length === 0) {\n this.valuesList = [];\n return this.valuesList;\n } else if (ids instanceof SdcQuerySet) {\n this.valuesList = structuredClone(ids.valuesList);\n this.valuesList.forEach(value => value._setQuerySet(this, true));\n return this.valuesList;\n } else if (ids instanceof SdcModel) {\n this.valuesList = [structuredClone(ids)];\n this.valuesList.forEach(value => value._setQuerySet(this, true));\n return this.valuesList;\n }\n let numList,\n numId = Number.NaN;\n if (Number.isInteger(ids)) {\n numId = ids;\n } else if (ids instanceof Array) {\n const tempNumList = ids.map(x => parseInt(x));\n if (!tempNumList.some(Number.isNaN)) {\n numList = tempNumList;\n }\n } else if (typeof ids === \"string\") {\n const tempNumList = ids.split(',').map(x => parseInt(x));\n if (!tempNumList.some(Number.isNaN)) {\n numList = tempNumList;\n } else {\n numId = parseInt(ids);\n }\n }\n if (!Number.isNaN(numId)) {\n const newModel = this.new();\n newModel.id = numId;\n } else if (numList) {\n this.valuesList = this.valuesList.filter(item => numList.includes(item.id));\n const valueIds = this.getIds();\n numList.filter(x => !valueIds.includes(x)).forEach(id => {\n this.valuesList.push(new ((0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName))({\n id\n }));\n });\n }\n return this.valuesList;\n }\n getIds() {\n return this.valuesList.map(x => x.id);\n }\n\n /**\n * Number of model instances currently present in the queryset cache.\n *\n * @returns {number}\n */\n get length() {\n return this.valuesList.length;\n }\n\n /**\n * Resolve a model instance by id, loading the queryset first if needed.\n *\n * @param {*} id\n * @returns {SdcModel|null}\n */\n byId(id) {\n if (id !== null) {\n const normalizedId = normalizePk(id);\n return this.valuesList.find(elm => elm.id === normalizedId) ?? null;\n }\n return null;\n }\n\n /**\n * Merge additional query constraints into the current queryset.\n *\n * @param {object} modelQuery\n * @returns {SdcQuerySet}\n */\n setFilter(modelQuery) {\n this.modelQuery = modelQuery;\n return this;\n }\n addFilter(modelQuery) {\n this.modelQuery = Object.assign({}, this.modelQuery, modelQuery);\n return this;\n }\n\n /**\n * @param {?object} values\n * @returns {SdcModel}\n */\n new(values = {}) {\n const newModel = new ((0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName))(values);\n newModel._setQuerySet(this, false);\n this.valuesList.push(newModel);\n return newModel;\n }\n\n /**\n * Load model instances matching the current query into the queryset cache.\n *\n * @param {?object} modelQuery\n * @returns {Promise<SdcQuerySet>}\n */\n load(modelQuery = null) {\n this.valuesList = [];\n this.modelQuery = modelQuery ?? this.modelQuery;\n return this._sendLoad();\n }\n\n /**\n * Load model instances matching the current query into the queryset cache.\n *\n * @param {?object} modelQuery\n * @param {?SdcModel} item\n * @returns {Promise<SdcQuerySet>}\n */\n update({\n modelQuery = null,\n item = null\n }) {\n this.modelQuery = modelQuery ?? this.modelQuery;\n let loadQuery = item ? {\n pk: item.id\n } : this.modelQuery;\n return this._sendLoad(loadQuery);\n }\n\n /**\n *\n * @param pk {integr}\n * @param elem {SdcModel}\n * @returns {Promise<unknown>}\n */\n delete({\n pk = null,\n elem = null\n }) {\n pk = !elem ? pk : elem.id;\n if (pk === null) {\n throw new Error(\"pk or elem must be set\");\n }\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return this.isConnected().then(() => {\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"delete\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n pk\n }\n }));\n this.openRequest[id] = [resolve, reject];\n });\n });\n }\n\n /**\n * Request the server-side queryset data over the model websocket.\n *\n * @returns {Promise<*>}\n */\n _sendLoad(loadQuery = null) {\n return this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"load\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: loadQuery ?? this.modelQuery\n }\n }));\n this.openRequest[id] = [data => {\n this.loaded = true;\n resolve(data);\n }, reject];\n });\n });\n }\n\n /**\n * Render the list-view endpoint for the current model.\n *\n * @param {object} options\n * @returns {*}\n */\n _sendListView({\n modelQuery = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this.view({\n modelQuery,\n cbResolve,\n cbReject,\n templateContext,\n eventType: \"list_view\"\n });\n }\n\n /**\n * Render a named model view and append its HTML to a container element.\n *\n * @param {object} options\n * @returns {*}\n */\n view({\n viewName = \"html_list_template\",\n modelQuery = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {},\n eventType = \"named_view\"\n }) {\n let $divList = $('<div class=\"container-fluid\">');\n this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: eventType,\n event_id: id,\n args: {\n view_name: viewName,\n model_name: this.modelName,\n model_query: modelQuery,\n template_context: templateContext\n }\n }));\n this.openRequest[id] = [data => {\n $divList.append(data.html);\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divList);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n });\n return $divList;\n }\n\n /**\n * Render the detail-view endpoint for a single model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _sendDetailView({\n pk = null,\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n pk = normalizePk(pk);\n let $divList = $('<div class=\"container-fluid\">');\n this.isConnected().then(() => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"detail_view\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n pk,\n template_context: templateContext\n }\n }));\n this.openRequest[id] = [data => {\n $divList.append(data.html);\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divList);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n });\n return $divList;\n }\n\n /**\n * Fetch a model form fragment and attach the SDC form metadata expected by\n * the rest of the client.\n *\n * @param {string} eventType\n * @param {SdcModel} modelObj\n */\n getForm({\n modelObj,\n eventType,\n formName,\n $divForm,\n cbResolve,\n cbReject,\n formId\n }) {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n const pk = modelObj.id ?? -1;\n this.isConnected().then(() => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: eventType,\n event_id: id,\n args: {\n model_name: this.modelName,\n pk,\n form_name: formName\n }\n }));\n });\n const className = pk === null || pk === -1 ? \"create\" : \"edit\";\n this.openRequest[id] = [data => {\n $divForm.append(data.html);\n let $form = $divForm.closest(\"form\").addClass(`sdc-model-${className}-form sdc-model-form ${formId}`).data(\"model\", modelObj).data(\"model_pk\", pk).data(\"form_name\", formName);\n modelObj.addForm($form);\n if ($form.length > 0 && !$form[0].hasAttribute(\"sdc_submit\")) {\n $form.attr(\"sdc_submit\", \"submitModelFormDistributor\");\n }\n _sdc_main_js__WEBPACK_IMPORTED_MODULE_2__.app.refresh($divForm).then(() => null);\n cbResolve && cbResolve(data);\n }, res => {\n cbReject && cbReject(res);\n }];\n }\n\n /**\n * Fetch a single model instance matching the current query.\n *\n * @param {?object} modelQuery\n * @param {?boolean} doNotLoad true if modelQuery contains id or pk and object does not need to be loaded.\n * @returns {Promise<SdcModel>}\n */\n async get(modelQuery = null, doNotLoad = false) {\n if (doNotLoad) {\n const id = modelQuery?.id ?? modelQuery?.pk;\n return this.byId(id) ?? this.new(modelQuery || this.modelQuery);\n }\n await this.load(modelQuery);\n if (this.length !== 1) {\n throw new Error(`model query returns ${this.length} but only 1 expected.`);\n }\n return this.valuesList[0];\n }\n detailView({\n pk,\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._sendDetailView({\n pk,\n cbResolve,\n cbReject,\n templateContext\n });\n }\n listView({\n modelQuery = {},\n searchValues = {},\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._sendListView({\n modelQuery: Object.assign({}, this.modelQuery, modelQuery, {\n '__search_values': searchValues\n }),\n cbResolve,\n cbReject,\n templateContext\n });\n }\n save({\n pk = null,\n formName = \"edit_form\",\n data = null\n } = {}) {\n const normPk = normalizePk(pk);\n return this.isConnected().then(() => {\n let elemList;\n if (normPk > -1) {\n const elem = this.byId(normPk);\n if (!elem) {\n return Promise.reject(new SdcModelError(`Element not found with ID: ${normPk}`));\n }\n elemList = [elem];\n } else {\n elemList = this.valuesList;\n }\n let pList = [];\n elemList.forEach(elem => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n pList.push(new Promise((resolve, reject) => {\n this._readFiles(elem).then(files => {\n const sendData = data ? {\n ...data\n } : elem.serialize();\n sendData.pk = elem.id;\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"save\",\n event_id: id,\n args: {\n form_name: formName,\n model_name: this.modelName,\n model_query: this.modelQuery,\n data: sendData,\n pk: sendData.pk,\n files: files\n }\n }));\n this.openRequest[id] = [res => {\n let data = typeof res.data.instance === \"string\" ? JSON.parse(res.data.instance) : res.data.instance;\n res.data.instance = this._parseServerRes(data);\n resolve(res);\n }, reject];\n });\n }));\n });\n return Promise.all(pList);\n });\n }\n\n /**\n *\n * @param elem {?SdcModel}\n * @param data {?object}\n * @returns {Promise<unknown>}\n */\n create({\n elem = null,\n data = null\n } = {}) {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n if (!elem) {\n elem = this.new(data);\n }\n return this.isConnected().then(() => {\n return new Promise((resolve, reject) => {\n this._readFiles(elem).then(files => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"create\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery,\n data: data ?? elem?.serialize() ?? {},\n files: files\n }\n }));\n this.openRequest[id] = [res => {\n let data = typeof res.data.instance === \"string\" ? JSON.parse(res.data.instance) : res.data.instance;\n if (elem) {\n elem.id = data[0]?.pk || data[0]?.id;\n }\n res.data.instance = this._parseServerRes(data)[0];\n resolve(res);\n }, reject];\n });\n });\n });\n }\n\n /**\n * Ensure the websocket is open and has completed the server-side connect\n * handshake before issuing model requests.\n *\n * Multiple callers can arrive while a connection attempt is already in\n * progress. In that case they are queued behind the same synthetic request id.\n *\n * @returns {Promise<void>}\n */\n isConnected() {\n return new Promise((resolve, reject) => {\n if (this._isConnected) {\n resolve();\n } else if (!this._isConnectingProcess || !this.openRequest[CONNECTING_REQUEST_ID]) {\n this._isConnectingProcess = true;\n this.openRequest[CONNECTING_REQUEST_ID] = [() => {}, () => {}];\n this._connectToServer().then(() => {\n resolve(this._checkConnection());\n });\n } else {\n const [resolveOrigin, rejectOrigin] = this.openRequest[CONNECTING_REQUEST_ID];\n this.openRequest[CONNECTING_REQUEST_ID] = [() => {\n resolveOrigin();\n resolve();\n }, () => {\n rejectOrigin();\n reject();\n }];\n }\n });\n }\n\n /**\n * Close the websocket and disable automatic reconnect for this queryset.\n */\n close() {\n if (this.socket) {\n this._autoReconnect = false;\n this.socket.onclose = () => {};\n this.socket.close();\n delete this[\"socket\"];\n }\n this.valuesList.forEach(elem => {\n elem._onClose();\n });\n }\n\n /**\n * Upload attached `File` values in fixed-size chunks before save/create calls.\n *\n * @param {SdcModel} elem\n * @returns {Promise<object>}\n */\n _readFiles(elem) {\n let toSolve = [];\n let files = {};\n if (!elem) {\n return Promise.resolve(files);\n }\n Object.keys(elem.constructor.fields).forEach(key => {\n const value = elem[key];\n if (value instanceof File) {\n toSolve.push(new Promise(async (resolve, reject) => {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.openRequest[id] = [resolve, reject];\n const buffer = await value.arrayBuffer();\n let result = new Uint8Array(buffer);\n let numberOfChunks = Math.ceil(result.length / MAX_FILE_UPLOAD);\n files[key] = {\n id: id,\n file_name: value.name,\n field_name: key,\n content_length: value.size\n };\n for (let i = 0; i < numberOfChunks; ++i) {\n const chunk = Array.from(result.slice(MAX_FILE_UPLOAD * i, MAX_FILE_UPLOAD * (i + 1)));\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"upload\",\n event_id: id,\n args: {\n chunk,\n idx: i,\n number_of_chunks: numberOfChunks,\n file_name: value.name,\n field_name: key,\n content_length: value.size,\n content_type: value.type,\n model_name: this.modelName,\n model_query: this.modelQuery\n }\n }));\n }\n }));\n }\n });\n return Promise.all(toSolve).then(() => {\n return files;\n });\n }\n\n /**\n * Route websocket responses to the matching pending request and update local\n * state when the server sends model payloads.\n *\n * @param {MessageEvent} e\n */\n async _onMessage(e) {\n let data = JSON.parse(e.data);\n if (data.is_error) {\n if (this.openRequest.hasOwnProperty(data.event_id)) {\n this.openRequest[data.event_id][1](new SdcModelError(data));\n this._closeOpenRequest(data.event_id);\n }\n if (data.msg || data.header) {\n (0,_sdc_events_js__WEBPACK_IMPORTED_MODULE_3__.trigger)(\"pushErrorMsg\", data.header || \"\", data.msg || \"\");\n }\n if (data.type === \"connect\") {\n this.openRequest[CONNECTING_REQUEST_ID][1](new SdcModelError(data));\n this._closeOpenRequest(CONNECTING_REQUEST_ID);\n this._autoReconnect = false;\n this.socket.close();\n }\n } else {\n if (data.msg || data.header) {\n (0,_sdc_events_js__WEBPACK_IMPORTED_MODULE_3__.trigger)(\"pushMsg\", data.header || \"\", data.msg || \"\");\n }\n if (data.type === \"connect\") {\n this._isConnected = true;\n this._isConnectingProcess = false;\n this.openRequest[CONNECTING_REQUEST_ID][0](data);\n this._closeOpenRequest(CONNECTING_REQUEST_ID);\n } else if ([\"load\", \"named_view\", \"detail_view\"].includes(data.type)) {\n const jsonRes = JSON.parse(data.args.data);\n data.args.data = await this._parseServerRes(jsonRes);\n } else if (data.type === \"on_update\" || data.type === \"on_create\") {\n const jsonRes = JSON.parse(data.args.data);\n let obj = await this._parseServerRes(jsonRes);\n let cb;\n if (data.type === \"on_create\") {\n cb = this.onCreate;\n } else {\n cb = this.onUpdate;\n }\n cb(obj);\n data.args.data = obj;\n }\n let instance = data.data?.instance;\n if (instance) {\n data.data.instance = JSON.parse(data.data.instance);\n }\n if (this.openRequest.hasOwnProperty(data.event_id)) {\n this.openRequest[data.event_id][0](data);\n this._closeOpenRequest(data.event_id);\n }\n }\n }\n\n /**\n * Wait until all in-flight websocket requests for this queryset are resolved.\n *\n * @returns {Promise<void>}\n */\n noOpenRequests() {\n return new Promise(resolve => {\n if (Object.keys(this.openRequest).length === 0) {\n return resolve();\n }\n this._onNoOpenRequests.push(resolve);\n });\n }\n\n /**\n * Remove a completed request and wake any `noOpenRequests()` waiters when the\n * request map becomes empty.\n *\n * @param {string} eventId\n */\n _closeOpenRequest(eventId) {\n delete this.openRequest[eventId];\n if (Object.keys(this.openRequest).length === 0) {\n this._onNoOpenRequests.forEach(x => x());\n this._onNoOpenRequests = [];\n }\n }\n\n /**\n * Establish the raw websocket connection for this queryset.\n *\n * @returns {Promise<void>}\n */\n _connectToServer() {\n return new Promise(resolve => {\n const modelIdentifier = `${this.modelName}` + (this.modelId > 0 ? `/${this.modelId}` : \"\");\n if (window.location.protocol === \"https:\") {\n this.socket = new WebSocket(`wss://${window.location.host}/sdc_ws/model/${modelIdentifier}`);\n } else {\n this.socket = new WebSocket(`ws://${window.location.host}/sdc_ws/model/${modelIdentifier}`);\n }\n this.socket.onmessage = this._onMessage.bind(this);\n this.socket.onclose = e => {\n console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`);\n this._isConnected = false;\n for (const [_key, value] of Object.entries(this.openRequest)) {\n value[1](e);\n }\n this.openRequest = {};\n setTimeout(() => {\n if (this._autoReconnect) {\n this._connectToServer().then(() => {});\n }\n }, 1000);\n };\n this.socket.onerror = err => {\n console.error(`Model Socket encountered error: ${err} Closing socket`);\n if (this._isConnected) {\n try {\n this.socket.close();\n } catch (e) {}\n }\n };\n this.socket.onopen = () => {\n resolve();\n };\n });\n }\n\n /**\n * Perform the application-level connect handshake once the websocket opens.\n *\n * @returns {Promise<*>}\n */\n _checkConnection() {\n const id = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n return new Promise((resolve, reject) => {\n this.socket.send(JSON.stringify({\n event: \"model\",\n event_type: \"connect\",\n event_id: id,\n args: {\n model_name: this.modelName,\n model_query: this.modelQuery\n }\n }));\n this.openRequest[id] = [resolve, reject];\n });\n }\n\n /**\n * Convert the backend model payload into locally tracked model objects.\n *\n * @param {Array<object>} results\n */\n _parseServerRes(results) {\n const newModels = [];\n for (const x of results) {\n const ModelClass = (0,_sdc_socket_js__WEBPACK_IMPORTED_MODULE_1__.getModel)(this.modelName);\n if (!ModelClass) {\n throw new Error(`${this.modelName} is no SdcModel. mybe the models ar not importad.`);\n }\n const newModel = new ModelClass({\n 'id': x.pk ?? x.id,\n ...x.fields\n });\n const currentModel = this.byId(newModel.id);\n if (currentModel) {\n currentModel.setValues(newModel);\n newModels.push(currentModel);\n } else {\n this.valuesList.push(newModel);\n newModel._setQuerySet(this, true);\n newModels.push(newModel);\n }\n }\n this.valuesList.sort((a, b) => a._id - b._id);\n return newModels;\n }\n}\nclass SdcModel {\n static fields = {};\n\n /**\n * Base model wrapper used by SDC model registrations.\n *\n * @param {string} modelName\n */\n constructor(modelName) {\n this._id = null;\n this._forms = [];\n this.loaded = false;\n this.formId = (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.uuidv4)();\n this.modelName = modelName;\n }\n\n /**\n *\n * @param {object?} modelQuerySet\n * @param {AbstractSDC} parent\n * @returns {SdcQuerySet}\n */\n static querySet(modelQuerySet = null, parent = null) {\n if (!parent) {\n return new SdcQuerySet(this.modeName, modelQuerySet);\n }\n return parent.querySet(this.modeName, modelQuerySet);\n }\n addForm($form) {\n // Remove old listeners if form already set\n const onChange = this._onChange.bind(this);\n this._forms.push($form);\n if ($form) {\n // Attach delegated event handler to all inputs\n $form.on(\"input.formWatcher change.formWatcher\", \"input, select, textarea\", onChange);\n }\n }\n _onChange(event) {\n const {\n name\n } = event.target;\n if (this.constructor.fields[name]) {\n this[`set${name}`]((0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.getValueFromField)(event.target));\n }\n }\n _updateForm(fieldName) {\n const self = this;\n this._forms.forEach($form => {\n $form.find(`[name=\"${fieldName}\"]`).each(function () {\n (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.setValueInField)(this, self[fieldName]);\n });\n });\n }\n setValues(data = {}) {\n throw new Error(\"setValues() must be implemented by subclass\");\n }\n\n /**\n * Attach the queryset that owns this model instance.\n *\n * @param {SdcQuerySet} querySet\n * @param {boolean} isLoaded\n */\n _setQuerySet(querySet, isLoaded) {\n this._querySet = new WeakRef(querySet);\n this.loaded = isLoaded;\n }\n save({\n formName = \"edit_form\",\n data = null\n } = {}) {\n return this._querySet.deref().save({\n pk: this.id,\n formName,\n data\n });\n }\n create({\n data = null\n } = {}) {\n return this._querySet.deref().create({\n elem: this,\n data\n });\n }\n delete() {\n return this._querySet.deref().delete({\n elem: this\n });\n }\n load() {\n return this._querySet.deref().update({\n item: this\n });\n }\n get id() {\n return this._id;\n }\n set pk(data) {\n this._id = data;\n }\n get pk() {\n return this._id;\n }\n close() {\n return this._querySet.deref().close();\n }\n _onClose() {\n Object.keys(this.constructor.fields).filter(x => this[`_${x}`] instanceof SdcQuerySet).forEach(x => this[`_${x}`].close());\n }\n\n /**\n * Request the server-rendered detail view for this model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n detailView({\n cbResolve = null,\n cbReject = null,\n templateContext = {}\n }) {\n return this._querySet.deref().detailView({\n pk: this.id,\n cbResolve,\n cbReject,\n templateContext\n });\n }\n serialize() {\n return Object.entries(this.constructor.fields).reduce((acc, [key, val]) => {\n const value = this[key];\n if (value instanceof SdcQuerySet) {\n if (val.many_to_many || val.one_to_many) {\n acc[key] = value.getIds();\n } else {\n const allIds = value.getIds();\n if (allIds.length > 0) {\n acc[key] = allIds[0];\n } else {\n acc[key] = null;\n }\n }\n } else if (val.is_relation && value instanceof SdcModel) {\n acc[key] = value.id ?? null;\n } else {\n acc[key] = value;\n }\n return acc;\n }, {});\n }\n toJson() {\n const res = {};\n for (let key in this.constructor.fields) {\n const value = this[key];\n if (value instanceof File) {\n res[key] = value.name;\n } else if (value instanceof SdcModel) {\n res[key] = value.id;\n } else if (value instanceof SdcQuerySet) {\n res[key] = value.getIds();\n } else {\n res[key] = value;\n }\n }\n return res;\n }\n\n /**\n * Backwards-compatible alias for syncing values from a form into the model.\n *\n * @param {*} $forms\n * @returns {*}\n */\n syncFormToModel($forms) {\n return this.syncForm($forms);\n }\n\n /**\n * Resolve the form collection associated with this model instance.\n *\n * @param {*} $forms\n * @returns {*}\n */\n _resolveForms($forms) {\n if (!$forms || !$forms.hasClass(this.formId)) {\n return $(`.${this.formId}`);\n }\n return $forms;\n }\n\n /**\n * Copy the current model state into matching form fields.\n *\n * @param {*} $forms\n */\n syncModelToForm($forms) {\n $forms = this._resolveForms($forms);\n const self = this;\n const fields = this.constructor.fields;\n $forms.each(function () {\n const pk = normalizePk($(this).data(\"model_pk\"));\n if (self.id !== pk) {\n return;\n }\n for (let formItem of this.elements) {\n let name = formItem.name;\n if (name && name !== \"\" && !!fields[name]) {\n (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.setValueInField)(formItem, self[name]);\n }\n }\n });\n }\n\n /**\n * Copy matching form values back onto the current model instance.\n *\n * Hidden inputs are parsed to their original primitive type when possible.\n *\n * @param {*} $forms\n * @returns {*}\n */\n syncForm($forms) {\n $forms = this._resolveForms($forms);\n const self = this;\n const fields = this.constructor.fields;\n const returnValue = {};\n function setValueInForm(name, value) {\n if (!!fields[name]) {\n self[name] = value;\n }\n returnValue[name] = value;\n }\n $forms.each(function () {\n const pk = normalizePk($(this).data(\"model_pk\"));\n if (self.id !== pk && (self.id !== null || pk !== -1)) {\n return;\n }\n for (let formItem of this.elements) {\n setValueInForm(formItem.name, (0,_sdc_utils_js__WEBPACK_IMPORTED_MODULE_0__.getValueFromField)(formItem));\n }\n return self;\n });\n return returnValue;\n }\n\n /**\n * Render the correct server-side form for this model state.\n *\n * @param {object} options\n * @returns {*}\n */\n form({\n cbResolve = null,\n cbReject = null\n } = {}) {\n if (this.id === null || this.id === -1) {\n return this._createForm({\n cbReject,\n cbResolve\n });\n }\n return this._editForm({\n cbReject,\n cbResolve\n });\n }\n\n /**\n * Render the create form for a new model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _createForm({\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $(\"<div>\");\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"create_form\",\n formName: null,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Render the edit form for an existing model instance.\n *\n * @param {object} options\n * @returns {*}\n */\n _editForm({\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $(\"<div>\");\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"edit_form\",\n formName: null,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Render a named server-side form for this model.\n *\n * @param {object} options\n * @returns {*}\n */\n namedForm({\n formName,\n cbResolve = null,\n cbReject = null\n }) {\n let $divForm = $('<div class=\"container-fluid\">');\n this._querySet.deref().getForm({\n modelObj: this,\n eventType: \"named_form\",\n formName,\n $divForm,\n cbResolve,\n cbReject,\n formId: this.formId\n });\n return $divForm;\n }\n\n /**\n * Validate a field value using the supplied field config.\n *\n * @param {*} value\n * @param {object} config\n */\n validate(value, config) {\n const err = validateField(value, config);\n if (err) throw new Error(err);\n }\n\n /**\n * Convert a raw input value into the shape expected by the field config.\n *\n * @param {*} value\n * @param {object} config\n * @returns {*}\n */\n parseValue(value, config) {\n const {\n type\n } = config;\n switch (type) {\n case \"CharField\":\n case \"TeextField\":\n case \"UUIDField\":\n case \"EmailField\":\n return `${value}`;\n case \"IntegerField\":\n case \"AutoField\":\n case \"BigIntegerField\":\n return parseInt(value, 10);\n case \"FloatField\":\n case \"DecimalField\":\n if (typeof value !== \"number\") {\n return \"Must be a number\";\n }\n break;\n case \"BooleanField\":\n return !!value;\n case \"DateField\":\n case \"DateTimeField\":\n return Date.parse(value);\n case \"URLField\":\n return new URL(value);\n case \"FileField\":\n if (value == null) {\n return null;\n }\n if (typeof value === \"string\") {\n return null;\n }\n if (FileLoaded.isValid(value)) {\n return new FileLoaded(value);\n }\n if (value instanceof FileLoaded) {\n return new FileLoaded(value);\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n if (config.max_size && value.size > config.max_size) {\n return `File too large (max ${config.max_size} bytes)`;\n }\n if (config.allowed_types && !config.allowed_types.includes(value.type)) {\n return `Invalid file type (${value.type})`;\n }\n return value;\n }\n break;\n case \"JSONField\":\n if (typeof value === \"object\") {\n return value;\n }\n if (typeof value === \"string\") {\n return JSON.parse(value);\n }\n break;\n default:\n break;\n }\n return value;\n }\n}\n\n/**\n * Validate a field value against the field metadata received from the backend.\n *\n * @param {*} value\n * @param {object} config\n * @returns {?string}\n */\nfunction validateField(value, config) {\n const {\n type,\n required,\n max_length: maxLength,\n is_relation: isRelation,\n many_to_many: manyToMany,\n one_to_many: oneToMany,\n many_to_one: manyToOne,\n one_to_one: oneToOne,\n related_model: relatedModel\n } = config;\n void isRelation;\n if (required) {\n if (value === null || value === undefined || value === \"\") {\n return \"This field is required\";\n }\n }\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n if (manyToMany || oneToMany || manyToOne || oneToOne) {\n if (!(value instanceof SdcQuerySet) || value.modelName !== relatedModel) {\n if (typeof value !== \"object\" && Number.isNaN(parseInt(value))) {\n return \"Must be object or ID\";\n }\n return null;\n }\n }\n switch (type) {\n case \"CharField\":\n case \"TextField\":\n if (typeof value !== \"string\") {\n return \"Must be a string\";\n }\n if (maxLength && value.length > maxLength) {\n return `Max length is ${maxLength}`;\n }\n break;\n case \"IntegerField\":\n case \"AutoField\":\n case \"BigIntegerField\":\n if (!Number.isInteger(value)) {\n return \"Must be an integer\";\n }\n break;\n case \"FloatField\":\n case \"DecimalField\":\n if (typeof value !== \"number\") {\n return \"Must be a number\";\n }\n break;\n case \"BooleanField\":\n if (typeof value !== \"boolean\") {\n return \"Must be a boolean\";\n }\n break;\n case \"DateField\":\n case \"DateTimeField\":\n if (isNaN(Date.parse(value))) {\n return \"Must be a valid date\";\n }\n break;\n case \"EmailField\":\n if (typeof value !== \"string\" || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n return \"Invalid email\";\n }\n break;\n case \"URLField\":\n try {\n new URL(value);\n } catch {\n return \"Invalid URL\";\n }\n break;\n case \"UUIDField\":\n if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value)) {\n return \"Invalid UUID\";\n }\n break;\n case \"JSONField\":\n if (typeof value !== \"object\") {\n return \"Must be JSON object\";\n }\n break;\n case \"FileField\":\n if (!FileLoaded.isValid(value) && !(value instanceof File) && !(value instanceof FileLoaded)) {\n return \"Must be a valid file\";\n }\n break;\n default:\n break;\n }\n return null;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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SUFFRixLQUFLLFlBQVk7TUFDZixJQUFJLE9BQU9BLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyw0QkFBNEIsQ0FBQzRQLElBQUksQ0FBQzVQLEtBQUssQ0FBQyxFQUFFO1FBQzFFLE9BQU8sZUFBZTtNQUN4QjtNQUNBO0lBRUYsS0FBSyxVQUFVO01BQ2IsSUFBSTtRQUNGLElBQUk0TyxHQUFHLENBQUM1TyxLQUFLLENBQUM7TUFDaEIsQ0FBQyxDQUFDLE1BQU07UUFDTixPQUFPLGFBQWE7TUFDdEI7TUFDQTtJQUVGLEtBQUssV0FBVztNQUNkLElBQUksQ0FBQywyRUFBMkUsQ0FBQzRQLElBQUksQ0FBQzVQLEtBQUssQ0FBQyxFQUFFO1FBQzVGLE9BQU8sY0FBYztNQUN2QjtNQUNBO0lBRUYsS0FBSyxXQUFXO01BQ2QsSUFBSSxPQUFPQSxLQUFLLEtBQUssUUFBUSxFQUFFO1FBQzdCLE9BQU8scUJBQXFCO01BQzlCO01BQ0E7SUFDRixLQUFLLFdBQVc7TUFDZCxJQUFJLENBQUNmLFVBQVUsQ0FBQ2MsT0FBTyxDQUFDQyxLQUFLLENBQUMsSUFBSSxFQUFFQSxLQUFLLFlBQVlHLElBQUksQ0FBQyxJQUFJLEVBQUVILEtBQUssWUFBWWYsVUFBVSxDQUFDLEVBQUU7UUFDNUYsT0FBTyxzQkFBc0I7TUFDL0I7TUFDQTtJQUNGO01BQ0U7RUFDSjtFQUVBLE9BQU8sSUFBSTtBQUNiIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vc2RjX2NsaWVudC8uL3NyYy9zaW1wbGVEb21Db250cm9sL3NkY19tb2RlbC5qcz80NDM2Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Z2V0VmFsdWVGcm9tRmllbGQsIHNldFZhbHVlSW5GaWVsZCwgdXVpZHY0fSBmcm9tIFwiLi9zZGNfdXRpbHMuanNcIjtcbmltcG9ydCB7Z2V0TW9kZWx9IGZyb20gXCIuL3NkY19zb2NrZXQuanNcIlxuaW1wb3J0IHthcHB9IGZyb20gXCIuL3NkY19tYWluLmpzXCI7XG5pbXBvcnQge3RyaWdnZXJ9IGZyb20gXCIuL3NkY19ldmVudHMuanNcIjtcblxuY29uc3QgTUFYX0ZJTEVfVVBMT0FEID0gMjUwMDA7XG5jb25zdCBDT05ORUNUSU5HX1JFUVVFU1RfSUQgPSBcIl9jb25uZWN0aW5nX3Byb2Nlc3NcIjtcblxuY2xhc3MgU2RjTW9kZWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICBpZiAodHlwZW9mIHByb3BzID09PSAnc3RyaW5nJykge1xuICAgICAgcHJvcHMgPSB7XG4gICAgICAgIG1zZzogcHJvcHMsXG4gICAgICAgIGlzX2Vycm9yOiB0cnVlLFxuICAgICAgICBoZWFkZXI6ICdFcnJvcidcbiAgICAgIH1cbiAgICB9XG4gICAgc3VwZXIocHJvcHMubXNnKVxuICAgIHRoaXMubXNnID0gcHJvcHMubXNnO1xuICAgIHRoaXMuaGVhZGVyID0gcHJvcHMuaGVhZGVyO1xuICAgIHRoaXMuaXNfZXJyb3IgPSBwcm9wcy5pc19lcnJvcjtcbiAgICB0aGlzLmh0bWwgPSBwcm9wcy5odG1sO1xuICB9XG59XG5cbmNsYXNzIEZpbGVMb2FkZWQge1xuICBjb25zdHJ1Y3Rvcih7bmFtZSwgdXJsfSkge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gICAgdGhpcy5jb250ZW50ID0gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmIChmb3JjZSB8fCAhdGhpcy5jb250ZW50KSB7XG4gICAgICB0aGlzLmNvbnRlbnQgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICQuZ2V0KHRoaXMudXJsKS50aGVuKHJlc29sdmUpLmNhdGNoKFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUoJycpO1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRlbnQ7XG4gIH1cblxuICBhc3luYyB0ZXh0KCkge1xuICAgIHJldHVybiB0aGlzLmxvYWQoKTtcbiAgfVxuXG4gIHN0YXRpYyBpc1ZhbGlkKHZhbHVlKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJlxuICAgICAgISh2YWx1ZSBpbnN0YW5jZW9mIEZpbGUpICYmXG4gICAgICB0eXBlb2YgdmFsdWUudXJsID09PSBcInN0cmluZ1wiICYmXG4gICAgICB0eXBlb2YgdmFsdWUubmFtZSA9PT0gXCJzdHJpbmdcIlxuICAgICk7XG4gIH1cblxuXG59XG5cbi8qKlxuICogTm9ybWFsaXplIGFuIGluY29taW5nIHByaW1hcnkga2V5IHZhbHVlLlxuICpcbiAqIGAtMWAgaXMgdXNlZCB0aHJvdWdob3V0IHRoaXMgbW9kdWxlIGFzIHRoZSBzZW50aW5lbCBmb3IgXCJuZXcgb2JqZWN0IC8gbm8gcGtcIi5cbiAqXG4gKiBAcGFyYW0geyp9IHBrXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mdW5jdGlvbiBub3JtYWxpemVQayhwaykge1xuICBjb25zdCBub3JtYWxpemVkUGsgPSBwYXJzZUludChwayA/PyAtMSwgMTApO1xuICByZXR1cm4gTnVtYmVyLmlzTmFOKG5vcm1hbGl6ZWRQaykgPyAtMSA6IG5vcm1hbGl6ZWRQaztcbn1cblxuZXhwb3J0IGNsYXNzIFNkY1F1ZXJ5U2V0IHtcbiAgLyoqXG4gICAqIExpZ2h0d2VpZ2h0IGNsaWVudC1zaWRlIGNvbGxlY3Rpb24gd3JhcHBlciBhcm91bmQgdGhlIFNEQyBtb2RlbCB3ZWJzb2NrZXQuXG4gICAqXG4gICAqIFRoZSBxdWVyeXNldCBleHBvc2VzIGFycmF5LWxpa2UgYWNjZXNzIHRocm91Z2ggYSBwcm94eSB3aGlsZSBhbHNvIGtlZXBpbmdcbiAgICogdHJhY2sgb2Ygc29ja2V0IHN0YXRlIGFuZCBvdXRzdGFuZGluZyByZXF1ZXN0cyBmb3IgdGhhdCBtb2RlbC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGVsTmFtZVxuICAgKiBAcGFyYW0ge29iamVjdH0gbW9kZWxRdWVyeVxuICAgKi9cbiAgY29uc3RydWN0b3IobW9kZWxOYW1lLCBtb2RlbFF1ZXJ5ID0ge30pIHtcbiAgICB0aGlzLnZhbHVlc0xpc3QgPSBbXTtcbiAgICB0aGlzLmxvYWRlZCA9IGZhbHNlO1xuICAgIHRoaXMubW9kZWxOYW1lID0gbW9kZWxOYW1lO1xuICAgIHRoaXMubW9kZWxRdWVyeSA9IG1vZGVsUXVlcnkgPz8ge307XG4gICAgdGhpcy5fb25Ob09wZW5SZXF1ZXN0cyA9IFtdO1xuICAgIHRoaXMuX2lzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgdGhpcy5faXNDb25uZWN0aW5nUHJvY2VzcyA9IGZhbHNlO1xuICAgIHRoaXMuX2F1dG9SZWNvbm5lY3QgPSB0cnVlO1xuICAgIHRoaXMuc29ja2V0ID0gbnVsbDtcbiAgICAvLyBSZXF1ZXN0IHJlc29sdmVycyBhcmUgc3RvcmVkIGJ5IHdlYnNvY2tldCBldmVudCBpZCB1bnRpbCB0aGUgc2VydmVyIHJlc3BvbmRzLlxuICAgIHRoaXMub3BlblJlcXVlc3QgPSB7fTtcbiAgICB0aGlzLm1vZGVsSWQgPSAwO1xuICAgIHRoaXMub25VcGRhdGUgPSAoKSA9PiB7XG4gICAgfTtcbiAgICB0aGlzLm9uQ3JlYXRlID0gKCkgPT4ge1xuICAgIH07XG5cbiAgICByZXR1cm4gbmV3IFByb3h5KHRoaXMsIHtcbiAgICAgIGdldCh0YXJnZXQsIHByb3ApIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wICE9PSBcInN5bWJvbFwiICYmICFpc05hTihwcm9wKSkge1xuICAgICAgICAgIHJldHVybiB0YXJnZXQudmFsdWVzTGlzdFtwcm9wXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFyZ2V0W3Byb3BdO1xuICAgICAgfSxcblxuICAgICAgc2V0KHRhcmdldCwgcHJvcCwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCFpc05hTihwcm9wKSkge1xuICAgICAgICAgIHRhcmdldC52YWx1ZXNMaXN0W3Byb3BdID0gdmFsdWU7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0W3Byb3BdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgbGV0IGlkeCA9IC0xO1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0OiAoKSA9PiB7XG4gICAgICAgICsraWR4O1xuICAgICAgICBpZiAoaWR4IDwgdGhpcy52YWx1ZXNMaXN0Lmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiB7dmFsdWU6IHRoaXMudmFsdWVzTGlzdFtpZHhdLCBkb25lOiBmYWxzZX07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHt2YWx1ZTogbnVsbCwgZG9uZTogdHJ1ZX07XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBzZXQgb25fY3JlYXRlKGhhbmRsZXIpIHtcbiAgICB0aGlzLm9uQ3JlYXRlID0gaGFuZGxlcjtcbiAgfVxuXG4gIHNldCBvbl91cGRhdGUoaGFuZGxlcikge1xuICAgIHRoaXMub25VcGRhdGUgPSBoYW5kbGVyO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW50ZWdyfHN0cmluZz58aW50ZWdlcnxTZGNNb2RlbHxTZGNRdWVyeVNldHxzdHJpbmd9IGlkc1xuICAgKi9cbiAgc2V0SWRzKGlkcykge1xuXG4gICAgaWYgKGlkcyA9PT0gbnVsbCB8fCBpZHMgPT09IFwiXCIgfHwgQXJyYXkuaXNBcnJheShpZHMpICYmIGlkcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMudmFsdWVzTGlzdCA9IFtdO1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdDtcbiAgICB9IGVsc2UgaWYgKGlkcyBpbnN0YW5jZW9mIFNkY1F1ZXJ5U2V0KSB7XG4gICAgICB0aGlzLnZhbHVlc0xpc3QgPSBzdHJ1Y3R1cmVkQ2xvbmUoaWRzLnZhbHVlc0xpc3QpO1xuICAgICAgdGhpcy52YWx1ZXNMaXN0LmZvckVhY2godmFsdWUgPT4gdmFsdWUuX3NldFF1ZXJ5U2V0KHRoaXMsIHRydWUpKTtcbiAgICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3Q7XG4gICAgfSBlbHNlIGlmIChpZHMgaW5zdGFuY2VvZiBTZGNNb2RlbCkge1xuICAgICAgdGhpcy52YWx1ZXNMaXN0ID0gW3N0cnVjdHVyZWRDbG9uZShpZHMpXTtcbiAgICAgIHRoaXMudmFsdWVzTGlzdC5mb3JFYWNoKHZhbHVlID0+IHZhbHVlLl9zZXRRdWVyeVNldCh0aGlzLCB0cnVlKSk7XG4gICAgICByZXR1cm4gdGhpcy52YWx1ZXNMaXN0O1xuICAgIH1cblxuICAgIGxldCBudW1MaXN0LCBudW1JZCA9IE51bWJlci5OYU47XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIoaWRzKSkge1xuICAgICAgbnVtSWQgPSBpZHM7XG4gICAgfSBlbHNlIGlmIChpZHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgY29uc3QgdGVtcE51bUxpc3QgPSBpZHMubWFwKCh4KSA9PiBwYXJzZUludCh4KSk7XG4gICAgICBpZiAoIXRlbXBOdW1MaXN0LnNvbWUoTnVtYmVyLmlzTmFOKSkge1xuICAgICAgICBudW1MaXN0ID0gdGVtcE51bUxpc3Q7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgaWRzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBjb25zdCB0ZW1wTnVtTGlzdCA9IGlkcy5zcGxpdCgnLCcpLm1hcCgoeCkgPT4gcGFyc2VJbnQoeCkpO1xuICAgICAgaWYgKCF0ZW1wTnVtTGlzdC5zb21lKE51bWJlci5pc05hTikpIHtcbiAgICAgICAgbnVtTGlzdCA9IHRlbXBOdW1MaXN0XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBudW1JZCA9IHBhcnNlSW50KGlkcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFOdW1iZXIuaXNOYU4obnVtSWQpKSB7XG4gICAgICBjb25zdCBuZXdNb2RlbCA9IHRoaXMubmV3KCk7XG4gICAgICBuZXdNb2RlbC5pZCA9IG51bUlkO1xuICAgIH0gZWxzZSBpZiAobnVtTGlzdCkge1xuICAgICAgdGhpcy52YWx1ZXNMaXN0ID0gdGhpcy52YWx1ZXNMaXN0LmZpbHRlcigoaXRlbSkgPT4gbnVtTGlzdC5pbmNsdWRlcyhpdGVtLmlkKSk7XG4gICAgICBjb25zdCB2YWx1ZUlkcyA9IHRoaXMuZ2V0SWRzKCk7XG4gICAgICBudW1MaXN0LmZpbHRlcih4ID0+ICF2YWx1ZUlkcy5pbmNsdWRlcyh4KSkuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgdGhpcy52YWx1ZXNMaXN0LnB1c2gobmV3IChnZXRNb2RlbCh0aGlzLm1vZGVsTmFtZSkpKHtpZH0pKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWx1ZXNMaXN0O1xuICB9XG5cbiAgZ2V0SWRzKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3QubWFwKHggPT4geC5pZCk7XG4gIH1cblxuICAvKipcbiAgICogTnVtYmVyIG9mIG1vZGVsIGluc3RhbmNlcyBjdXJyZW50bHkgcHJlc2VudCBpbiB0aGUgcXVlcnlzZXQgY2FjaGUuXG4gICAqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbGVuZ3RoKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc0xpc3QubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYSBtb2RlbCBpbnN0YW5jZSBieSBpZCwgbG9hZGluZyB0aGUgcXVlcnlzZXQgZmlyc3QgaWYgbmVlZGVkLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IGlkXG4gICAqIEByZXR1cm5zIHtTZGNNb2RlbHxudWxsfVxuICAgKi9cbiAgYnlJZChpZCkge1xuICAgIGlmIChpZCAhPT0gbnVsbCkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZElkID0gbm9ybWFsaXplUGsoaWQpO1xuICAgICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdC5maW5kKChlbG0pID0+IGVsbS5pZCA9PT0gbm9ybWFsaXplZElkKSA/PyBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlIGFkZGl0aW9uYWwgcXVlcnkgY29uc3RyYWludHMgaW50byB0aGUgY3VycmVudCBxdWVyeXNldC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHJldHVybnMge1NkY1F1ZXJ5U2V0fVxuICAgKi9cbiAgc2V0RmlsdGVyKG1vZGVsUXVlcnkpIHtcbiAgICB0aGlzLm1vZGVsUXVlcnkgPSBtb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkRmlsdGVyKG1vZGVsUXVlcnkpIHtcbiAgICB0aGlzLm1vZGVsUXVlcnkgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm1vZGVsUXVlcnksIG1vZGVsUXVlcnkpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7P29iamVjdH0gdmFsdWVzXG4gICAqIEByZXR1cm5zIHtTZGNNb2RlbH1cbiAgICovXG4gIG5ldyh2YWx1ZXMgPSB7fSkge1xuICAgIGNvbnN0IG5ld01vZGVsID0gbmV3IChnZXRNb2RlbCh0aGlzLm1vZGVsTmFtZSkpKHZhbHVlcyk7XG4gICAgbmV3TW9kZWwuX3NldFF1ZXJ5U2V0KHRoaXMsIGZhbHNlKTtcbiAgICB0aGlzLnZhbHVlc0xpc3QucHVzaChuZXdNb2RlbCk7XG4gICAgcmV0dXJuIG5ld01vZGVsO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbW9kZWwgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5IGludG8gdGhlIHF1ZXJ5c2V0IGNhY2hlLlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHJldHVybnMge1Byb21pc2U8U2RjUXVlcnlTZXQ+fVxuICAgKi9cbiAgbG9hZChtb2RlbFF1ZXJ5ID0gbnVsbCkge1xuICAgIHRoaXMudmFsdWVzTGlzdCA9IFtdO1xuICAgIHRoaXMubW9kZWxRdWVyeSA9IG1vZGVsUXVlcnkgPz8gdGhpcy5tb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzLl9zZW5kTG9hZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbW9kZWwgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5IGludG8gdGhlIHF1ZXJ5c2V0IGNhY2hlLlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHBhcmFtIHs/U2RjTW9kZWx9IGl0ZW1cbiAgICogQHJldHVybnMge1Byb21pc2U8U2RjUXVlcnlTZXQ+fVxuICAgKi9cbiAgdXBkYXRlKHttb2RlbFF1ZXJ5ID0gbnVsbCwgaXRlbSA9IG51bGx9KSB7XG4gICAgdGhpcy5tb2RlbFF1ZXJ5ID0gbW9kZWxRdWVyeSA/PyB0aGlzLm1vZGVsUXVlcnk7XG4gICAgbGV0IGxvYWRRdWVyeSA9IGl0ZW0gPyB7cGs6IGl0ZW0uaWR9IDogdGhpcy5tb2RlbFF1ZXJ5O1xuICAgIHJldHVybiB0aGlzLl9zZW5kTG9hZChsb2FkUXVlcnkpO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBwayB7aW50ZWdyfVxuICAgKiBAcGFyYW0gZWxlbSB7U2RjTW9kZWx9XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHVua25vd24+fVxuICAgKi9cbiAgZGVsZXRlKHtwayA9IG51bGwsIGVsZW0gPSBudWxsfSkge1xuICAgIHBrID0gIWVsZW0gPyBwayA6IGVsZW0uaWQ7XG4gICAgaWYgKHBrID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwayBvciBlbGVtIG11c3QgYmUgc2V0XCIpO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGV2ZW50OiBcIm1vZGVsXCIsXG4gICAgICAgICAgICBldmVudF90eXBlOiBcImRlbGV0ZVwiLFxuICAgICAgICAgICAgZXZlbnRfaWQ6IGlkLFxuICAgICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgbW9kZWxfcXVlcnk6IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgICAgcGssXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW3Jlc29sdmUsIHJlamVjdF07XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRoZSBzZXJ2ZXItc2lkZSBxdWVyeXNldCBkYXRhIG92ZXIgdGhlIG1vZGVsIHdlYnNvY2tldC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAqL1xuICBfc2VuZExvYWQobG9hZFF1ZXJ5ID0gbnVsbCkge1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJsb2FkXCIsXG4gICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogbG9hZFF1ZXJ5ID8/IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtpZF0gPSBbKGRhdGEpPT4ge1xuICAgICAgICAgIHRoaXMubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9LCByZWplY3RdO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSBsaXN0LXZpZXcgZW5kcG9pbnQgZm9yIHRoZSBjdXJyZW50IG1vZGVsLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIF9zZW5kTGlzdFZpZXcoe1xuICAgICAgICAgICAgICAgICAgbW9kZWxRdWVyeSA9IHt9LFxuICAgICAgICAgICAgICAgICAgY2JSZXNvbHZlID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgIGNiUmVqZWN0ID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgIHRlbXBsYXRlQ29udGV4dCA9IHt9LFxuICAgICAgICAgICAgICAgIH0pIHtcbiAgICByZXR1cm4gdGhpcy52aWV3KHtcbiAgICAgIG1vZGVsUXVlcnksXG4gICAgICBjYlJlc29sdmUsXG4gICAgICBjYlJlamVjdCxcbiAgICAgIHRlbXBsYXRlQ29udGV4dCxcbiAgICAgIGV2ZW50VHlwZTogXCJsaXN0X3ZpZXdcIixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgYSBuYW1lZCBtb2RlbCB2aWV3IGFuZCBhcHBlbmQgaXRzIEhUTUwgdG8gYSBjb250YWluZXIgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICB2aWV3KHtcbiAgICAgICAgIHZpZXdOYW1lID0gXCJodG1sX2xpc3RfdGVtcGxhdGVcIixcbiAgICAgICAgIG1vZGVsUXVlcnkgPSB7fSxcbiAgICAgICAgIGNiUmVzb2x2ZSA9IG51bGwsXG4gICAgICAgICBjYlJlamVjdCA9IG51bGwsXG4gICAgICAgICB0ZW1wbGF0ZUNvbnRleHQgPSB7fSxcbiAgICAgICAgIGV2ZW50VHlwZSA9IFwibmFtZWRfdmlld1wiLFxuICAgICAgIH0pIHtcbiAgICBsZXQgJGRpdkxpc3QgPSAkKCc8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG4gICAgdGhpcy5pc0Nvbm5lY3RlZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaWQgPSB1dWlkdjQoKTtcbiAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgIGV2ZW50X3R5cGU6IGV2ZW50VHlwZSxcbiAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgYXJnczoge1xuICAgICAgICAgICAgdmlld19uYW1lOiB2aWV3TmFtZSxcbiAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgbW9kZWxfcXVlcnk6IG1vZGVsUXVlcnksXG4gICAgICAgICAgICB0ZW1wbGF0ZV9jb250ZXh0OiB0ZW1wbGF0ZUNvbnRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLm9wZW5SZXF1ZXN0W2lkXSA9IFtcbiAgICAgICAgKGRhdGEpID0+IHtcbiAgICAgICAgICAkZGl2TGlzdC5hcHBlbmQoZGF0YS5odG1sKTtcbiAgICAgICAgICBhcHAucmVmcmVzaCgkZGl2TGlzdCk7XG4gICAgICAgICAgY2JSZXNvbHZlICYmIGNiUmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfSxcbiAgICAgICAgKHJlcykgPT4ge1xuICAgICAgICAgIGNiUmVqZWN0ICYmIGNiUmVqZWN0KHJlcyk7XG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZMaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZGV0YWlsLXZpZXcgZW5kcG9pbnQgZm9yIGEgc2luZ2xlIG1vZGVsIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIF9zZW5kRGV0YWlsVmlldyh7XG4gICAgICAgICAgICAgICAgICAgIHBrID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2JSZXNvbHZlID0gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2JSZWplY3QgPSBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZUNvbnRleHQgPSB7fSxcbiAgICAgICAgICAgICAgICAgIH0pIHtcbiAgICBwayA9IG5vcm1hbGl6ZVBrKHBrKTtcbiAgICBsZXQgJGRpdkxpc3QgPSAkKCc8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG5cbiAgICB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIGV2ZW50OiBcIm1vZGVsXCIsXG4gICAgICAgICAgZXZlbnRfdHlwZTogXCJkZXRhaWxfdmlld1wiLFxuICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgIG1vZGVsX3F1ZXJ5OiB0aGlzLm1vZGVsUXVlcnksXG4gICAgICAgICAgICBwayxcbiAgICAgICAgICAgIHRlbXBsYXRlX2NvbnRleHQ6IHRlbXBsYXRlQ29udGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAoZGF0YSkgPT4ge1xuICAgICAgICAgICRkaXZMaXN0LmFwcGVuZChkYXRhLmh0bWwpO1xuICAgICAgICAgIGFwcC5yZWZyZXNoKCRkaXZMaXN0KTtcbiAgICAgICAgICBjYlJlc29sdmUgJiYgY2JSZXNvbHZlKGRhdGEpO1xuICAgICAgICB9LFxuICAgICAgICAocmVzKSA9PiB7XG4gICAgICAgICAgY2JSZWplY3QgJiYgY2JSZWplY3QocmVzKTtcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgfSk7XG5cbiAgICByZXR1cm4gJGRpdkxpc3Q7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYSBtb2RlbCBmb3JtIGZyYWdtZW50IGFuZCBhdHRhY2ggdGhlIFNEQyBmb3JtIG1ldGFkYXRhIGV4cGVjdGVkIGJ5XG4gICAqIHRoZSByZXN0IG9mIHRoZSBjbGllbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFR5cGVcbiAgICogQHBhcmFtIHtTZGNNb2RlbH0gbW9kZWxPYmpcbiAgICovXG4gIGdldEZvcm0oe21vZGVsT2JqLCBldmVudFR5cGUsIGZvcm1OYW1lLCAkZGl2Rm9ybSwgY2JSZXNvbHZlLCBjYlJlamVjdCwgZm9ybUlkfSkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgY29uc3QgcGsgPSBtb2RlbE9iai5pZCA/PyAtMTtcbiAgICB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgZXZlbnQ6IFwibW9kZWxcIixcbiAgICAgICAgICBldmVudF90eXBlOiBldmVudFR5cGUsXG4gICAgICAgICAgZXZlbnRfaWQ6IGlkLFxuICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgcGssXG4gICAgICAgICAgICBmb3JtX25hbWU6IGZvcm1OYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHBrID09PSBudWxsIHx8IHBrID09PSAtMSA/IFwiY3JlYXRlXCIgOiBcImVkaXRcIjtcblxuICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgKGRhdGEpID0+IHtcbiAgICAgICAgJGRpdkZvcm0uYXBwZW5kKGRhdGEuaHRtbCk7XG4gICAgICAgIGxldCAkZm9ybSA9ICRkaXZGb3JtXG4gICAgICAgICAgLmNsb3Nlc3QoXCJmb3JtXCIpXG4gICAgICAgICAgLmFkZENsYXNzKFxuICAgICAgICAgICAgYHNkYy1tb2RlbC0ke2NsYXNzTmFtZX0tZm9ybSBzZGMtbW9kZWwtZm9ybSAke2Zvcm1JZH1gLFxuICAgICAgICAgIClcbiAgICAgICAgICAuZGF0YShcIm1vZGVsXCIsIG1vZGVsT2JqKVxuICAgICAgICAgIC5kYXRhKFwibW9kZWxfcGtcIiwgcGspXG4gICAgICAgICAgLmRhdGEoXCJmb3JtX25hbWVcIiwgZm9ybU5hbWUpO1xuICAgICAgICBtb2RlbE9iai5hZGRGb3JtKCRmb3JtKTtcbiAgICAgICAgaWYgKCRmb3JtLmxlbmd0aCA+IDAgJiYgISRmb3JtWzBdLmhhc0F0dHJpYnV0ZShcInNkY19zdWJtaXRcIikpIHtcbiAgICAgICAgICAkZm9ybS5hdHRyKFwic2RjX3N1Ym1pdFwiLCBcInN1Ym1pdE1vZGVsRm9ybURpc3RyaWJ1dG9yXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXBwLnJlZnJlc2goJGRpdkZvcm0pLnRoZW4oKCkgPT4gbnVsbCk7XG4gICAgICAgIGNiUmVzb2x2ZSAmJiBjYlJlc29sdmUoZGF0YSk7XG4gICAgICB9LFxuICAgICAgKHJlcykgPT4ge1xuICAgICAgICBjYlJlamVjdCAmJiBjYlJlamVjdChyZXMpO1xuICAgICAgfSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIGEgc2luZ2xlIG1vZGVsIGluc3RhbmNlIG1hdGNoaW5nIHRoZSBjdXJyZW50IHF1ZXJ5LlxuICAgKlxuICAgKiBAcGFyYW0gez9vYmplY3R9IG1vZGVsUXVlcnlcbiAgICogQHBhcmFtIHs/Ym9vbGVhbn0gZG9Ob3RMb2FkIHRydWUgaWYgbW9kZWxRdWVyeSBjb250YWlucyBpZCBvciBwayBhbmQgb2JqZWN0IGRvZXMgbm90IG5lZWQgdG8gYmUgbG9hZGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTZGNNb2RlbD59XG4gICAqL1xuICBhc3luYyBnZXQobW9kZWxRdWVyeSA9IG51bGwsIGRvTm90TG9hZCA9IGZhbHNlKSB7XG4gICAgaWYgKGRvTm90TG9hZCkge1xuICAgICAgY29uc3QgaWQgPSBtb2RlbFF1ZXJ5Py5pZCA/PyBtb2RlbFF1ZXJ5Py5waztcbiAgICAgIHJldHVybiB0aGlzLmJ5SWQoaWQpID8/IHRoaXMubmV3KG1vZGVsUXVlcnkgfHwgdGhpcy5tb2RlbFF1ZXJ5KTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5sb2FkKG1vZGVsUXVlcnkpO1xuICAgIGlmICh0aGlzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtb2RlbCBxdWVyeSByZXR1cm5zICR7dGhpcy5sZW5ndGh9IGJ1dCBvbmx5IDEgZXhwZWN0ZWQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudmFsdWVzTGlzdFswXTtcbiAgfVxuXG4gIGRldGFpbFZpZXcoe3BrLCBjYlJlc29sdmUgPSBudWxsLCBjYlJlamVjdCA9IG51bGwsIHRlbXBsYXRlQ29udGV4dCA9IHt9fSkge1xuICAgIHJldHVybiB0aGlzLl9zZW5kRGV0YWlsVmlldyh7XG4gICAgICBwayxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgdGVtcGxhdGVDb250ZXh0LFxuICAgIH0pO1xuICB9XG5cbiAgbGlzdFZpZXcoe21vZGVsUXVlcnkgPSB7fSwgc2VhcmNoVmFsdWVzID0ge30sIGNiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbCwgdGVtcGxhdGVDb250ZXh0ID0ge319KSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbmRMaXN0Vmlldyh7XG4gICAgICBtb2RlbFF1ZXJ5OiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm1vZGVsUXVlcnksIG1vZGVsUXVlcnksIHsgJ19fc2VhcmNoX3ZhbHVlcyc6IHNlYXJjaFZhbHVlcyB9KSxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgdGVtcGxhdGVDb250ZXh0LFxuICAgIH0pO1xuICB9XG5cbiAgc2F2ZSh7cGsgPSBudWxsLCBmb3JtTmFtZSA9IFwiZWRpdF9mb3JtXCIsIGRhdGEgPSBudWxsfSA9IHt9KSB7XG4gICAgY29uc3Qgbm9ybVBrID0gbm9ybWFsaXplUGsocGspO1xuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICBsZXQgZWxlbUxpc3Q7XG4gICAgICBpZiAobm9ybVBrID4gLTEpIHtcbiAgICAgICAgY29uc3QgZWxlbSA9IHRoaXMuYnlJZChub3JtUGspO1xuICAgICAgICBpZiAoIWVsZW0pIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFNkY01vZGVsRXJyb3IoYEVsZW1lbnQgbm90IGZvdW5kIHdpdGggSUQ6ICR7bm9ybVBrfWApKTtcbiAgICAgICAgfVxuICAgICAgICBlbGVtTGlzdCA9IFtlbGVtXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1MaXN0ID0gdGhpcy52YWx1ZXNMaXN0O1xuICAgICAgfVxuICAgICAgbGV0IHBMaXN0ID0gW107XG4gICAgICBlbGVtTGlzdC5mb3JFYWNoKChlbGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgICAgIHBMaXN0LnB1c2goXG4gICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcmVhZEZpbGVzKGVsZW0pLnRoZW4oKGZpbGVzKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHNlbmREYXRhID0gZGF0YSA/IHsuLi5kYXRhfSA6IGVsZW0uc2VyaWFsaXplKCk7XG4gICAgICAgICAgICAgIHNlbmREYXRhLnBrID0gZWxlbS5pZDtcbiAgICAgICAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJzYXZlXCIsXG4gICAgICAgICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvcm1fbmFtZTogZm9ybU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1vZGVsX25hbWU6IHRoaXMubW9kZWxOYW1lLFxuICAgICAgICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogdGhpcy5tb2RlbFF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgICBkYXRhOiBzZW5kRGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcGs6IHNlbmREYXRhLnBrLFxuICAgICAgICAgICAgICAgICAgICBmaWxlczogZmlsZXMsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAgICAgICAgIChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxldCBkYXRhID1cbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHJlcy5kYXRhLmluc3RhbmNlID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgPyBKU09OLnBhcnNlKHJlcy5kYXRhLmluc3RhbmNlKVxuICAgICAgICAgICAgICAgICAgICAgIDogcmVzLmRhdGEuaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgICByZXMuZGF0YS5pbnN0YW5jZSA9IHRoaXMuX3BhcnNlU2VydmVyUmVzKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVqZWN0LFxuICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHBMaXN0KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gZWxlbSB7P1NkY01vZGVsfVxuICAgKiBAcGFyYW0gZGF0YSB7P29iamVjdH1cbiAgICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59XG4gICAqL1xuICBjcmVhdGUoe2VsZW0gPSBudWxsLCBkYXRhID0gbnVsbH0gPSB7fSkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgaWYgKCFlbGVtKSB7XG4gICAgICBlbGVtID0gdGhpcy5uZXcoZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzQ29ubmVjdGVkKCkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB0aGlzLl9yZWFkRmlsZXMoZWxlbSkudGhlbigoZmlsZXMpID0+IHtcbiAgICAgICAgICB0aGlzLnNvY2tldC5zZW5kKFxuICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICBldmVudF90eXBlOiBcImNyZWF0ZVwiLFxuICAgICAgICAgICAgICBldmVudF9pZDogaWQsXG4gICAgICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgICBtb2RlbF9xdWVyeTogdGhpcy5tb2RlbFF1ZXJ5LFxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgPz8gZWxlbT8uc2VyaWFsaXplKCkgPz8ge30sXG4gICAgICAgICAgICAgICAgZmlsZXM6IGZpbGVzLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbaWRdID0gW1xuICAgICAgICAgICAgKHJlcykgPT4ge1xuICAgICAgICAgICAgICBsZXQgZGF0YSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHJlcy5kYXRhLmluc3RhbmNlID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICA/IEpTT04ucGFyc2UocmVzLmRhdGEuaW5zdGFuY2UpXG4gICAgICAgICAgICAgICAgICA6IHJlcy5kYXRhLmluc3RhbmNlO1xuICAgICAgICAgICAgICBpZiAoZWxlbSkge1xuICAgICAgICAgICAgICAgIGVsZW0uaWQgPSBkYXRhWzBdPy5wayB8fCBkYXRhWzBdPy5pZDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXMuZGF0YS5pbnN0YW5jZSA9IHRoaXMuX3BhcnNlU2VydmVyUmVzKGRhdGEpWzBdO1xuICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVqZWN0LFxuICAgICAgICAgIF07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlIHRoZSB3ZWJzb2NrZXQgaXMgb3BlbiBhbmQgaGFzIGNvbXBsZXRlZCB0aGUgc2VydmVyLXNpZGUgY29ubmVjdFxuICAgKiBoYW5kc2hha2UgYmVmb3JlIGlzc3VpbmcgbW9kZWwgcmVxdWVzdHMuXG4gICAqXG4gICAqIE11bHRpcGxlIGNhbGxlcnMgY2FuIGFycml2ZSB3aGlsZSBhIGNvbm5lY3Rpb24gYXR0ZW1wdCBpcyBhbHJlYWR5IGluXG4gICAqIHByb2dyZXNzLiBJbiB0aGF0IGNhc2UgdGhleSBhcmUgcXVldWVkIGJlaGluZCB0aGUgc2FtZSBzeW50aGV0aWMgcmVxdWVzdCBpZC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2lzQ29ubmVjdGVkKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICF0aGlzLl9pc0Nvbm5lY3RpbmdQcm9jZXNzIHx8XG4gICAgICAgICF0aGlzLm9wZW5SZXF1ZXN0W0NPTk5FQ1RJTkdfUkVRVUVTVF9JRF1cbiAgICAgICkge1xuICAgICAgICB0aGlzLl9pc0Nvbm5lY3RpbmdQcm9jZXNzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtDT05ORUNUSU5HX1JFUVVFU1RfSURdID0gWygpID0+IHtcbiAgICAgICAgfSwgKCkgPT4ge1xuICAgICAgICB9XTtcbiAgICAgICAgdGhpcy5fY29ubmVjdFRvU2VydmVyKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVzb2x2ZSh0aGlzLl9jaGVja0Nvbm5lY3Rpb24oKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgW3Jlc29sdmVPcmlnaW4sIHJlamVjdE9yaWdpbl0gPVxuICAgICAgICAgIHRoaXMub3BlblJlcXVlc3RbQ09OTkVDVElOR19SRVFVRVNUX0lEXTtcbiAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtDT05ORUNUSU5HX1JFUVVFU1RfSURdID0gW1xuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVPcmlnaW4oKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHJlamVjdE9yaWdpbigpO1xuICAgICAgICAgICAgcmVqZWN0KCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgd2Vic29ja2V0IGFuZCBkaXNhYmxlIGF1dG9tYXRpYyByZWNvbm5lY3QgZm9yIHRoaXMgcXVlcnlzZXQuXG4gICAqL1xuICBjbG9zZSgpIHtcbiAgICBpZiAodGhpcy5zb2NrZXQpIHtcbiAgICAgIHRoaXMuX2F1dG9SZWNvbm5lY3QgPSBmYWxzZTtcbiAgICAgIHRoaXMuc29ja2V0Lm9uY2xvc2UgPSAoKSA9PiB7XG4gICAgICB9O1xuICAgICAgdGhpcy5zb2NrZXQuY2xvc2UoKTtcbiAgICAgIGRlbGV0ZSB0aGlzW1wic29ja2V0XCJdO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWVzTGlzdC5mb3JFYWNoKChlbGVtKSA9PiB7XG4gICAgICBlbGVtLl9vbkNsb3NlKClcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGxvYWQgYXR0YWNoZWQgYEZpbGVgIHZhbHVlcyBpbiBmaXhlZC1zaXplIGNodW5rcyBiZWZvcmUgc2F2ZS9jcmVhdGUgY2FsbHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U2RjTW9kZWx9IGVsZW1cbiAgICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0Pn1cbiAgICovXG4gIF9yZWFkRmlsZXMoZWxlbSkge1xuICAgIGxldCB0b1NvbHZlID0gW107XG4gICAgbGV0IGZpbGVzID0ge307XG4gICAgaWYgKCFlbGVtKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZpbGVzKTtcbiAgICB9XG4gICAgT2JqZWN0LmtleXMoZWxlbS5jb25zdHJ1Y3Rvci5maWVsZHMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBlbGVtW2tleV07XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBGaWxlKSB7XG4gICAgICAgIHRvU29sdmUucHVzaChcbiAgICAgICAgICBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHV1aWR2NCgpO1xuICAgICAgICAgICAgdGhpcy5vcGVuUmVxdWVzdFtpZF0gPSBbcmVzb2x2ZSwgcmVqZWN0XTtcblxuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgdmFsdWUuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICAgICAgICAgICAgbGV0IG51bWJlck9mQ2h1bmtzID0gTWF0aC5jZWlsKHJlc3VsdC5sZW5ndGggLyBNQVhfRklMRV9VUExPQUQpO1xuICAgICAgICAgICAgZmlsZXNba2V5XSA9IHtcbiAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICBmaWxlX25hbWU6IHZhbHVlLm5hbWUsXG4gICAgICAgICAgICAgIGZpZWxkX25hbWU6IGtleSxcbiAgICAgICAgICAgICAgY29udGVudF9sZW5ndGg6IHZhbHVlLnNpemUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNodW5rczsgKytpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNodW5rID0gQXJyYXkuZnJvbShyZXN1bHQuc2xpY2UoXG4gICAgICAgICAgICAgICAgTUFYX0ZJTEVfVVBMT0FEICogaSxcbiAgICAgICAgICAgICAgICBNQVhfRklMRV9VUExPQUQgKiAoaSArIDEpLFxuICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgdGhpcy5zb2NrZXQuc2VuZChcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgICAgICAgICAgZXZlbnRfdHlwZTogXCJ1cGxvYWRcIixcbiAgICAgICAgICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICAgICAgICAgIGFyZ3M6IHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmssXG4gICAgICAgICAgICAgICAgICAgIGlkeDogaSxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyX29mX2NodW5rczogbnVtYmVyT2ZDaHVua3MsXG4gICAgICAgICAgICAgICAgICAgIGZpbGVfbmFtZTogdmFsdWUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgZmllbGRfbmFtZToga2V5LFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50X2xlbmd0aDogdmFsdWUuc2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudF90eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICAgICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxfcXVlcnk6IHRoaXMubW9kZWxRdWVyeSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwodG9Tb2x2ZSkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZmlsZXM7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUm91dGUgd2Vic29ja2V0IHJlc3BvbnNlcyB0byB0aGUgbWF0Y2hpbmcgcGVuZGluZyByZXF1ZXN0IGFuZCB1cGRhdGUgbG9jYWxcbiAgICogc3RhdGUgd2hlbiB0aGUgc2VydmVyIHNlbmRzIG1vZGVsIHBheWxvYWRzLlxuICAgKlxuICAgKiBAcGFyYW0ge01lc3NhZ2VFdmVudH0gZVxuICAgKi9cbiAgYXN5bmMgX29uTWVzc2FnZShlKSB7XG4gICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGUuZGF0YSk7XG4gICAgaWYgKGRhdGEuaXNfZXJyb3IpIHtcbiAgICAgIGlmICh0aGlzLm9wZW5SZXF1ZXN0Lmhhc093blByb3BlcnR5KGRhdGEuZXZlbnRfaWQpKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbZGF0YS5ldmVudF9pZF1bMV0obmV3IFNkY01vZGVsRXJyb3IoZGF0YSkpO1xuICAgICAgICB0aGlzLl9jbG9zZU9wZW5SZXF1ZXN0KGRhdGEuZXZlbnRfaWQpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGEubXNnIHx8IGRhdGEuaGVhZGVyKSB7XG4gICAgICAgIHRyaWdnZXIoXCJwdXNoRXJyb3JNc2dcIiwgZGF0YS5oZWFkZXIgfHwgXCJcIiwgZGF0YS5tc2cgfHwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLnR5cGUgPT09IFwiY29ubmVjdFwiKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbQ09OTkVDVElOR19SRVFVRVNUX0lEXVsxXShuZXcgU2RjTW9kZWxFcnJvcihkYXRhKSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoQ09OTkVDVElOR19SRVFVRVNUX0lEKTtcbiAgICAgICAgdGhpcy5fYXV0b1JlY29ubmVjdCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNvY2tldC5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGF0YS5tc2cgfHwgZGF0YS5oZWFkZXIpIHtcbiAgICAgICAgdHJpZ2dlcihcInB1c2hNc2dcIiwgZGF0YS5oZWFkZXIgfHwgXCJcIiwgZGF0YS5tc2cgfHwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkYXRhLnR5cGUgPT09IFwiY29ubmVjdFwiKSB7XG4gICAgICAgIHRoaXMuX2lzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5faXNDb25uZWN0aW5nUHJvY2VzcyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9wZW5SZXF1ZXN0W0NPTk5FQ1RJTkdfUkVRVUVTVF9JRF1bMF0oZGF0YSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoQ09OTkVDVElOR19SRVFVRVNUX0lEKTtcbiAgICAgIH0gZWxzZSBpZiAoW1wibG9hZFwiLCBcIm5hbWVkX3ZpZXdcIiwgXCJkZXRhaWxfdmlld1wiXS5pbmNsdWRlcyhkYXRhLnR5cGUpKSB7XG4gICAgICAgIGNvbnN0IGpzb25SZXMgPSBKU09OLnBhcnNlKGRhdGEuYXJncy5kYXRhKTtcbiAgICAgICAgZGF0YS5hcmdzLmRhdGEgPSBhd2FpdCB0aGlzLl9wYXJzZVNlcnZlclJlcyhqc29uUmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09PSBcIm9uX3VwZGF0ZVwiIHx8IGRhdGEudHlwZSA9PT0gXCJvbl9jcmVhdGVcIikge1xuICAgICAgICBjb25zdCBqc29uUmVzID0gSlNPTi5wYXJzZShkYXRhLmFyZ3MuZGF0YSk7XG5cbiAgICAgICAgbGV0IG9iaiA9IGF3YWl0IHRoaXMuX3BhcnNlU2VydmVyUmVzKGpzb25SZXMpO1xuICAgICAgICBsZXQgY2I7XG5cbiAgICAgICAgaWYgKGRhdGEudHlwZSA9PT0gXCJvbl9jcmVhdGVcIikge1xuICAgICAgICAgIGNiID0gdGhpcy5vbkNyZWF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYiA9IHRoaXMub25VcGRhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjYihvYmopO1xuICAgICAgICBkYXRhLmFyZ3MuZGF0YSA9IG9iajtcbiAgICAgIH1cblxuICAgICAgbGV0IGluc3RhbmNlID0gZGF0YS5kYXRhPy5pbnN0YW5jZTtcbiAgICAgIGlmIChpbnN0YW5jZSkge1xuICAgICAgICBkYXRhLmRhdGEuaW5zdGFuY2UgPSBKU09OLnBhcnNlKGRhdGEuZGF0YS5pbnN0YW5jZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9wZW5SZXF1ZXN0Lmhhc093blByb3BlcnR5KGRhdGEuZXZlbnRfaWQpKSB7XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3RbZGF0YS5ldmVudF9pZF1bMF0oZGF0YSk7XG4gICAgICAgIHRoaXMuX2Nsb3NlT3BlblJlcXVlc3QoZGF0YS5ldmVudF9pZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdhaXQgdW50aWwgYWxsIGluLWZsaWdodCB3ZWJzb2NrZXQgcmVxdWVzdHMgZm9yIHRoaXMgcXVlcnlzZXQgYXJlIHJlc29sdmVkLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIG5vT3BlblJlcXVlc3RzKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMub3BlblJlcXVlc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9vbk5vT3BlblJlcXVlc3RzLnB1c2gocmVzb2x2ZSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGEgY29tcGxldGVkIHJlcXVlc3QgYW5kIHdha2UgYW55IGBub09wZW5SZXF1ZXN0cygpYCB3YWl0ZXJzIHdoZW4gdGhlXG4gICAqIHJlcXVlc3QgbWFwIGJlY29tZXMgZW1wdHkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudElkXG4gICAqL1xuICBfY2xvc2VPcGVuUmVxdWVzdChldmVudElkKSB7XG4gICAgZGVsZXRlIHRoaXMub3BlblJlcXVlc3RbZXZlbnRJZF07XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMub3BlblJlcXVlc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5fb25Ob09wZW5SZXF1ZXN0cy5mb3JFYWNoKCh4KSA9PiB4KCkpO1xuICAgICAgdGhpcy5fb25Ob09wZW5SZXF1ZXN0cyA9IFtdO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFc3RhYmxpc2ggdGhlIHJhdyB3ZWJzb2NrZXQgY29ubmVjdGlvbiBmb3IgdGhpcyBxdWVyeXNldC5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBfY29ubmVjdFRvU2VydmVyKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgbW9kZWxJZGVudGlmaWVyID1cbiAgICAgICAgYCR7dGhpcy5tb2RlbE5hbWV9YCArICh0aGlzLm1vZGVsSWQgPiAwID8gYC8ke3RoaXMubW9kZWxJZH1gIDogXCJcIik7XG4gICAgICBpZiAod2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSBcImh0dHBzOlwiKSB7XG4gICAgICAgIHRoaXMuc29ja2V0ID0gbmV3IFdlYlNvY2tldChcbiAgICAgICAgICBgd3NzOi8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0vc2RjX3dzL21vZGVsLyR7bW9kZWxJZGVudGlmaWVyfWAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQoXG4gICAgICAgICAgYHdzOi8vJHt3aW5kb3cubG9jYXRpb24uaG9zdH0vc2RjX3dzL21vZGVsLyR7bW9kZWxJZGVudGlmaWVyfWAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc29ja2V0Lm9ubWVzc2FnZSA9IHRoaXMuX29uTWVzc2FnZS5iaW5kKHRoaXMpO1xuXG4gICAgICB0aGlzLnNvY2tldC5vbmNsb3NlID0gKGUpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgU0RDIE1vZGVsICgke3RoaXMubW9kZWxOYW1lfSwgJHt0aGlzLm1vZGVsSWR9KSBTb2NrZXQgY2xvc2VkIHVuZXhwZWN0ZWRseWAsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX2lzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3QgW19rZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLm9wZW5SZXF1ZXN0KSkge1xuICAgICAgICAgIHZhbHVlWzFdKGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlblJlcXVlc3QgPSB7fTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5fYXV0b1JlY29ubmVjdCkge1xuICAgICAgICAgICAgdGhpcy5fY29ubmVjdFRvU2VydmVyKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDEwMDApO1xuICAgICAgfTtcblxuICAgICAgdGhpcy5zb2NrZXQub25lcnJvciA9IChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgTW9kZWwgU29ja2V0IGVuY291bnRlcmVkIGVycm9yOiAke2Vycn0gQ2xvc2luZyBzb2NrZXRgKTtcbiAgICAgICAgaWYgKHRoaXMuX2lzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuc29ja2V0LmNsb3NlKCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgdGhpcy5zb2NrZXQub25vcGVuID0gKCkgPT4ge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gdGhlIGFwcGxpY2F0aW9uLWxldmVsIGNvbm5lY3QgaGFuZHNoYWtlIG9uY2UgdGhlIHdlYnNvY2tldCBvcGVucy5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAqL1xuICBfY2hlY2tDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdXVpZHY0KCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuc29ja2V0LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBldmVudDogXCJtb2RlbFwiLFxuICAgICAgICAgIGV2ZW50X3R5cGU6IFwiY29ubmVjdFwiLFxuICAgICAgICAgIGV2ZW50X2lkOiBpZCxcbiAgICAgICAgICBhcmdzOiB7XG4gICAgICAgICAgICBtb2RlbF9uYW1lOiB0aGlzLm1vZGVsTmFtZSxcbiAgICAgICAgICAgIG1vZGVsX3F1ZXJ5OiB0aGlzLm1vZGVsUXVlcnksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICB0aGlzLm9wZW5SZXF1ZXN0W2lkXSA9IFtyZXNvbHZlLCByZWplY3RdO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdGhlIGJhY2tlbmQgbW9kZWwgcGF5bG9hZCBpbnRvIGxvY2FsbHkgdHJhY2tlZCBtb2RlbCBvYmplY3RzLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5PG9iamVjdD59IHJlc3VsdHNcbiAgICovXG4gIF9wYXJzZVNlcnZlclJlcyhyZXN1bHRzKSB7XG4gICAgY29uc3QgbmV3TW9kZWxzID0gW11cbiAgICBmb3IgKGNvbnN0IHggb2YgcmVzdWx0cykge1xuICAgICAgY29uc3QgTW9kZWxDbGFzcyA9IGdldE1vZGVsKHRoaXMubW9kZWxOYW1lKTtcbiAgICAgIGlmKCFNb2RlbENsYXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm1vZGVsTmFtZX0gaXMgbm8gU2RjTW9kZWwuIG15YmUgdGhlIG1vZGVscyBhciBub3QgaW1wb3J0YWQuYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdNb2RlbCA9IG5ldyBNb2RlbENsYXNzKHsnaWQnOiB4LnBrID8/IHguaWQsIC4uLnguZmllbGRzfSk7XG4gICAgICBjb25zdCBjdXJyZW50TW9kZWwgPSB0aGlzLmJ5SWQobmV3TW9kZWwuaWQpO1xuICAgICAgaWYgKGN1cnJlbnRNb2RlbCkge1xuICAgICAgICBjdXJyZW50TW9kZWwuc2V0VmFsdWVzKG5ld01vZGVsKTtcbiAgICAgICAgbmV3TW9kZWxzLnB1c2goY3VycmVudE1vZGVsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudmFsdWVzTGlzdC5wdXNoKG5ld01vZGVsKTtcbiAgICAgICAgbmV3TW9kZWwuX3NldFF1ZXJ5U2V0KHRoaXMsIHRydWUpO1xuICAgICAgICBuZXdNb2RlbHMucHVzaChuZXdNb2RlbCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudmFsdWVzTGlzdC5zb3J0KChhLCBiKSA9PiBhLl9pZCAtIGIuX2lkKTtcbiAgICByZXR1cm4gbmV3TW9kZWxzO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNkY01vZGVsIHtcbiAgc3RhdGljIGZpZWxkcyA9IHt9O1xuXG4gIC8qKlxuICAgKiBCYXNlIG1vZGVsIHdyYXBwZXIgdXNlZCBieSBTREMgbW9kZWwgcmVnaXN0cmF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1vZGVsTmFtZVxuICAgKi9cbiAgY29uc3RydWN0b3IobW9kZWxOYW1lKSB7XG4gICAgdGhpcy5faWQgPSBudWxsO1xuICAgIHRoaXMuX2Zvcm1zID0gW107XG4gICAgdGhpcy5sb2FkZWQgPSBmYWxzZTtcbiAgICB0aGlzLmZvcm1JZCA9IHV1aWR2NCgpO1xuICAgIHRoaXMubW9kZWxOYW1lID0gbW9kZWxOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0P30gbW9kZWxRdWVyeVNldFxuICAgKiBAcGFyYW0ge0Fic3RyYWN0U0RDfSBwYXJlbnRcbiAgICogQHJldHVybnMge1NkY1F1ZXJ5U2V0fVxuICAgKi9cbiAgc3RhdGljIHF1ZXJ5U2V0KG1vZGVsUXVlcnlTZXQgPSBudWxsLCBwYXJlbnQgPSBudWxsKSB7XG4gICAgaWYgKCFwYXJlbnQpIHtcbiAgICAgIHJldHVybiBuZXcgU2RjUXVlcnlTZXQodGhpcy5tb2RlTmFtZSwgbW9kZWxRdWVyeVNldCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcmVudC5xdWVyeVNldCh0aGlzLm1vZGVOYW1lLCBtb2RlbFF1ZXJ5U2V0KTtcbiAgfVxuXG4gIGFkZEZvcm0oJGZvcm0pIHtcbiAgICAvLyBSZW1vdmUgb2xkIGxpc3RlbmVycyBpZiBmb3JtIGFscmVhZHkgc2V0XG4gICAgY29uc3Qgb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5fZm9ybXMucHVzaCgkZm9ybSk7XG5cbiAgICBpZiAoJGZvcm0pIHtcbiAgICAgIC8vIEF0dGFjaCBkZWxlZ2F0ZWQgZXZlbnQgaGFuZGxlciB0byBhbGwgaW5wdXRzXG4gICAgICAkZm9ybS5vbihcbiAgICAgICAgXCJpbnB1dC5mb3JtV2F0Y2hlciBjaGFuZ2UuZm9ybVdhdGNoZXJcIixcbiAgICAgICAgXCJpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYVwiLFxuICAgICAgICBvbkNoYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfb25DaGFuZ2UoZXZlbnQpIHtcbiAgICBjb25zdCB7bmFtZX0gPSBldmVudC50YXJnZXQ7XG4gICAgaWYgKHRoaXMuY29uc3RydWN0b3IuZmllbGRzW25hbWVdKSB7XG4gICAgICB0aGlzW2BzZXQke25hbWV9YF0oZ2V0VmFsdWVGcm9tRmllbGQoZXZlbnQudGFyZ2V0KSk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZUZvcm0oZmllbGROYW1lKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fZm9ybXMuZm9yRWFjaCgoJGZvcm0pID0+IHtcbiAgICAgICRmb3JtLmZpbmQoYFtuYW1lPVwiJHtmaWVsZE5hbWV9XCJdYCkuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNldFZhbHVlSW5GaWVsZCh0aGlzLCBzZWxmW2ZpZWxkTmFtZV0pXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldFZhbHVlcyhkYXRhID0ge30pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXRWYWx1ZXMoKSBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCB0aGUgcXVlcnlzZXQgdGhhdCBvd25zIHRoaXMgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7U2RjUXVlcnlTZXR9IHF1ZXJ5U2V0XG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNMb2FkZWRcbiAgICovXG4gIF9zZXRRdWVyeVNldChxdWVyeVNldCwgaXNMb2FkZWQpIHtcbiAgICB0aGlzLl9xdWVyeVNldCA9IG5ldyBXZWFrUmVmKHF1ZXJ5U2V0KTtcbiAgICB0aGlzLmxvYWRlZCA9IGlzTG9hZGVkO1xuICB9XG5cbiAgc2F2ZSh7Zm9ybU5hbWUgPSBcImVkaXRfZm9ybVwiLCBkYXRhID0gbnVsbH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLnNhdmUoe3BrOiB0aGlzLmlkLCBmb3JtTmFtZSwgZGF0YX0pO1xuICB9XG5cbiAgY3JlYXRlKHtkYXRhID0gbnVsbH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmNyZWF0ZSh7ZWxlbTogdGhpcywgZGF0YX0pO1xuICB9XG5cbiAgZGVsZXRlKCkge1xuICAgIHJldHVybiB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmRlbGV0ZSh7ZWxlbTogdGhpc30pO1xuICB9XG5cbiAgbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcXVlcnlTZXQuZGVyZWYoKS51cGRhdGUoe2l0ZW06IHRoaXN9KTtcbiAgfVxuXG4gIGdldCBpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5faWQ7XG4gIH1cblxuICBzZXQgcGsoZGF0YSkge1xuICAgIHRoaXMuX2lkID0gZGF0YTtcbiAgfVxuXG4gIGdldCBwaygpIHtcbiAgICByZXR1cm4gdGhpcy5faWQ7XG4gIH1cblxuICBjbG9zZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcXVlcnlTZXQuZGVyZWYoKS5jbG9zZSgpO1xuICB9XG5cbiAgX29uQ2xvc2UoKSB7XG4gICAgT2JqZWN0LmtleXModGhpcy5jb25zdHJ1Y3Rvci5maWVsZHMpXG4gICAgICAuZmlsdGVyKCh4KSA9PiB0aGlzW2BfJHt4fWBdIGluc3RhbmNlb2YgU2RjUXVlcnlTZXQpXG4gICAgICAuZm9yRWFjaCgoeCkgPT4gdGhpc1tgXyR7eH1gXS5jbG9zZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0IHRoZSBzZXJ2ZXItcmVuZGVyZWQgZGV0YWlsIHZpZXcgZm9yIHRoaXMgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgZGV0YWlsVmlldyh7Y2JSZXNvbHZlID0gbnVsbCwgY2JSZWplY3QgPSBudWxsLCB0ZW1wbGF0ZUNvbnRleHQgPSB7fX0pIHtcbiAgICByZXR1cm4gdGhpcy5fcXVlcnlTZXQuZGVyZWYoKS5kZXRhaWxWaWV3KHtwazogdGhpcy5pZCwgY2JSZXNvbHZlLCBjYlJlamVjdCwgdGVtcGxhdGVDb250ZXh0fSk7XG4gIH1cblxuICBzZXJpYWxpemUoKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMuY29uc3RydWN0b3IuZmllbGRzKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzW2tleV07XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZGNRdWVyeVNldCkge1xuICAgICAgICBpZiAodmFsLm1hbnlfdG9fbWFueSB8fCB2YWwub25lX3RvX21hbnkpIHtcbiAgICAgICAgICBhY2Nba2V5XSA9IHZhbHVlLmdldElkcygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGFsbElkcyA9IHZhbHVlLmdldElkcygpO1xuICAgICAgICAgIGlmIChhbGxJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYWNjW2tleV0gPSBhbGxJZHNbMF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFjY1trZXldID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh2YWwuaXNfcmVsYXRpb24gJiYgdmFsdWUgaW5zdGFuY2VvZiBTZGNNb2RlbCkge1xuICAgICAgICBhY2Nba2V5XSA9IHZhbHVlLmlkID8/IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjXG4gICAgfSwge30pO1xuICB9XG5cbiAgdG9Kc29uKCkge1xuICAgIGNvbnN0IHJlcyA9IHt9XG4gICAgZm9yIChsZXQga2V5IGluIHRoaXMuY29uc3RydWN0b3IuZmllbGRzKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XTtcblxuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRmlsZSkge1xuICAgICAgICByZXNba2V5XSA9IHZhbHVlLm5hbWU7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgU2RjTW9kZWwpIHtcbiAgICAgICAgcmVzW2tleV0gPSB2YWx1ZS5pZDtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZGNRdWVyeVNldCkge1xuICAgICAgICByZXNba2V5XSA9IHZhbHVlLmdldElkcygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEJhY2t3YXJkcy1jb21wYXRpYmxlIGFsaWFzIGZvciBzeW5jaW5nIHZhbHVlcyBmcm9tIGEgZm9ybSBpbnRvIHRoZSBtb2RlbC5cbiAgICpcbiAgICogQHBhcmFtIHsqfSAkZm9ybXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBzeW5jRm9ybVRvTW9kZWwoJGZvcm1zKSB7XG4gICAgcmV0dXJuIHRoaXMuc3luY0Zvcm0oJGZvcm1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBmb3JtIGNvbGxlY3Rpb24gYXNzb2NpYXRlZCB3aXRoIHRoaXMgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gJGZvcm1zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgX3Jlc29sdmVGb3JtcygkZm9ybXMpIHtcbiAgICBpZiAoISRmb3JtcyB8fCAhJGZvcm1zLmhhc0NsYXNzKHRoaXMuZm9ybUlkKSkge1xuICAgICAgcmV0dXJuICQoYC4ke3RoaXMuZm9ybUlkfWApO1xuICAgIH1cblxuICAgIHJldHVybiAkZm9ybXM7XG4gIH1cblxuICAvKipcbiAgICogQ29weSB0aGUgY3VycmVudCBtb2RlbCBzdGF0ZSBpbnRvIG1hdGNoaW5nIGZvcm0gZmllbGRzLlxuICAgKlxuICAgKiBAcGFyYW0geyp9ICRmb3Jtc1xuICAgKi9cbiAgc3luY01vZGVsVG9Gb3JtKCRmb3Jtcykge1xuICAgICRmb3JtcyA9IHRoaXMuX3Jlc29sdmVGb3JtcygkZm9ybXMpO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgZmllbGRzID0gdGhpcy5jb25zdHJ1Y3Rvci5maWVsZHM7XG4gICAgJGZvcm1zLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGsgPSBub3JtYWxpemVQaygkKHRoaXMpLmRhdGEoXCJtb2RlbF9wa1wiKSk7XG4gICAgICBpZiAoc2VsZi5pZCAhPT0gcGspIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBmb3JtSXRlbSBvZiB0aGlzLmVsZW1lbnRzKSB7XG4gICAgICAgIGxldCBuYW1lID0gZm9ybUl0ZW0ubmFtZTtcbiAgICAgICAgaWYgKG5hbWUgJiYgbmFtZSAhPT0gXCJcIiAmJiAhIWZpZWxkc1tuYW1lXSkge1xuICAgICAgICAgIHNldFZhbHVlSW5GaWVsZChmb3JtSXRlbSwgc2VsZltuYW1lXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcHkgbWF0Y2hpbmcgZm9ybSB2YWx1ZXMgYmFjayBvbnRvIHRoZSBjdXJyZW50IG1vZGVsIGluc3RhbmNlLlxuICAgKlxuICAgKiBIaWRkZW4gaW5wdXRzIGFyZSBwYXJzZWQgdG8gdGhlaXIgb3JpZ2luYWwgcHJpbWl0aXZlIHR5cGUgd2hlbiBwb3NzaWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHsqfSAkZm9ybXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBzeW5jRm9ybSgkZm9ybXMpIHtcbiAgICAkZm9ybXMgPSB0aGlzLl9yZXNvbHZlRm9ybXMoJGZvcm1zKTtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMuY29uc3RydWN0b3IuZmllbGRzO1xuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge31cblxuICAgIGZ1bmN0aW9uIHNldFZhbHVlSW5Gb3JtKG5hbWUsIHZhbHVlKSB7XG4gICAgICBpZiAoISFmaWVsZHNbbmFtZV0pIHtcbiAgICAgICAgc2VsZltuYW1lXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuVmFsdWVbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAkZm9ybXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwayA9IG5vcm1hbGl6ZVBrKCQodGhpcykuZGF0YShcIm1vZGVsX3BrXCIpKTtcbiAgICAgIGlmIChzZWxmLmlkICE9PSBwayAmJiAoc2VsZi5pZCAhPT0gbnVsbCB8fCBwayAhPT0gLTEpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgZm9ybUl0ZW0gb2YgdGhpcy5lbGVtZW50cykge1xuICAgICAgICBzZXRWYWx1ZUluRm9ybShmb3JtSXRlbS5uYW1lLCBnZXRWYWx1ZUZyb21GaWVsZChmb3JtSXRlbSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2VsZjtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgdGhlIGNvcnJlY3Qgc2VydmVyLXNpZGUgZm9ybSBmb3IgdGhpcyBtb2RlbCBzdGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBmb3JtKHtjYlJlc29sdmUgPSBudWxsLCBjYlJlamVjdCA9IG51bGx9ID0ge30pIHtcbiAgICBpZiAodGhpcy5pZCA9PT0gbnVsbCB8fCB0aGlzLmlkID09PSAtMSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUZvcm0oe2NiUmVqZWN0LCBjYlJlc29sdmV9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRGb3JtKHtjYlJlamVjdCwgY2JSZXNvbHZlfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSBjcmVhdGUgZm9ybSBmb3IgYSBuZXcgbW9kZWwgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgX2NyZWF0ZUZvcm0oe2NiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbH0pIHtcbiAgICBsZXQgJGRpdkZvcm0gPSAkKFwiPGRpdj5cIik7XG4gICAgdGhpcy5fcXVlcnlTZXQuZGVyZWYoKS5nZXRGb3JtKHtcbiAgICAgIG1vZGVsT2JqOiB0aGlzLFxuICAgICAgZXZlbnRUeXBlOiBcImNyZWF0ZV9mb3JtXCIsXG4gICAgICBmb3JtTmFtZTogbnVsbCxcbiAgICAgICRkaXZGb3JtLFxuICAgICAgY2JSZXNvbHZlLFxuICAgICAgY2JSZWplY3QsXG4gICAgICBmb3JtSWQ6IHRoaXMuZm9ybUlkLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgZWRpdCBmb3JtIGZvciBhbiBleGlzdGluZyBtb2RlbCBpbnN0YW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBfZWRpdEZvcm0oe2NiUmVzb2x2ZSA9IG51bGwsIGNiUmVqZWN0ID0gbnVsbH0pIHtcbiAgICBsZXQgJGRpdkZvcm0gPSAkKFwiPGRpdj5cIik7XG5cbiAgICB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmdldEZvcm0oe1xuICAgICAgbW9kZWxPYmo6IHRoaXMsXG4gICAgICBldmVudFR5cGU6IFwiZWRpdF9mb3JtXCIsXG4gICAgICBmb3JtTmFtZTogbnVsbCxcbiAgICAgICRkaXZGb3JtLFxuICAgICAgY2JSZXNvbHZlLFxuICAgICAgY2JSZWplY3QsXG4gICAgICBmb3JtSWQ6IHRoaXMuZm9ybUlkLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuICRkaXZGb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciBhIG5hbWVkIHNlcnZlci1zaWRlIGZvcm0gZm9yIHRoaXMgbW9kZWwuXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgbmFtZWRGb3JtKHtmb3JtTmFtZSwgY2JSZXNvbHZlID0gbnVsbCwgY2JSZWplY3QgPSBudWxsfSkge1xuICAgIGxldCAkZGl2Rm9ybSA9ICQoJzxkaXYgIGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCI+Jyk7XG5cbiAgICB0aGlzLl9xdWVyeVNldC5kZXJlZigpLmdldEZvcm0oe1xuICAgICAgbW9kZWxPYmo6IHRoaXMsXG4gICAgICBldmVudFR5cGU6IFwibmFtZWRfZm9ybVwiLFxuICAgICAgZm9ybU5hbWUsXG4gICAgICAkZGl2Rm9ybSxcbiAgICAgIGNiUmVzb2x2ZSxcbiAgICAgIGNiUmVqZWN0LFxuICAgICAgZm9ybUlkOiB0aGlzLmZvcm1JZCxcbiAgICB9KTtcblxuICAgIHJldHVybiAkZGl2Rm9ybTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIGZpZWxkIHZhbHVlIHVzaW5nIHRoZSBzdXBwbGllZCBmaWVsZCBjb25maWcuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICAgKi9cbiAgdmFsaWRhdGUodmFsdWUsIGNvbmZpZykge1xuICAgIGNvbnN0IGVyciA9IHZhbGlkYXRlRmllbGQodmFsdWUsIGNvbmZpZyk7XG4gICAgaWYgKGVycikgdGhyb3cgbmV3IEVycm9yKGVycik7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhIHJhdyBpbnB1dCB2YWx1ZSBpbnRvIHRoZSBzaGFwZSBleHBlY3RlZCBieSB0aGUgZmllbGQgY29uZmlnLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWdcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBwYXJzZVZhbHVlKHZhbHVlLCBjb25maWcpIHtcbiAgICBjb25zdCB7XG4gICAgICB0eXBlXG4gICAgfSA9IGNvbmZpZztcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBcIkNoYXJGaWVsZFwiOlxuICAgICAgY2FzZSBcIlRlZXh0RmllbGRcIjpcbiAgICAgIGNhc2UgXCJVVUlERmllbGRcIjpcbiAgICAgIGNhc2UgXCJFbWFpbEZpZWxkXCI6XG4gICAgICAgIHJldHVybiBgJHt2YWx1ZX1gO1xuXG4gICAgICBjYXNlIFwiSW50ZWdlckZpZWxkXCI6XG4gICAgICBjYXNlIFwiQXV0b0ZpZWxkXCI6XG4gICAgICBjYXNlIFwiQmlnSW50ZWdlckZpZWxkXCI6XG4gICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApO1xuXG4gICAgICBjYXNlIFwiRmxvYXRGaWVsZFwiOlxuICAgICAgY2FzZSBcIkRlY2ltYWxGaWVsZFwiOlxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIG51bWJlclwiO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiQm9vbGVhbkZpZWxkXCI6XG4gICAgICAgIHJldHVybiAhIXZhbHVlO1xuXG4gICAgICBjYXNlIFwiRGF0ZUZpZWxkXCI6XG4gICAgICBjYXNlIFwiRGF0ZVRpbWVGaWVsZFwiOlxuICAgICAgICByZXR1cm4gRGF0ZS5wYXJzZSh2YWx1ZSk7XG5cbiAgICAgIGNhc2UgXCJVUkxGaWVsZFwiOlxuICAgICAgICByZXR1cm4gbmV3IFVSTCh2YWx1ZSk7XG5cbiAgICAgIGNhc2UgXCJGaWxlRmllbGRcIjpcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChGaWxlTG9hZGVkLmlzVmFsaWQodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGaWxlTG9hZGVkKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEZpbGVMb2FkZWQpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZpbGVMb2FkZWQodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBGaWxlICE9PSBcInVuZGVmaW5lZFwiICYmIHZhbHVlIGluc3RhbmNlb2YgRmlsZSkge1xuICAgICAgICAgIGlmIChjb25maWcubWF4X3NpemUgJiYgdmFsdWUuc2l6ZSA+IGNvbmZpZy5tYXhfc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGBGaWxlIHRvbyBsYXJnZSAobWF4ICR7Y29uZmlnLm1heF9zaXplfSBieXRlcylgO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjb25maWcuYWxsb3dlZF90eXBlcyAmJiAhY29uZmlnLmFsbG93ZWRfdHlwZXMuaW5jbHVkZXModmFsdWUudHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBgSW52YWxpZCBmaWxlIHR5cGUgKCR7dmFsdWUudHlwZX0pYDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJKU09ORmllbGRcIjpcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZSBhIGZpZWxkIHZhbHVlIGFnYWluc3QgdGhlIGZpZWxkIG1ldGFkYXRhIHJlY2VpdmVkIGZyb20gdGhlIGJhY2tlbmQuXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZ1xuICogQHJldHVybnMgez9zdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRmllbGQodmFsdWUsIGNvbmZpZykge1xuICBjb25zdCB7XG4gICAgdHlwZSxcbiAgICByZXF1aXJlZCxcbiAgICBtYXhfbGVuZ3RoOiBtYXhMZW5ndGgsXG4gICAgaXNfcmVsYXRpb246IGlzUmVsYXRpb24sXG4gICAgbWFueV90b19tYW55OiBtYW55VG9NYW55LFxuICAgIG9uZV90b19tYW55OiBvbmVUb01hbnksXG4gICAgbWFueV90b19vbmU6IG1hbnlUb09uZSxcbiAgICBvbmVfdG9fb25lOiBvbmVUb09uZSxcbiAgICByZWxhdGVkX21vZGVsOiByZWxhdGVkTW9kZWwsXG4gIH0gPSBjb25maWc7XG5cbiAgdm9pZCBpc1JlbGF0aW9uO1xuXG4gIGlmIChyZXF1aXJlZCkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSBcIlwiKSB7XG4gICAgICByZXR1cm4gXCJUaGlzIGZpZWxkIGlzIHJlcXVpcmVkXCI7XG4gICAgfVxuICB9XG5cbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IFwiXCIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChtYW55VG9NYW55IHx8IG9uZVRvTWFueSB8fCBtYW55VG9PbmUgfHwgb25lVG9PbmUpIHtcbiAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIFNkY1F1ZXJ5U2V0KSB8fCB2YWx1ZS5tb2RlbE5hbWUgIT09IHJlbGF0ZWRNb2RlbCkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiBOdW1iZXIuaXNOYU4ocGFyc2VJbnQodmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gXCJNdXN0IGJlIG9iamVjdCBvciBJRFwiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBcIkNoYXJGaWVsZFwiOlxuICAgIGNhc2UgXCJUZXh0RmllbGRcIjpcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIHN0cmluZ1wiO1xuICAgICAgfVxuICAgICAgaWYgKG1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiBtYXhMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGBNYXggbGVuZ3RoIGlzICR7bWF4TGVuZ3RofWA7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJJbnRlZ2VyRmllbGRcIjpcbiAgICBjYXNlIFwiQXV0b0ZpZWxkXCI6XG4gICAgY2FzZSBcIkJpZ0ludGVnZXJGaWVsZFwiOlxuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gXCJNdXN0IGJlIGFuIGludGVnZXJcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkZsb2F0RmllbGRcIjpcbiAgICBjYXNlIFwiRGVjaW1hbEZpZWxkXCI6XG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHJldHVybiBcIk11c3QgYmUgYSBudW1iZXJcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkJvb2xlYW5GaWVsZFwiOlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIGJvb2xlYW5cIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIkRhdGVGaWVsZFwiOlxuICAgIGNhc2UgXCJEYXRlVGltZUZpZWxkXCI6XG4gICAgICBpZiAoaXNOYU4oRGF0ZS5wYXJzZSh2YWx1ZSkpKSB7XG4gICAgICAgIHJldHVybiBcIk11c3QgYmUgYSB2YWxpZCBkYXRlXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJFbWFpbEZpZWxkXCI6XG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiIHx8ICEvXlteXFxzQF0rQFteXFxzQF0rXFwuW15cXHNAXSskLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gXCJJbnZhbGlkIGVtYWlsXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJVUkxGaWVsZFwiOlxuICAgICAgdHJ5IHtcbiAgICAgICAgbmV3IFVSTCh2YWx1ZSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiSW52YWxpZCBVUkxcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcIlVVSURGaWVsZFwiOlxuICAgICAgaWYgKCEvXlswLTlhLWZdezh9LVswLTlhLWZdezR9LVsxLTVdWzAtOWEtZl17M30tWzg5YWJdWzAtOWEtZl17M30tWzAtOWEtZl17MTJ9JC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIFwiSW52YWxpZCBVVUlEXCI7XG4gICAgICB9XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJKU09ORmllbGRcIjpcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBKU09OIG9iamVjdFwiO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcIkZpbGVGaWVsZFwiOlxuICAgICAgaWYgKCFGaWxlTG9hZGVkLmlzVmFsaWQodmFsdWUpICYmICEodmFsdWUgaW5zdGFuY2VvZiBGaWxlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRmlsZUxvYWRlZCkpIHtcbiAgICAgICAgcmV0dXJuIFwiTXVzdCBiZSBhIHZhbGlkIGZpbGVcIjtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl0sIm5hbWVzIjpbImdldFZhbHVlRnJvbUZpZWxkIiwic2V0VmFsdWVJbkZpZWxkIiwidXVpZHY0IiwiZ2V0TW9kZWwiLCJhcHAiLCJ0cmlnZ2VyIiwiTUFYX0ZJTEVfVVBMT0FEIiwiQ09OTkVDVElOR19SRVFVRVNUX0lEIiwiU2RjTW9kZWxFcnJvciIsIkVycm9yIiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIm1zZyIsImlzX2Vycm9yIiwiaGVhZGVyIiwiaHRtbCIsIkZpbGVMb2FkZWQiLCJuYW1lIiwidXJsIiwiY29udGVudCIsImxvYWQiLCJmb3JjZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiJCIsImdldCIsInRoZW4iLCJjYXRjaCIsInRleHQiLCJpc1ZhbGlkIiwidmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJGaWxlIiwibm9ybWFsaXplUGsiLCJwayIsIm5vcm1hbGl6ZWRQayIsInBhcnNlSW50IiwiTnVtYmVyIiwiaXNOYU4iLCJTZGNRdWVyeVNldCIsIm1vZGVsTmFtZSIsIm1vZGVsUXVlcnkiLCJ2YWx1ZXNMaXN0IiwibG9hZGVkIiwiX29uTm9PcGVuUmVxdWVzdHMiLCJfaXNDb25uZWN0ZWQiLCJfaXNDb25uZWN0aW5nUHJvY2VzcyIsIl9hdXRvUmVjb25uZWN0Iiwic29ja2V0Iiwib3BlblJlcXVlc3QiLCJtb2RlbElkIiwib25VcGRhdGUiLCJvbkNyZWF0ZSIsIlByb3h5IiwidGFyZ2V0IiwicHJvcCIsInNldCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiaWR4IiwibmV4dCIsImxlbmd0aCIsImRvbmUiLCJvbl9jcmVhdGUiLCJoYW5kbGVyIiwib25fdXBkYXRlIiwic2V0SWRzIiwiaWRzIiwic3RydWN0dXJlZENsb25lIiwiZm9yRWFjaCIsIl9zZXRRdWVyeVNldCIsIlNkY01vZGVsIiwibnVtTGlzdCIsIm51bUlkIiwiTmFOIiwiaXNJbnRlZ2VyIiwidGVtcE51bUxpc3QiLCJtYXAiLCJ4Iiwic29tZSIsInNwbGl0IiwibmV3TW9kZWwiLCJuZXciLCJpZCIsImZpbHRlciIsIml0ZW0iLCJpbmNsdWRlcyIsInZhbHVlSWRzIiwiZ2V0SWRzIiwicHVzaCIsImJ5SWQiLCJub3JtYWxpemVkSWQiLCJmaW5kIiwiZWxtIiwic2V0RmlsdGVyIiwiYWRkRmlsdGVyIiwiT2JqZWN0IiwiYXNzaWduIiwidmFsdWVzIiwiX3NlbmRMb2FkIiwidXBkYXRlIiwibG9hZFF1ZXJ5IiwiZGVsZXRlIiwiZWxlbSIsImlzQ29ubmVjdGVkIiwic2VuZCIsIkpTT04iLCJzdHJpbmdpZnkiLCJldmVudCIsImV2ZW50X3R5cGUiLCJldmVudF9pZCIsImFyZ3MiLCJtb2RlbF9uYW1lIiwibW9kZWxfcXVlcnkiLCJkYXRhIiwiX3NlbmRMaXN0VmlldyIsImNiUmVzb2x2ZSIsImNiUmVqZWN0IiwidGVtcGxhdGVDb250ZXh0IiwidmlldyIsImV2ZW50VHlwZSIsInZpZXdOYW1lIiwiJGRpdkxpc3QiLCJ2aWV3X25hbWUiLCJ0ZW1wbGF0ZV9jb250ZXh0IiwiYXBwZW5kIiwicmVmcmVzaCIsInJlcyIsIl9zZW5kRGV0YWlsVmlldyIsImdldEZvcm0iLCJtb2RlbE9iaiIsImZvcm1OYW1lIiwiJGRpdkZvcm0iLCJmb3JtSWQiLCJmb3JtX25hbWUiLCJjbGFzc05hbWUiLCIkZm9ybSIsImNsb3Nlc3QiLCJhZGRDbGFzcyIsImFkZEZvcm0iLCJoYXNBdHRyaWJ1dGUiLCJhdHRyIiwiZG9Ob3RMb2FkIiwiZGV0YWlsVmlldyIsImxpc3RWaWV3Iiwic2VhcmNoVmFsdWVzIiwic2F2ZSIsIm5vcm1QayIsImVsZW1MaXN0IiwicExpc3QiLCJfcmVhZEZpbGVzIiwiZmlsZXMiLCJzZW5kRGF0YSIsInNlcmlhbGl6ZSIsImluc3RhbmNlIiwicGFyc2UiLCJfcGFyc2VTZXJ2ZXJSZXMiLCJhbGwiLCJjcmVhdGUiLCJfY29ubmVjdFRvU2VydmVyIiwiX2NoZWNrQ29ubmVjdGlvbiIsInJlc29sdmVPcmlnaW4iLCJyZWplY3RPcmlnaW4iLCJjbG9zZSIsIm9uY2xvc2UiLCJfb25DbG9zZSIsInRvU29sdmUiLCJrZXlzIiwiZmllbGRzIiwia2V5IiwiYnVmZmVyIiwiYXJyYXlCdWZmZXIiLCJyZXN1bHQiLCJVaW50OEFycmF5IiwibnVtYmVyT2ZDaHVua3MiLCJNYXRoIiwiY2VpbCIsImZpbGVfbmFtZSIsImZpZWxkX25hbWUiLCJjb250ZW50X2xlbmd0aCIsInNpemUiLCJpIiwiY2h1bmsiLCJmcm9tIiwic2xpY2UiLCJudW1iZXJfb2ZfY2h1bmtzIiwiY29udGVudF90eXBlIiwidHlwZSIsIl9vbk1lc3NhZ2UiLCJlIiwiaGFzT3duUHJvcGVydHkiLCJfY2xvc2VPcGVuUmVxdWVzdCIsImpzb25SZXMiLCJvYmoiLCJjYiIsIm5vT3BlblJlcXVlc3RzIiwiZXZlbnRJZCIsIm1vZGVsSWRlbnRpZmllciIsIndpbmRvdyIsImxvY2F0aW9uIiwicHJvdG9jb2wiLCJXZWJTb2NrZXQiLCJob3N0Iiwib25tZXNzYWdlIiwiYmluZCIsImNvbnNvbGUiLCJlcnJvciIsIl9rZXkiLCJlbnRyaWVzIiwic2V0VGltZW91dCIsIm9uZXJyb3IiLCJlcnIiLCJvbm9wZW4iLCJyZXN1bHRzIiwibmV3TW9kZWxzIiwiTW9kZWxDbGFzcyIsImN1cnJlbnRNb2RlbCIsInNldFZhbHVlcyIsInNvcnQiLCJhIiwiYiIsIl9pZCIsIl9mb3JtcyIsInF1ZXJ5U2V0IiwibW9kZWxRdWVyeVNldCIsInBhcmVudCIsIm1vZGVOYW1lIiwib25DaGFuZ2UiLCJfb25DaGFuZ2UiLCJvbiIsIl91cGRhdGVGb3JtIiwiZmllbGROYW1lIiwic2VsZiIsImVhY2giLCJpc0xvYWRlZCIsIl9xdWVyeVNldCIsIldlYWtSZWYiLCJkZXJlZiIsInJlZHVjZSIsImFjYyIsInZhbCIsIm1hbnlfdG9fbWFueSIsIm9uZV90b19tYW55IiwiYWxsSWRzIiwiaXNfcmVsYXRpb24iLCJ0b0pzb24iLCJzeW5jRm9ybVRvTW9kZWwiLCIkZm9ybXMiLCJzeW5jRm9ybSIsIl9yZXNvbHZlRm9ybXMiLCJoYXNDbGFzcyIsInN5bmNNb2RlbFRvRm9ybSIsImZvcm1JdGVtIiwiZWxlbWVudHMiLCJyZXR1cm5WYWx1ZSIsInNldFZhbHVlSW5Gb3JtIiwiZm9ybSIsIl9jcmVhdGVGb3JtIiwiX2VkaXRGb3JtIiwibmFtZWRGb3JtIiwidmFsaWRhdGUiLCJjb25maWciLCJ2YWxpZGF0ZUZpZWxkIiwicGFyc2VWYWx1ZSIsIkRhdGUiLCJVUkwiLCJtYXhfc2l6ZSIsImFsbG93ZWRfdHlwZXMiLCJyZXF1aXJlZCIsIm1heF9sZW5ndGgiLCJtYXhMZW5ndGgiLCJpc1JlbGF0aW9uIiwibWFueVRvTWFueSIsIm9uZVRvTWFueSIsIm1hbnlfdG9fb25lIiwibWFueVRvT25lIiwib25lX3RvX29uZSIsIm9uZVRvT25lIiwicmVsYXRlZF9tb2RlbCIsInJlbGF0ZWRNb2RlbCIsInVuZGVmaW5lZCIsInRlc3QiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/simpleDomControl/sdc_model.js\n\n}");
|
|
78
78
|
|
|
79
79
|
/***/ },
|
|
80
80
|
|
package/dist/ugly.index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={};let t;e.d=(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);const n=/(?<=^|,\s?)[^=\s,]+/g,r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function s(){return new Promise(function(e){e()})}function o(e){return(e=(e=e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)).replace(/[0-9]+/g,e=>`-${e}`)).replace(/^[-]/g,"")}function i(e){return e.replace(/-./g,e=>`${e[1].toUpperCase()}`)}const l=(e,t)=>{let n=t,r=Object.getOwnPropertyNames(e.prototype).concat(Object.getOwnPropertySymbols(e.prototype));for(;""!==n.name;)Object.getOwnPropertyNames(n.prototype).concat(Object.getOwnPropertySymbols(n.prototype)).forEach(t=>{t.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)||r.includes(t)||(r.push(t),Object.defineProperty(e.prototype,t,Object.getOwnPropertyDescriptor(n.prototype,t)))}),n=Object.getPrototypeOf(n)};function a(e,t,n){return $.ajax({url:t,type:n||"POST",xhr:function(){var e=$.ajaxSettings.xhr();return e.upload&&e.upload.addEventListener("progress",c,!1),e},data:e,cache:!1,contentType:!1,processData:!1,beforeSend:function(e,t){(function(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)})(t.type)||this.crossDomain||e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}})}function c(e){if(e.lengthComputable){var t=Math.round(e.loaded/e.total*100),n=$(".progress-container");100===t?n.hide():n.show(),t+="%",n.find(".progress-bar").css({width:t}).text(t)}}function u(e,t=null){return"string"!=typeof e?e:t&&void 0!==t[e]?"function"==typeof t[e]?t[e].bind(t):t[e]:e.match(/^(true|false)$/)?"true"===e:"undefined"!==e?"none"===e.toLowerCase()?null:e.match(/^-?\d+$/)?parseInt(e):e.match(/^-?\d+\.?\d+$/)?parseFloat(e):e.match(/^(['][^']*['])|(["][^"]*["])$/)?e.substr(1,e.length-2):e:void 0}function d(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function h(e){e.find(".has-error").removeClass("has-error").find(".alert-danger").remove(),e.find(".non-field-errors").remove()}function f(e,t){t=$("<div>").append(t),e.find(".has-error").removeClass("has-error").find(".alert-danger").safeRemove(),e.find(".non-field-errors").safeRemove();let n=t.find("input[type=file]").parent();e.find("input[type=file]").parent().each(function(e){$(this).replaceWith(n[e])});let r=0===t.find(".non-field-errors").insertAfter(e.find(".hidden-form-fields")).length;return t.find(".has-error").each(function(){r=!1;let t=$(this),n=t.data("auto-id"),s=e.find(".form-group."+n);s.addClass("has-error"),s.find(".form-input-container").append(t.find(".alert-danger"))}),r}function m(e){let{type:t,name:n}=e;return n&&""!==n?"hidden"===t?(r=$(e).val()).toLowerCase().match(/^(true|false)$/)?"true"===r.toLowerCase():"undefined"!==r?"none"===r.toLowerCase()?null:r.match(/^-?\d+$/)?parseInt(r,10):r.match(/^-?\d+\.?\d+$/)?parseFloat(r):r.match(/^(['][^']*['])|(["][^"]*["])$/)?r.substring(1,r.length-1):r:void 0:"checkbox"===t?e.checked:"file"===t?e.files[0]:$(e).val():null;var r}function p(e,t){let{type:n,name:r}=e;if(r&&""!==r)if("checkbox"===n)e.checked=t;else if("file"===n){if(t instanceof File&&"undefined"!=typeof DataTransfer){let n=new DataTransfer;n.items.add(t),e.files=n}}else t instanceof ue?$(e).val(t.id):t instanceof ce?$(e).val(`[${t.getIds().join(",")}]`):$(e).val(t);return null}function y(e,t=[]){return Object.fromEntries(Object.entries(e).filter(([e,n])=>e!==D&&!t.includes(e)).map(([e,t])=>{if("string"==typeof t&&t.startsWith("SDC_JSON_MODEL=["))try{const{pk:n,fields:r}=JSON.parse(t.slice(16,-1));return[e,{...r,id:n,pk:n}]}catch{}return[e,t]}))}function g(e,t,n=null){let r=function(e,t){let n;e||(e=[]);let r=t.data(),s=y(r,e);n=[];for(let t=0;t<e.length;t++){let s=e[t];r.hasOwnProperty(s)?n.push(r[s]):n.push("undefined")}return n.push(s),n}(e,t);return function(e,t=null){let n=[];for(let r=0;r<e.length;r++){let s=u(e[r],t);n.push(s)}return n}(r,n)}function v(e,t,s){if(!e)return!1;if("function"!=typeof e.onInit)return!1;let o;var i;"function"==typeof e._on_init_params?o=e._on_init_params():o=(i=e.onInit.toString().replace(r,"")).slice(i.indexOf("(")+1,i.indexOf(")")).match(n)||[];let l=g(o,t,s._parentController);if(e.onInit.apply(s,l),s===e)for(let n in e._mixins)v(e._mixins[n],t,s)}const w=["onbeforeunload","onunload"],b=Object.keys(window).filter(e=>/^on/.test(e)&&!w.includes(e)).map(e=>e.slice(2));function R(e,t,n){let r;switch(e){case"mouseleave":case"mouseout":case"mouseenter":case"mousein":return r=document.elementFromPoint(t.clientX,t.clientY),n!==r&&!n.contains(r);default:return!0}}function C(e){let t=e.type;e.hasOwnProperty("namespace")&&e.namespace&&e.namespace.length&&(t+=`.${e.namespace}`);let n=$(e.target),r=null,s=!1,o=!1;for(e.stopImmediatePropagation=()=>o=!0,e.stopPropagation=()=>o=s=!0;n.length;){let i=n.attr(`sdc_${t}`);if(i&&R(t,e,n[0])){if(!r&&(r=G(n),!r))return;for(;r;){if(i.split(" ").forEach(o=>{if(s)return;let i=null;if("function"==typeof o)i=o;else if("function"==typeof r[o])i=r[o];else if("string"==typeof o&&o.startsWith("this.event_")){if(i=r.getEvents()[t],!i)return;if(i=i[o.slice(11)],!i)return}i&&i.call(r,n,e)}),o)return;r=r._parentController}}if(s)return;n=n.parent()}return{res:!0}}function N(e){if(e._isEventsSet)return;const t=e.getEvents();for(let n in t)if(t.hasOwnProperty(n)){let r=t[n];for(let t in r)r.hasOwnProperty(t)&&e.find(t).each(function(){let e=$(this),r=e.attr(`sdc_${n}`)||null;r=r?r.split(" "):[];const s=`this.event_${t}`;-1===r.indexOf(s)&&(r.push(s),e.attr(`sdc_${n}`,r.join(" ")))})}}let O=[],S={};function k(e,t){if(e){let n=i(t._tagName);e._childController[n]||(e._childController[n]=[]),e._childController[n].push(t)}return t._parentController=e}function E(e,t,n,r){let s=[];r=function(e,t){e=(e=e.concat(S[t][1])).filter((e,t,n)=>n.indexOf(e)===t);let n=!0;for(;n;){n=!1;for(let t of e)for(let r of S[t][1])e.includes(r)||(e.push(r),n=!0)}return e}(r,n);for(let e of r)s.push(S[e][0]);let o=new(function(e,...t){let n={[e.name]:class{constructor(...n){let r={};t.forEach(e=>{let t;Object.assign(this,t=new e),t._tagName=e.prototype._tagName,t._isMixin=!0,r[e.name]=t}),Object.assign(this,new e),this._mixins=r}static get name(){return e.name}static className(){return this.name}get mixins(){return this._mixins}}}[e.name];return l(n,e),t.forEach(e=>{l(n,e)}),n}(S[n][0],...s));return o._tagName=n,k(e,o),o.$container=t,function(e,t){v(t,e,t)}(t,o),o}function F(e,t,n,r){if(O.includes(n)){let s=i(n);return window[s]||(window[s]=E(e,t,n,r)),window[s].$container=t,window[s]}return E(e,t,n,r)}function P(e,t){const n=function(e){return function(e){let t={args:{}};return e.contentUrl&&(t=W(e),e.contentUrl=t.url),Promise.all([Q(e,t.args)]).then(function(e){let t=e[0];if(t)try{return $(t)}catch{return $("<div></div>").append(t)}return null})}(e).then(t=>!e.onLoad||e._onLoadDone?t:(e._onLoadDone=!0,(e.onLoad(t)||s()).then(()=>t)))}(e).then(function(t){return function(e,t){return K(e,t).then(function(t){if(t=t||!0,e.willShow){let n=e.willShow();if(n instanceof Promise)return n.then(function(){return t})}return t})}(e,t)}).then(()=>function(e,t){return ee(null,e,t)}(e,t)).catch(function(t){return K(e,t)});return e.load_async?Promise.resolve():n}function x(e){const t=function(e){let t=[];for(;e;)e._isEventsSet=!1,t.unshift(e),e=e._parentController;return t}(e.controller[0]),n=t.concat(e.controller.slice(1));for(let t of n)N(t),t.onRefresh(e.controller[0])}function I(e,t){let n=Boolean(e);return n?e.uuids.has(t._uuid)||(e.uuids.add(t._uuid),e.controller.push(t)):e={uuids:new Set([t._uuid]),controller:[t]},{isRunningProcess:n,refreshProcess:e}}let L={},j={};function q(e,t){return T(e),j.hasOwnProperty(e)?t[j[e]]?void L[e].push(t):console.log("No event handler: "+e,t):console.log("No event: "+e,t)}function T(e,t){t||(t=e),j[e]||(j[e]=t,L[e]=[])}function M(e){for(let t in L)if(L.hasOwnProperty(t))for(let n=L[t].length-1;n>=0;n--)e===L[t][n]&&L[t].splice(n,1)}function A(e){let t=Array.apply(null,arguments);if(e=t.shift(),!L.hasOwnProperty(e)||!j.hasOwnProperty(e))return s();let n=L[e],r=j[e],o=[];for(let e=0;e<n.length;e++){let s=n[e][r].apply(n[e],t);void 0!==s&&o.push(s)}return Promise.all(o)}let U={};const D="_controller_",J="_sdc_controller_";function V(e,t,n){if(!e)return[];let r=e.children(),s=[];return r.each(function(e,r){let o=$(r),i=o.prop("tagName").toLowerCase().split("_");$.inArray(i[0],t)>=0?s.push({tag:i[0],super:i.splice(1)||[],dom:o}):i[0].startsWith("this.")?o.addClass(`_bind_to_update_handler sdc_uuid_${n._uuid}`):s=s.concat(V(o,t,n))}),s}function Q(e,t){const{contentUrl:n,_tagName:r,contentReload:s}=e;return n?U[r]?Promise.resolve(U[r]):(t.VERSION=$e.VERSION,t._method="content",$.get(n,t).then(function(e){return s||(U[r]=e),e}).catch(function(t){throw 301===t.status&&A("_RedirectOnView",t.responseJSON["url-link"]),"function"==typeof e.confirmPageLoaded&&A("navLoaded",{controller_name:()=>t.status}),`<sdc-error data-code="${t.status}">${t.responseText}</sdc-error>`})):Promise.resolve(!1)}function B(e,t,n=null){return t=t||e.data(D),H($e.tagNames,e,t,n)}function W(e){let t=e.contentUrl;if(e&&0===e._urlParams.length){let n,r=/%\(([^)]+)\)\w/gm;for(e._urlParams=[];n=r.exec(t);)e._urlParams.push(n[1]),e.contentReload=!0}let n=function(e,t){return g(e._urlParams,t)}(e,e.$container);return e._urlParams.length&&(t=function(e,t,n){for(let r in e._urlParams)if(e._urlParams.hasOwnProperty(r)){let s=e._urlParams[r],o=RegExp("%\\("+s+"\\)\\w","gm");t=t.replace(o,""+n.shift())}return t}(e,t,n)),e.parsedContentUrl=t,{url:t,args:n[n.length-1]}}function G(e){return e.hasClass(J)?e.data(`${D}`):e.closest(`.${J}`).data(`${D}`)}function z(e,t,n,r,s){let o=e.data(D);return o?B(e,o,s):(o=F(r,e,t,n),e.data(D,o),e.addClass(J),P(o,s))}function K(e,t,n=null){if(t&&t.length>0){e.$container.empty(),e.$container.attr(e._tagName,"");for(let t in e._mixins)e.$container.attr(e._mixins[t]._tagName,"");e.$container.append(t)}return B(e.$container,e,n)}function H(e,t,n,r){return new Promise(s=>{let o=V(t,e,n),i=o.length;if(0===i)return s();for(let e=0;e<o.length;e++)z(o[e].dom,o[e].tag,o[e].super,n,r).then(()=>{if(i--,0===i)return s()})})}function X({$element:e,id:t=[],parent:n=null}){t.push(function(e){if(3===e[0].nodeType)return`TEXT__${e[0].nodeValue}`;const t=[e[0].tagName];return"INPUT"===e[0].nodeName&&[["name",""],["type","text"],["id",""]].forEach(([n,r])=>{const s=e.attr(n)??r;s&&t.push(s)}),t.join("__")}(e));const r={$element:e,id:t.join("::"),depth:t.length,idx:0,getRealParent:()=>n,getIdx:function(){return this.idx=Math.max(0,(this.getRealParent()?.getIdx()??-1)+e.index()+1),this.idx},op:null,parent:n};return r.getIdx.bind(r),[r].concat(e.contents().toArray().map(e=>X({$element:$(e),id:t.slice(),parent:r})).flat())}function Y(e,t){const n=X({$element:t}),r=X({$element:e});n.map((e,t)=>e.idx=t),r.map((e,t)=>e.idx=t);const s=Math.max(...r.concat(n).map(e=>e.depth)),o=Z(n,r,s);let i=[];window.MAIN=t,window.OPS=o,o.forEach((e,t)=>{const{op:n,$element:r,idx:s}=e;if("keep_counterpart"===n.type){if(n.counterpart.getIdx()!==s){const t=e.getBefore();t?n.counterpart.$element.insertAfter(t.$element):e.getRealParent().$element.prepend(n.counterpart.$element)}!function(e,t){const n=e[0].attributes??[],r=t[0].attributes??[];[...n].forEach(n=>{t.is(`[${n.name}]`)||e.removeAttr(n.name)}),[...r].forEach(t=>{t.name.startsWith("data")||e.attr(t.name)===t.value||e.attr(t.name,t.value)}),e.removeData(),Object.entries(t.data()).forEach(([t,n])=>{e.data(t,n)})}(n.counterpart.$element,r),r.hasClass(J)&&(r.data(D).$container=n.counterpart.$element,r.data(D,null)),i.push(r)}else if("delete"===n.type)r.safeRemove();else if("insert"===n.type){const{after:t,target:n}=e.op;t?r.insertAfter(t.$element):n&&n.$element.prepend(r)}}),i.forEach(e=>e.safeRemove())}function Z(e,t,n){return t.filter(e=>e.depth===n&&!e.op).forEach(t=>{const n=e.find(e=>!e.op&&e.id===t.id);if(n){const e=(t,n)=>{t.op={type:"keep",idx:n.idx},n.op={type:"keep_counterpart",counterpart:t},t=t.parent,n=n.parent,!t||t.op||n?.op||e(t,n)};e(n,t)}}),n>1?Z(e,t,n-1):(e.forEach((t,n)=>{if(!t.op){const r=(e[n-1]?.op.idx??-1)+1;t.op={type:"delete",idx:r}}}),t.forEach((e,n)=>{if(e.getBefore=()=>function(e,n){const r=e.depth;for(;n>=1&&e.depth>=r;)if((e=t[n-=1]).depth===r)return"keep_counterpart"===e.op.type?e.op.counterpart:e;return null}(e,n),e.getRealParent=()=>{return(t=e).parent?"keep_counterpart"===t.parent.op.type?t.parent.op.counterpart:t.parent:null;var t},!e.op){const t=e.getRealParent(),n="insert"===t?.op.type?"insert_ignore":"insert";e.op={type:n,target:t,after:e.getBefore()}}}),[...e,...t].sort((e,t)=>(e.op?.idx??e.idx)-(t.op?.idx??t.idx)))}function ee(e,t,n=null){if(t||(t=G(e)),!t)return Promise.resolve();const{refreshProcess:r,isRunningProcess:s}=I(n,t);return e??=t.$container,H($e.tagNames,e,t,n).then(()=>function(e,t,n){return function(e,t,n){const r=[];return t.find(`._bind_to_update_handler.sdc_uuid_${e._uuid}`).each(function(){const t=$(this);let s;if(t.hasClass("_with_handler"))s=t.data("handler");else{let t=this.tagName.toLowerCase().replace(/^this./,"");e[t]&&(s=e[t])}if("function"==typeof s){const n=y(t.data());s=s.bind(e)(n)}s&&r.push(Promise.resolve(s).then(r=>{let s=$("<div></div>");return s.append(r),""===t.html()&&t.append("<div></div>"),$e.reconcile(e,s,t.children(),n)}))}),Promise.all(r)}(e,t??e.$container,n)}(t,e,r).then(()=>{s||x(r)}))}const te={};function ne(e,t){te[e]=t}function re(e){return te[e]}const se=25e3,oe="_connecting_process";class ie extends Error{constructor(e){"string"==typeof e&&(e={msg:e,is_error:!0,header:"Error"}),super(e.msg),this.msg=e.msg,this.header=e.header,this.is_error=e.is_error,this.html=e.html}}class le{constructor({name:e,url:t}){this.name=e,this.url=t,this.content=null}async load(e=!1){return!e&&this.content||(this.content=await new Promise((e,t)=>{$.get(this.url).then(e).catch(()=>{e("")})})),this.content}async text(){return this.load()}static isValid(e){return!(null===e||"object"!=typeof e||Array.isArray(e)||e instanceof File||"string"!=typeof e.url||"string"!=typeof e.name)}}function ae(e){const t=parseInt(e??-1,10);return Number.isNaN(t)?-1:t}class ce{constructor(e,t={}){return this.valuesList=[],this.loaded=!1,this.modelName=e,this.modelQuery=t??{},this._onNoOpenRequests=[],this._isConnected=!1,this._isConnectingProcess=!1,this._autoReconnect=!0,this.socket=null,this.openRequest={},this.modelId=0,this.onUpdate=()=>{},this.onCreate=()=>{},new Proxy(this,{get:(e,t)=>"symbol"==typeof t||isNaN(t)?e[t]:e.valuesList[t],set:(e,t,n)=>isNaN(t)?(e[t]=n,!0):(e.valuesList[t]=n,!0)})}[Symbol.iterator](){let e=-1;return{next:()=>(++e,e<this.valuesList.length?{value:this.valuesList[e],done:!1}:{value:null,done:!0})}}set on_create(e){this.onCreate=e}set on_update(e){this.onUpdate=e}setIds(e){if(null===e||Array.isArray(e)&&0===e.length)return this.valuesList=[],this.valuesList;if(e instanceof ce)return this.valuesList=structuredClone(e.valuesList),this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;if(e instanceof ue)return this.valuesList=[structuredClone(e)],this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;let t,n=Number.NaN;if(Number.isInteger(e))n=e;else if(e instanceof Array){const n=e.map(e=>parseInt(e));n.some(Number.isNaN)||(t=n)}else if(e instanceof String){const r=e.split(",").map(e=>parseInt(e));r.some(Number.isNaN)?n=parseInt(e):t=r}if(Number.isNaN(n)){if(t){this.valuesList=this.valuesList.filter(e=>t.includes(e.id));const e=this.getIds();t.filter(t=>!e.includes(t)).forEach(e=>{this.valuesList.push(new(re(this.modelName))({id:e}))})}}else this.new().id=n;return this.valuesList}getIds(){return this.valuesList.map(e=>e.id)}get length(){return this.valuesList.length}byId(e){if(null!==e){const t=ae(e);return this.valuesList.find(e=>e.id===t)??null}return null}setFilter(e){return this.modelQuery=e,this}addFilter(e){return this.modelQuery=Object.assign({},this.modelQuery,e),this}new(e={}){const t=new(re(this.modelName))(e);return t._setQuerySet(this,!1),this.valuesList.push(t),t}load(e=null){return this.valuesList=[],this.modelQuery=e??this.modelQuery,this._sendLoad()}update({modelQuery:e=null,item:t=null}){this.modelQuery=e??this.modelQuery;let n=t?{pk:t.id}:this.modelQuery;return this._sendLoad(n)}delete({pk:e=null,elem:t=null}){if(null===(e=t?t.id:e))throw new Error("pk or elem must be set");const n=d();return this.isConnected().then(()=>new Promise((t,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"delete",event_id:n,args:{model_name:this.modelName,model_query:this.modelQuery,pk:e}})),this.openRequest[n]=[t,r]}))}_sendLoad(e=null){return this.isConnected().then(()=>{const t=d();return new Promise((n,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"load",event_id:t,args:{model_name:this.modelName,model_query:e??this.modelQuery}})),this.openRequest[t]=[e=>{this.loaded=!0,n(e)},r]})})}_sendListView({modelQuery:e={},cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this.view({modelQuery:e,cbResolve:t,cbReject:n,templateContext:r,eventType:"list_view"})}view({viewName:e="html_list_template",modelQuery:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={},eventType:o="named_view"}){let i=$('<div class="container-fluid">');return this.isConnected().then(()=>{const l=d();this.socket.send(JSON.stringify({event:"model",event_type:o,event_id:l,args:{view_name:e,model_name:this.modelName,model_query:t,template_context:s}})),this.openRequest[l]=[e=>{i.append(e.html),$e.refresh(i),n&&n(e)},e=>{r&&r(e)}]}),i}_sendDetailView({pk:e=null,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){e=ae(e);let s=$('<div class="container-fluid">');return this.isConnected().then(()=>{const o=d();this.socket.send(JSON.stringify({event:"model",event_type:"detail_view",event_id:o,args:{model_name:this.modelName,model_query:this.modelQuery,pk:e,template_context:r}})),this.openRequest[o]=[e=>{s.append(e.html),$e.refresh(s),t&&t(e)},e=>{n&&n(e)}]}),s}getForm({modelObj:e,eventType:t,formName:n,$divForm:r,cbResolve:s,cbReject:o,formId:i}){const l=d(),a=e.id??-1;this.isConnected().then(()=>{this.socket.send(JSON.stringify({event:"model",event_type:t,event_id:l,args:{model_name:this.modelName,pk:a,form_name:n}}))});const c=null===a||-1===a?"create":"edit";this.openRequest[l]=[t=>{r.append(t.html);let o=r.closest("form").addClass(`sdc-model-${c}-form sdc-model-form ${i}`).data("model",e).data("model_pk",a).data("form_name",n);e.addForm(o),o.length>0&&!o[0].hasAttribute("sdc_submit")&&o.attr("sdc_submit","submitModelFormDistributor"),$e.refresh(r).then(()=>null),s&&s(t)},e=>{o&&o(e)}]}async get(e=null,t=!1){if(t){const t=e?.id??e?.pk;return this.byId(t)??this.new(e||this.modelQuery)}if(await this.load(e),1!==this.length)throw new Error(`model query returns ${this.length} but only 1 expected.`);return this.valuesList[0]}detailView({pk:e,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this._sendDetailView({pk:e,cbResolve:t,cbReject:n,templateContext:r})}listView({modelQuery:e={},searchValues:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={}}){return this._sendListView({modelQuery:Object.assign({},this.modelQuery,e,{__search_values:t}),cbResolve:n,cbReject:r,templateContext:s})}save({pk:e=null,formName:t="edit_form",data:n=null}={}){const r=ae(e);return this.isConnected().then(()=>{let e;if(r>-1){const t=this.byId(r);if(!t)return Promise.reject(new ie(`Element not found with ID: ${r}`));e=[t]}else e=this.valuesList;let s=[];return e.forEach(e=>{const r=d();s.push(new Promise((s,o)=>{this._readFiles(e).then(i=>{const l=n?{...n}:e.serialize();l.pk=e.id,this.socket.send(JSON.stringify({event:"model",event_type:"save",event_id:r,args:{form_name:t,model_name:this.modelName,model_query:this.modelQuery,data:l,pk:l.pk,files:i}})),this.openRequest[r]=[e=>{let t="string"==typeof e.data.instance?JSON.parse(e.data.instance):e.data.instance;e.data.instance=this._parseServerRes(t),s(e)},o]})}))}),Promise.all(s)})}create({elem:e=null,data:t=null}={}){const n=d();return e||(e=this.new(t)),this.isConnected().then(()=>new Promise((r,s)=>{this._readFiles(e).then(o=>{this.socket.send(JSON.stringify({event:"model",event_type:"create",event_id:n,args:{model_name:this.modelName,model_query:this.modelQuery,data:t??e?.serialize()??{},files:o}})),this.openRequest[n]=[t=>{let n="string"==typeof t.data.instance?JSON.parse(t.data.instance):t.data.instance;e&&(e.id=n[0]?.pk||n[0]?.id),t.data.instance=this._parseServerRes(n)[0],r(t)},s]})}))}isConnected(){return new Promise((e,t)=>{if(this._isConnected)e();else if(this._isConnectingProcess&&this.openRequest[oe]){const[n,r]=this.openRequest[oe];this.openRequest[oe]=[()=>{n(),e()},()=>{r(),t()}]}else this._isConnectingProcess=!0,this.openRequest[oe]=[()=>{},()=>{}],this._connectToServer().then(()=>{e(this._checkConnection())})})}close(){this.socket&&(this._autoReconnect=!1,this.socket.onclose=()=>{},this.socket.close(),delete this.socket),this.valuesList.forEach(e=>{e._onClose()})}_readFiles(e){let t=[],n={};return e?(Object.keys(e.constructor.fields).forEach(r=>{const s=e[r];s instanceof File&&t.push(new Promise(async(e,t)=>{const o=d();this.openRequest[o]=[e,t];const i=await s.arrayBuffer();let l=new Uint8Array(i),a=Math.ceil(l.length/se);n[r]={id:o,file_name:s.name,field_name:r,content_length:s.size};for(let e=0;e<a;++e){const t=Array.from(l.slice(se*e,se*(e+1)));this.socket.send(JSON.stringify({event:"model",event_type:"upload",event_id:o,args:{chunk:t,idx:e,number_of_chunks:a,file_name:s.name,field_name:r,content_length:s.size,content_type:s.type,model_name:this.modelName,model_query:this.modelQuery}}))}}))}),Promise.all(t).then(()=>n)):Promise.resolve(n)}async _onMessage(e){let t=JSON.parse(e.data);if(t.is_error)this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][1](new ie(t)),this._closeOpenRequest(t.event_id)),(t.msg||t.header)&&A("pushErrorMsg",t.header||"",t.msg||""),"connect"===t.type&&(this.openRequest[oe][1](new ie(t)),this._closeOpenRequest(oe),this._autoReconnect=!1,this.socket.close());else{if((t.msg||t.header)&&A("pushMsg",t.header||"",t.msg||""),"connect"===t.type)this._isConnected=!0,this._isConnectingProcess=!1,this.openRequest[oe][0](t),this._closeOpenRequest(oe);else if(["load","named_view","detail_view"].includes(t.type)){const e=JSON.parse(t.args.data);t.args.data=await this._parseServerRes(e)}else if("on_update"===t.type||"on_create"===t.type){const e=JSON.parse(t.args.data);let n,r=await this._parseServerRes(e);n="on_create"===t.type?this.onCreate:this.onUpdate,n(r),t.args.data=r}let e=t.data?.instance;e&&(t.data.instance=JSON.parse(t.data.instance)),this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][0](t),this._closeOpenRequest(t.event_id))}}noOpenRequests(){return new Promise(e=>{if(0===Object.keys(this.openRequest).length)return e();this._onNoOpenRequests.push(e)})}_closeOpenRequest(e){delete this.openRequest[e],0===Object.keys(this.openRequest).length&&(this._onNoOpenRequests.forEach(e=>e()),this._onNoOpenRequests=[])}_connectToServer(){return new Promise(e=>{const t=`${this.modelName}`+(this.modelId>0?`/${this.modelId}`:"");"https:"===window.location.protocol?this.socket=new WebSocket(`wss://${window.location.host}/sdc_ws/model/${t}`):this.socket=new WebSocket(`ws://${window.location.host}/sdc_ws/model/${t}`),this.socket.onmessage=this._onMessage.bind(this),this.socket.onclose=e=>{console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`),this._isConnected=!1;for(const[t,n]of Object.entries(this.openRequest))n[1](e);this.openRequest={},setTimeout(()=>{this._autoReconnect&&this._connectToServer().then(()=>{})},1e3)},this.socket.onerror=e=>{if(console.error(`Model Socket encountered error: ${e} Closing socket`),this._isConnected)try{this.socket.close()}catch(e){}},this.socket.onopen=()=>{e()}})}_checkConnection(){const e=d();return new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"connect",event_id:e,args:{model_name:this.modelName,model_query:this.modelQuery}})),this.openRequest[e]=[t,n]})}_parseServerRes(e){const t=[];for(const n of e){const e=new(re(this.modelName))({id:n.pk??n.id,...n.fields}),r=this.byId(e.id);r?(r.setValues(e),t.push(r)):(this.valuesList.push(e),e._setQuerySet(this,!0),t.push(e))}return this.valuesList.sort((e,t)=>e._id-t._id),t}}class ue{static fields={};constructor(e){this._id=null,this._forms=[],this.loaded=!1,this.formId=d(),this.modelName=e}static querySet(e=null,t=null){return t?t.querySet(this.modeName,e):new ce(this.modeName,e)}addForm(e){const t=this._onChange.bind(this);this._forms.push(e),e&&e.on("input.formWatcher change.formWatcher","input, select, textarea",t)}_onChange(e){const{name:t}=e.target;this.constructor.fields[t]&&this[`set${t}`](m(e.target))}_updateForm(e){const t=this;this._forms.forEach(n=>{n.find(`[name="${e}"]`).each(function(){p(this,t[e])})})}setValues(e={}){throw new Error("setValues() must be implemented by subclass")}_setQuerySet(e,t){this._querySet=new WeakRef(e),this.loaded=t}save({formName:e="edit_form",data:t=null}={}){return this._querySet.deref().save({pk:this.id,formName:e,data:t})}create({data:e=null}={}){return this._querySet.deref().create({elem:this,data:e})}delete(){return this._querySet.deref().delete({elem:this})}load(){return this._querySet.deref().update({item:this})}get id(){return this._id}set pk(e){this._id=e}get pk(){return this._id}close(){return this._querySet.deref().close()}_onClose(){Object.keys(this.constructor.fields).filter(e=>this[`_${e}`]instanceof ce).forEach(e=>this[`_${e}`].close())}detailView({cbResolve:e=null,cbReject:t=null,templateContext:n={}}){return this._querySet.deref().detailView({pk:this.id,cbResolve:e,cbReject:t,templateContext:n})}serialize(){return Object.entries(this.constructor.fields).reduce((e,[t,n])=>{const r=this[t];if(r instanceof ce)if(n.many_to_many||n.one_to_many)e[t]=r.getIds();else{const n=r.getIds();n.length>0?e[t]=n[0]:e[t]=null}else n.is_relation&&r instanceof ue?e[t]=r.id??null:e[t]=r;return e},{})}toJson(){const e={};for(let t in this.constructor.fields){const n=this[t];n instanceof File?e[t]=n.name:e[t]=n instanceof ue?n.id:n instanceof ce?n.getIds():n}return e}syncFormToModel(e){return this.syncForm(e)}_resolveForms(e){return e&&e.hasClass(this.formId)?e:$(`.${this.formId}`)}syncModelToForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields;e.each(function(){const e=ae($(this).data("model_pk"));if(t.id===e)for(let e of this.elements){let r=e.name;r&&""!==r&&n[r]&&p(e,t[r])}})}syncForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields,r={};function s(e,s){n[e]&&(t[e]=s),r[e]=s}return e.each(function(){const e=ae($(this).data("model_pk"));if(t.id===e||null===t.id&&-1===e){for(let e of this.elements)s(e.name,m(e));return t}}),r}form({cbResolve:e=null,cbReject:t=null}){return null===this.id||-1===this.id?this._createForm({cbReject:t,cbResolve:e}):this._editForm({cbReject:t,cbResolve:e})}_createForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"create_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}_editForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"edit_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}namedForm({formName:e,cbResolve:t=null,cbReject:n=null}){let r=$('<div class="container-fluid">');return this._querySet.deref().getForm({modelObj:this,eventType:"named_form",formName:e,$divForm:r,cbResolve:t,cbReject:n,formId:this.formId}),r}validate(e,t){const n=function(e,t){const{type:n,required:r,max_length:s,is_relation:o,many_to_many:i,one_to_many:l,many_to_one:a,one_to_one:c,related_model:u}=t;if(r&&(null==e||""===e))return"This field is required";if(null==e)return null;if((i||l||a||c)&&(!(e instanceof ce)||e.modelName!==u))return"object"!=typeof e&&Number.isNaN(parseInt(e))?"Must be object or ID":null;switch(n){case"CharField":case"TextField":if("string"!=typeof e)return"Must be a string";if(s&&e.length>s)return`Max length is ${s}`;break;case"IntegerField":case"AutoField":case"BigIntegerField":if(!Number.isInteger(e))return"Must be an integer";break;case"FloatField":case"DecimalField":if("number"!=typeof e)return"Must be a number";break;case"BooleanField":if("boolean"!=typeof e)return"Must be a boolean";break;case"DateField":case"DateTimeField":if(isNaN(Date.parse(e)))return"Must be a valid date";break;case"EmailField":if("string"!=typeof e||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))return"Invalid email";break;case"URLField":try{new URL(e)}catch{return"Invalid URL"}break;case"UUIDField":if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(e))return"Invalid UUID";break;case"JSONField":if("object"!=typeof e)return"Must be JSON object";break;case"FileField":if(!(le.isValid(e)||e instanceof File||e instanceof le))return"Must be a valid file"}return null}(e,t);if(n)throw new Error(n)}parseValue(e,t){const{type:n}=t;switch(n){case"CharField":case"TeextField":case"UUIDField":case"EmailField":return`${e}`;case"IntegerField":case"AutoField":case"BigIntegerField":return parseInt(e,10);case"FloatField":case"DecimalField":if("number"!=typeof e)return"Must be a number";break;case"BooleanField":return!!e;case"DateField":case"DateTimeField":return Date.parse(e);case"URLField":return new URL(e);case"FileField":if(null==e)return null;if("string"==typeof e)return null;if(le.isValid(e))return new le(e);if(e instanceof le)return new le(e);if("undefined"!=typeof File&&e instanceof File)return t.max_size&&e.size>t.max_size?`File too large (max ${t.max_size} bytes)`:t.allowed_types&&!t.allowed_types.includes(e.type)?`Invalid file type (${e.type})`:e;break;case"JSONField":if("object"==typeof e)return e;if("string"==typeof e)return JSON.parse(e)}return e}}let de=!1,he=!1,fe=null,me={};function pe(){return window.SERVER_CALL_VIA_WEB_SOCKET?new Promise(e=>de?e():he?void setTimeout(()=>{pe().then(()=>{e()})},200):e(ye())):Promise.resolve(!0)}function _e(){window.SERVER_CALL_VIA_WEB_SOCKET&&function(){if(de){de=!1;try{fe.close()}catch(e){}}}()}function ye(){return he=!0,new Promise(e=>{fe="https:"===window.location.protocol?new WebSocket(`wss://${window.location.host}/sdc_ws/ws/`):new WebSocket(`ws://${window.location.host}/sdc_ws/ws/`),fe.onmessage=function(e){ge(JSON.parse(e.data))},fe.onclose=function(){de&&console.error("SDC Socket closed unexpectedly"),de=!1;for(const[e,t]of Object.entries(me))t[1]({}),delete me[e];setTimeout(()=>{ye()},1e3)},fe.onerror=function(e){if(console.error("Socket encountered error: ",e.message,"Closing socket"),de)try{fe.close()}catch(e){}},fe.onopen=function(){de=!0,he=!1,e()}})}function ge(e){if(e||(e={}),e.is_error)(e.msg||e.header)&&A("pushErrorMsg",e.header||"",e.msg||""),e.id&&me[e.id]&&(me[e.id][1](e.data||null),delete me[e.id]);else if((e.msg||e.header)&&A("pushMsg",e.header||"",e.msg||""),e.type&&"sdc_recall"===e.type)e.id&&me[e.id]&&(me[e.id][0](e.data),delete me[e.id]);else if(e.type&&"sdc_event"===e.type){let t=e.event;t&&A(t,e.payload)}else e.type&&"sdc_redirect"===e.type&&A("onNavLink",e.link)}class ve{constructor(){this._uuid=d(),this.contentUrl="",this.contentReload=!1,this.parsedContentUrl=null,this.events=[],this.load_async=!1,this._isEventsSet=!1,this._allEvents=null,this._urlParams=[],this._models=[],this._cssUrls=[],this.afterShow=()=>{console.warn("afterShow is deprecated!!")},this._mixins={},this._tagName=Object.getPrototypeOf(this)._tagName??"",this._childController={},this._parentController=null,this._onLoadDone=!1,this.$container=null,this._isMixin=!1}_runLifecycle(e,t){$e.DEBUG&&!this._isMixin&&console.debug(e,this._tagName);let n=[];if(!this._isMixin){this._isMixin=!0;for(let r in this._mixins){let s=this._mixins[r];"function"==typeof s[e]&&n.push(s[e].apply(this,t))}return Promise.all(n).then(()=>{this._isMixin=!1})}}onInit(){$e.DEBUG&&!this._isMixin&&console.debug(Array.apply(null,arguments),this._tagName)}get parentController(){return this._parentController}get childController(){return this._childController}onLoad(){return this._runLifecycle("onLoad",arguments)}willShow(){return this._runLifecycle("willShow",arguments)}onRefresh(){return this._runLifecycle("onRefresh",arguments)}onRemove(){return this._runLifecycle("onRemove",arguments),!0}noOpenModelRequests(){return Promise.all(this._models.map(e=>e.noOpenRequests()))}remove(){for(const e of this._models)e.close();let e=this._childController;for(let t in e)if(e.hasOwnProperty(t))for(let n of e[t])if(!n.remove())return!1;if(!this.onRemove||this.onRemove()){M(this);const e=i(this._tagName);if(this._parentController._childController[e]){let t=this._parentController._childController[e];for(let e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)}return this.$container.remove(),!0}return!1}controller_name(){return this._tagName.replace(/-./g,e=>` ${e[1].toUpperCase()}`).replace(/^./g,e=>`${e.toUpperCase()}`)}addEvent(e,t,n){this.getEvents(),this._allEvents[e]=this._allEvents[e]||{},this._allEvents[e][t]=n}getEvents(){if(this._allEvents)return this._allEvents;let e=[];e=e.concat(this.events);for(let t in this._mixins){let n=this._mixins[t];Array.isArray(n.events)&&(e=e.concat(n.events))}return this._allEvents=_.merge(...e)}post(e,t){return $e.post(this,e,t)}get(e,t){return $e.get(this,e,t)}submitForm(e,t,n){return $e.submitFormAndUpdateView(this,e,t,n)}serverCall(e,t){let n=this.contentUrl.match(/sdc_view\/([^/]+)/i);if(n&&!(n.length<2))return function(e,t,n,r,s){return window.SERVER_CALL_VIA_WEB_SOCKET?function(e,t,n,r){let s=d();return pe().then(()=>{fe.send(JSON.stringify({event:"sdc_call",id:s,controller:t,app:e,function:n,args:r}))}),new Promise((e,t)=>{me[s]=[e,t]})}(e,t,r,s):function(e,t,n){return"object"!=typeof n&&Array.isArray(n)&&null===n&&(n={arg0:n}),n={data:JSON.stringify(n),_sdc_func_name:t,_method:"sdc_server_call"},$.post({url:e,data:n,beforeSend:function(e,t){e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}}).then(e=>{const t=e._return_data;return ge(t),t}).catch(e=>{const t=e.responseJSON;throw t.is_error=!0,ge(t),e})}(n,r,s)}(n[1],this._tagName,this.parsedContentUrl??this.contentUrl,e,t);console.error("To use the serverCall function the contentUrl must be set: "+this.name)}querySet(e,t={}){const n=new ce(e,t);return this._models.push(n),n}newModel(e,t={}){return console.warn("newModel is deprecated and will soon be removed"),this.querySet(e,t)}find(e){return this.$container.find(e)}refresh(){return $e.refresh(this.$container,this)}reload(){return $e.reloadController(this)}reconcile(e,t=null){return $e.reconcile(this,e,t)}submitModelFormDistributor(e,t){return"function"==typeof this._submitModelForm?this._submitModelForm(e,t):"function"==typeof this.submitModelForm?this.submitModelForm(e,t):this.defaultSubmitModelForm(e,t)}iterateAllChildren(){let e=this._childController,t=[];for(let n in e)if(e.hasOwnProperty(n))for(let r of e[n])t.push(r),t.push(...r.iterateAllChildren());return t}defaultSubmitModelForm(e,t){if(!this._isMixin){t.stopPropagation(),t.preventDefault();let{model:n,form_name:r}=e.data(),s=n.syncForm(e);return new Promise((t,o)=>{let i;i=null!==n.id&&n.id>=0?n.save({formName:r,data:s}):n.create({data:s}),i.then(n=>{h(e),this.submit_model_form_success&&this.submit_model_form_success(n[0]);for(const e of this.iterateAllChildren())e.submit_model_form_success&&e.submit_model_form_success(n[0]);t(n)}).catch(t=>{this.reconcile($(`<div class="container-fluid">${t.html}</div>`),e.find(".container-fluid").first()),this.submit_model_form_error&&this.submit_model_form_error(t);for(const e of this.iterateAllChildren())e.submit_model_form_error&&e.submit_model_form_error(t);o(t)})})}return Promise.resolve()}}const we={classname:"class"};window.sdcDom=function(e,t,...n){if(!e)return"";const r=function(e,t){let n,r=!1;if("string"==typeof e)n=$(document.createElement(e));else{const t=`this.${e.name}`;n=$(document.createElement(t)),n.data("handler",e),r=!0}return t&&Object.entries(t).forEach(([e,t])=>{e.startsWith("on")?n[0].addEventListener(e.substring(2).toLowerCase(),t):(we[e.toLowerCase()]&&(e=we[e.toLowerCase()]),n[0].setAttribute(e,t))}),r&&n.addClass("_bind_to_update_handler _with_handler"),n}(e,t);for(const e of n)r.append(e);return r};let be,$e={CSRF_TOKEN:window.CSRF_TOKEN||"",LANGUAGE_CODE:window.LANGUAGE_CODE||"en",DEBUG:window.DEBUG||!1,VERSION:window.VERSION||"0.0",tagNames:[],Global:O,rootController:null,globalRootController:null,_isInit:!1,_origin_trigger:null,_globalControllerClasses:[],init_sdc:()=>{$e._isInit||($e._isInit=!0,$e._origin_trigger?_e():($e._origin_trigger=$.fn.trigger,$.fn.trigger=function(e){const t={}.hasOwnProperty.call(e,"type")?e.type:e;return b.includes(t)||(b.push(t),$(window).on(t,C)),$e._origin_trigger.call(this,e)},$e.updateJquery()),pe(),function(){const e=$(window);b.forEach(t=>{e.off(t).on(t,C)})}(),$e.rootController=$e.rootController||new ve,$e.globalRootController=$e.globalRootController||new ve),$e.tagNames=Object.keys(S);const e=$("<div></div>");O.forEach(t=>{const n=S[t][0];e.append(`<${n.prototype._tagName}></${n.prototype._tagName}>`)});const{refreshProcess:n}=I(null,$e.rootController);return H($e.tagNames,e,$e.globalRootController,n).then(()=>H($e.tagNames,(t||(t=$("body")),t),$e.rootController,n).then(e=>(x(n),e)))},updateJquery:()=>{$.fn.safeReplace=function(e){return $e.safeReplace($(this),e)},$.fn.safeEmpty=function(){return $e.safeEmpty($(this))},$.fn.safeRemove=function(){return $e.safeRemove($(this))}},controllerToTag:e=>o(e.name).replace(/-controller$/,""),registerGlobal:e=>{$e.register(e);let t=e.prototype._tagName;O.push(t)},cleanCache:()=>{U={}},register:(e,t=!1)=>{let n=$e.controllerToTag(e);return!S[n]||t?(S[n]=[e,[]],e.prototype._tagName=n,{addMixin:(...e)=>{for(let t of e){let e;"string"==typeof t?e=o(t):t&&(e=$e.controllerToTag(t)),S[n][1].push(e)}}}):{addMixin:(...e)=>{}}},post:(e,t,n)=>(n||(n={}),n.CSRF_TOKEN=$e.CSRF_TOKEN,$e.ajax(e,t,n,$.post)),get:(e,t,n)=>$e.ajax(e,t,n,$.get),ajax:(e,t,n,r)=>{n||(n={}),n.VERSION=$e.VERSION,n._method=n._method||"api";const s=new Promise((o,i)=>r(t,n).then((t,n,r)=>{o(t,n,r),"redirect"===t.status?A("onNavLink",t["url-link"]):s.then(()=>{$e.refresh(e.$container)})}).catch(i));return s},submitFormAndUpdateView:(e,t,n,r)=>{let s=new FormData(t);const o=e=>{e["url-link"]?A("onNavLink",e["url-link"]):window.location.href=e.url},i=new Promise((l,c)=>{a(s,n||t.action,r||t.method).then((t,n,r)=>{l(t,n,r),"redirect"===t.status?o(t):i.then(()=>{$e.refresh(e.$container,e)})}).catch((e,t,n)=>{301===e.status?(e=e.responseJSON,o(e),l(e,t,n)):c(e,t,n)})});return i},submitForm:(e,t,n)=>{let r=new FormData(e);return new Promise((s,o)=>{a(r,t||e.action,n||e.method).then(s).catch(o)})},getController:e=>G(e),safeEmpty:e=>(e.children().each(function(e,t){let n=$(t);$e.safeRemove(n)}),e),safeReplace:(e,t)=>(t.insertBefore(e),$e.safeRemove(e)),safeRemove:e=>(e.each(function(){let e=$(this);e.data(`${D}`)&&e.data(`${D}`).remove()}),e.find(`.${J}`).each(function(){const e=$(this).data(`${D}`);e&&e.remove()}),e.remove()),reloadController:e=>function(e){if(e.contentUrl){let t=W(e);return e.contentUrl=t.url,Q(e,t.args)}return new Promise(e=>{e($())})}(e).then(t=>{let n=$(t);return $e.reconcile(e,n)}),reconcile:(e,t,n=null,r=null)=>{if(!n){let n=e.$container.clone().empty();n.data(D,null),n.removeClass(J),n.append(t),t=n}n=n??e.$container;const{refreshProcess:s,isRunningProcess:o}=I(r,e);return ee(t,e,s).then(()=>{var r;return Y(t,n),(r=e)._childController={},r.find(`.${J}`).each(function(){const e=G($(this));e===r&&k(r,e)}),o||x(s),e})},refresh:(e,t=null)=>ee(e,t)},Re=[];function Ce(){if(!jest)throw new Error("JEST is not defined");0===Re.length&&(be=$.ajax.bind($),Re.push(jest.spyOn($,"ajax")),Re[0].mockImplementation(function(e){return be(e).then(e=>e).catch(e=>e)}))}const Ne=_e,Oe={get_controller:async function(e,t={},n=""){Ce();const r=$("body");$e.updateJquery(),r.safeEmpty();const s=$(`<${e}>${n}</${e}>`);for(const[e,n]of Object.entries(t))s.data(e,n);const o=$("<div></div>").append(s);return r.append(o),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc(),$e.getController(s)},getCsrfToken:function(){return function(e){if(document.cookie&&""!==document.cookie){const t=document.cookie.split(";");for(let n=0;n<t.length;n++){const r=t[n].trim();if(r.substring(0,10)===e+"=")return decodeURIComponent(r.substring(10))}}return""}("csrftoken")},controllerFromTestHtml:async function(e,t=null){Ce();const n=$("body");$e.updateJquery(),n.safeEmpty().append(e),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc();let r=$e.rootController.iterateAllChildren();if(!t)return r;const s=r[0].onRefresh,o=jest.spyOn(r[0],"onRefresh");return new Promise(e=>{o.mockImplementation(function(){o.mockRestore();const t=s.apply(r[0],arguments);return e(r),t})})}};export{ve as AbstractSDC,ue as SdcModel,ce as SdcQuerySet,M as allOff,$e as app,u as checkIfParamNumberBoolOrString,h as clearErrorsInForm,F as controllerFactory,q as on,ne as registerModel,P as runControlFlowFunctions,f as setErrorsInForm,T as setEvent,Ne as socketReconnect,Oe as test_utils,A as trigger};
|
|
1
|
+
var e={};let t;e.d=(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},e.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);const n=/(?<=^|,\s?)[^=\s,]+/g,r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function s(){return new Promise(function(e){e()})}function o(e){return(e=(e=e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)).replace(/[0-9]+/g,e=>`-${e}`)).replace(/^[-]/g,"")}function i(e){return e.replace(/-./g,e=>`${e[1].toUpperCase()}`)}const l=(e,t)=>{let n=t,r=Object.getOwnPropertyNames(e.prototype).concat(Object.getOwnPropertySymbols(e.prototype));for(;""!==n.name;)Object.getOwnPropertyNames(n.prototype).concat(Object.getOwnPropertySymbols(n.prototype)).forEach(t=>{t.match(/^(?:constructor|prototype|arguments|caller|name|bind|call|apply|toString|length)$/)||r.includes(t)||(r.push(t),Object.defineProperty(e.prototype,t,Object.getOwnPropertyDescriptor(n.prototype,t)))}),n=Object.getPrototypeOf(n)};function a(e,t,n){return $.ajax({url:t,type:n||"POST",xhr:function(){var e=$.ajaxSettings.xhr();return e.upload&&e.upload.addEventListener("progress",c,!1),e},data:e,cache:!1,contentType:!1,processData:!1,beforeSend:function(e,t){(function(e){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(e)})(t.type)||this.crossDomain||e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}})}function c(e){if(e.lengthComputable){var t=Math.round(e.loaded/e.total*100),n=$(".progress-container");100===t?n.hide():n.show(),t+="%",n.find(".progress-bar").css({width:t}).text(t)}}function u(e,t=null){return"string"!=typeof e?e:t&&void 0!==t[e]?"function"==typeof t[e]?t[e].bind(t):t[e]:e.match(/^(true|false)$/)?"true"===e:"undefined"!==e?"none"===e.toLowerCase()?null:e.match(/^-?\d+$/)?parseInt(e):e.match(/^-?\d+\.?\d+$/)?parseFloat(e):e.match(/^(['][^']*['])|(["][^"]*["])$/)?e.substr(1,e.length-2):e:void 0}function d(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,e=>(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16))}function h(e){e.find(".has-error").removeClass("has-error").find(".alert-danger").remove(),e.find(".non-field-errors").remove()}function f(e,t){t=$("<div>").append(t),e.find(".has-error").removeClass("has-error").find(".alert-danger").safeRemove(),e.find(".non-field-errors").safeRemove();let n=t.find("input[type=file]").parent();e.find("input[type=file]").parent().each(function(e){$(this).replaceWith(n[e])});let r=0===t.find(".non-field-errors").insertAfter(e.find(".hidden-form-fields")).length;return t.find(".has-error").each(function(){r=!1;let t=$(this),n=t.data("auto-id"),s=e.find(".form-group."+n);s.addClass("has-error"),s.find(".form-input-container").append(t.find(".alert-danger"))}),r}function m(e){let{type:t,name:n}=e;return n&&""!==n?"hidden"===t?(r=$(e).val()).toLowerCase().match(/^(true|false)$/)?"true"===r.toLowerCase():"undefined"!==r?"none"===r.toLowerCase()?null:r.match(/^-?\d+$/)?parseInt(r,10):r.match(/^-?\d+\.?\d+$/)?parseFloat(r):r.match(/^(['][^']*['])|(["][^"]*["])$/)?r.substring(1,r.length-1):r:void 0:"checkbox"===t?e.checked:"file"===t?e.files[0]:$(e).val():null;var r}function p(e,t){let{type:n,name:r}=e;if(r&&""!==r)if("checkbox"===n)e.checked=t;else if("file"===n){if(t instanceof File&&"undefined"!=typeof DataTransfer){let n=new DataTransfer;n.items.add(t),e.files=n}}else t instanceof ue?$(e).val(t.id):t instanceof ce?$(e).val(`[${t.getIds().join(",")}]`):$(e).val(t);return null}function y(e,t=[]){return Object.fromEntries(Object.entries(e).filter(([e,n])=>e!==D&&!t.includes(e)).map(([e,t])=>{if("string"==typeof t&&t.startsWith("SDC_JSON_MODEL=["))try{const{pk:n,fields:r}=JSON.parse(t.slice(16,-1));return[e,{...r,id:n,pk:n}]}catch{}return[e,t]}))}function g(e,t,n=null){let r=function(e,t){let n;e||(e=[]);let r=t.data(),s=y(r,e);n=[];for(let t=0;t<e.length;t++){let s=e[t];r.hasOwnProperty(s)?n.push(r[s]):n.push("undefined")}return n.push(s),n}(e,t);return function(e,t=null){let n=[];for(let r=0;r<e.length;r++){let s=u(e[r],t);n.push(s)}return n}(r,n)}function v(e,t,s){if(!e)return!1;if("function"!=typeof e.onInit)return!1;let o;var i;"function"==typeof e._on_init_params?o=e._on_init_params():o=(i=e.onInit.toString().replace(r,"")).slice(i.indexOf("(")+1,i.indexOf(")")).match(n)||[];let l=g(o,t,s._parentController);if(e.onInit.apply(s,l),s===e)for(let n in e._mixins)v(e._mixins[n],t,s)}const w=["onbeforeunload","onunload"],b=Object.keys(window).filter(e=>/^on/.test(e)&&!w.includes(e)).map(e=>e.slice(2));function R(e,t,n){let r;switch(e){case"mouseleave":case"mouseout":case"mouseenter":case"mousein":return r=document.elementFromPoint(t.clientX,t.clientY),n!==r&&!n.contains(r);default:return!0}}function N(e){let t=e.type;e.hasOwnProperty("namespace")&&e.namespace&&e.namespace.length&&(t+=`.${e.namespace}`);let n=$(e.target),r=null,s=!1,o=!1;for(e.stopImmediatePropagation=()=>o=!0,e.stopPropagation=()=>o=s=!0;n.length;){let i=n.attr(`sdc_${t}`);if(i&&R(t,e,n[0])){if(!r&&(r=G(n),!r))return;for(;r;){if(i.split(" ").forEach(o=>{if(s)return;let i=null;if("function"==typeof o)i=o;else if("function"==typeof r[o])i=r[o];else if("string"==typeof o&&o.startsWith("this.event_")){if(i=r.getEvents()[t],!i)return;if(i=i[o.slice(11)],!i)return}i&&i.call(r,n,e)}),o)return;r=r._parentController}}if(s)return;n=n.parent()}return{res:!0}}function C(e){if(e._isEventsSet)return;const t=e.getEvents();for(let n in t)if(t.hasOwnProperty(n)){let r=t[n];for(let t in r)r.hasOwnProperty(t)&&e.find(t).each(function(){let e=$(this),r=e.attr(`sdc_${n}`)||null;r=r?r.split(" "):[];const s=`this.event_${t}`;-1===r.indexOf(s)&&(r.push(s),e.attr(`sdc_${n}`,r.join(" ")))})}}let O=[],S={};function k(e,t){if(e){let n=i(t._tagName);e._childController[n]||(e._childController[n]=[]),e._childController[n].push(t)}return t._parentController=e}function E(e,t,n,r){let s=[];r=function(e,t){e=(e=e.concat(S[t][1])).filter((e,t,n)=>n.indexOf(e)===t);let n=!0;for(;n;){n=!1;for(let t of e)for(let r of S[t][1])e.includes(r)||(e.push(r),n=!0)}return e}(r,n);for(let e of r)s.push(S[e][0]);let o=new(function(e,...t){let n={[e.name]:class{constructor(...n){let r={};t.forEach(e=>{let t;Object.assign(this,t=new e),t._tagName=e.prototype._tagName,t._isMixin=!0,r[e.name]=t}),Object.assign(this,new e),this._mixins=r}static get name(){return e.name}static className(){return this.name}get mixins(){return this._mixins}}}[e.name];return l(n,e),t.forEach(e=>{l(n,e)}),n}(S[n][0],...s));return o._tagName=n,k(e,o),o.$container=t,function(e,t){v(t,e,t)}(t,o),o}function F(e,t,n,r){if(O.includes(n)){let s=i(n);return window[s]||(window[s]=E(e,t,n,r)),window[s].$container=t,window[s]}return E(e,t,n,r)}function P(e,t){const n=function(e){return function(e){let t={args:{}};return e.contentUrl&&(t=W(e),e.contentUrl=t.url),Promise.all([Q(e,t.args)]).then(function(e){let t=e[0];if(t)try{return $(t)}catch{return $("<div></div>").append(t)}return null})}(e).then(t=>!e.onLoad||e._onLoadDone?t:(e._onLoadDone=!0,(e.onLoad(t)||s()).then(()=>t)))}(e).then(function(t){return function(e,t){return K(e,t).then(function(t){if(t=t||!0,e.willShow){let n=e.willShow();if(n instanceof Promise)return n.then(function(){return t})}return t})}(e,t)}).then(()=>function(e,t){return ee(null,e,t)}(e,t)).catch(function(t){return K(e,t)});return e.load_async?Promise.resolve():n}function x(e){const t=function(e){let t=[];for(;e;)e._isEventsSet=!1,t.unshift(e),e=e._parentController;return t}(e.controller[0]),n=t.concat(e.controller.slice(1));for(let t of n)C(t),t.onRefresh(e.controller[0])}function I(e,t){let n=Boolean(e);return n?e.uuids.has(t._uuid)||(e.uuids.add(t._uuid),e.controller.push(t)):e={uuids:new Set([t._uuid]),controller:[t]},{isRunningProcess:n,refreshProcess:e}}let L={},j={};function q(e,t){return T(e),j.hasOwnProperty(e)?t[j[e]]?void L[e].push(t):console.log("No event handler: "+e,t):console.log("No event: "+e,t)}function T(e,t){t||(t=e),j[e]||(j[e]=t,L[e]=[])}function M(e){for(let t in L)if(L.hasOwnProperty(t))for(let n=L[t].length-1;n>=0;n--)e===L[t][n]&&L[t].splice(n,1)}function A(e){let t=Array.apply(null,arguments);if(e=t.shift(),!L.hasOwnProperty(e)||!j.hasOwnProperty(e))return s();let n=L[e],r=j[e],o=[];for(let e=0;e<n.length;e++){let s=n[e][r].apply(n[e],t);void 0!==s&&o.push(s)}return Promise.all(o)}let U={};const D="_controller_",J="_sdc_controller_";function V(e,t,n){if(!e)return[];let r=e.children(),s=[];return r.each(function(e,r){let o=$(r),i=o.prop("tagName").toLowerCase().split("_");$.inArray(i[0],t)>=0?s.push({tag:i[0],super:i.splice(1)||[],dom:o}):i[0].startsWith("this.")?o.addClass(`_bind_to_update_handler sdc_uuid_${n._uuid}`):s=s.concat(V(o,t,n))}),s}function Q(e,t){const{contentUrl:n,_tagName:r,contentReload:s}=e;return n?U[r]?Promise.resolve(U[r]):(t.VERSION=$e.VERSION,t._method="content",$.get(n,t).then(function(e){return s||(U[r]=e),e}).catch(function(t){throw 301===t.status&&A("_RedirectOnView",t.responseJSON["url-link"]),"function"==typeof e.confirmPageLoaded&&A("navLoaded",{controller_name:()=>t.status}),`<sdc-error data-code="${t.status}">${t.responseText}</sdc-error>`})):Promise.resolve(!1)}function B(e,t,n=null){return t=t||e.data(D),H($e.tagNames,e,t,n)}function W(e){let t=e.contentUrl;if(e&&0===e._urlParams.length){let n,r=/%\(([^)]+)\)\w/gm;for(e._urlParams=[];n=r.exec(t);)e._urlParams.push(n[1]),e.contentReload=!0}let n=function(e,t){return g(e._urlParams,t)}(e,e.$container);return e._urlParams.length&&(t=function(e,t,n){for(let r in e._urlParams)if(e._urlParams.hasOwnProperty(r)){let s=e._urlParams[r],o=RegExp("%\\("+s+"\\)\\w","gm");t=t.replace(o,""+n.shift())}return t}(e,t,n)),e.parsedContentUrl=t,{url:t,args:n[n.length-1]}}function G(e){return e.hasClass(J)?e.data(`${D}`):e.closest(`.${J}`).data(`${D}`)}function z(e,t,n,r,s){let o=e.data(D);return o?B(e,o,s):(o=F(r,e,t,n),e.data(D,o),e.addClass(J),P(o,s))}function K(e,t,n=null){if(t&&t.length>0){e.$container.empty(),e.$container.attr(e._tagName,"");for(let t in e._mixins)e.$container.attr(e._mixins[t]._tagName,"");e.$container.append(t)}return B(e.$container,e,n)}function H(e,t,n,r){return new Promise(s=>{let o=V(t,e,n),i=o.length;if(0===i)return s();for(let e=0;e<o.length;e++)z(o[e].dom,o[e].tag,o[e].super,n,r).then(()=>{if(i--,0===i)return s()})})}function X({$element:e,id:t=[],parent:n=null}){t.push(function(e){if(3===e[0].nodeType)return`TEXT__${e[0].nodeValue}`;const t=[e[0].tagName];return"INPUT"===e[0].nodeName&&[["name",""],["type","text"],["id",""]].forEach(([n,r])=>{const s=e.attr(n)??r;s&&t.push(s)}),t.join("__")}(e));const r={$element:e,id:t.join("::"),depth:t.length,idx:0,getRealParent:()=>n,getIdx:function(){return this.idx=Math.max(0,(this.getRealParent()?.getIdx()??-1)+e.index()+1),this.idx},op:null,parent:n};return r.getIdx.bind(r),[r].concat(e.contents().toArray().map(e=>X({$element:$(e),id:t.slice(),parent:r})).flat())}function Y(e,t){const n=X({$element:t}),r=X({$element:e});n.map((e,t)=>e.idx=t),r.map((e,t)=>e.idx=t);const s=Math.max(...r.concat(n).map(e=>e.depth)),o=Z(n,r,s);let i=[];window.MAIN=t,window.OPS=o,o.forEach((e,t)=>{const{op:n,$element:r,idx:s}=e;if("keep_counterpart"===n.type){if(n.counterpart.getIdx()!==s){const t=e.getBefore();t?n.counterpart.$element.insertAfter(t.$element):e.getRealParent().$element.prepend(n.counterpart.$element)}!function(e,t){const n=e[0].attributes??[],r=t[0].attributes??[];[...n].forEach(n=>{t.is(`[${n.name}]`)||e.removeAttr(n.name)}),[...r].forEach(t=>{t.name.startsWith("data")||e.attr(t.name)===t.value||e.attr(t.name,t.value)}),e.removeData(),Object.entries(t.data()).forEach(([t,n])=>{e.data(t,n)})}(n.counterpart.$element,r),r.hasClass(J)&&(r.data(D).$container=n.counterpart.$element,r.data(D,null)),i.push(r)}else if("delete"===n.type)r.safeRemove();else if("insert"===n.type){const{after:t,target:n}=e.op;t?r.insertAfter(t.$element):n&&n.$element.prepend(r)}}),i.forEach(e=>e.safeRemove())}function Z(e,t,n){return t.filter(e=>e.depth===n&&!e.op).forEach(t=>{const n=e.find(e=>!e.op&&e.id===t.id);if(n){const e=(t,n)=>{t.op={type:"keep",idx:n.idx},n.op={type:"keep_counterpart",counterpart:t},t=t.parent,n=n.parent,!t||t.op||n?.op||e(t,n)};e(n,t)}}),n>1?Z(e,t,n-1):(e.forEach((t,n)=>{if(!t.op){const r=(e[n-1]?.op.idx??-1)+1;t.op={type:"delete",idx:r}}}),t.forEach((e,n)=>{if(e.getBefore=()=>function(e,n){const r=e.depth;for(;n>=1&&e.depth>=r;)if((e=t[n-=1]).depth===r)return"keep_counterpart"===e.op.type?e.op.counterpart:e;return null}(e,n),e.getRealParent=()=>{return(t=e).parent?"keep_counterpart"===t.parent.op.type?t.parent.op.counterpart:t.parent:null;var t},!e.op){const t=e.getRealParent(),n="insert"===t?.op.type?"insert_ignore":"insert";e.op={type:n,target:t,after:e.getBefore()}}}),[...e,...t].sort((e,t)=>(e.op?.idx??e.idx)-(t.op?.idx??t.idx)))}function ee(e,t,n=null){if(t||(t=G(e)),!t)return Promise.resolve();const{refreshProcess:r,isRunningProcess:s}=I(n,t);return e??=t.$container,H($e.tagNames,e,t,n).then(()=>function(e,t,n){return function(e,t,n){const r=[];return t.find(`._bind_to_update_handler.sdc_uuid_${e._uuid}`).each(function(){const t=$(this);let s;if(t.hasClass("_with_handler"))s=t.data("handler");else{let t=this.tagName.toLowerCase().replace(/^this./,"");e[t]&&(s=e[t])}if("function"==typeof s){const n=y(t.data());s=s.bind(e)(n)}s&&r.push(Promise.resolve(s).then(r=>{let s=$("<div></div>");return s.append(r),""===t.html()&&t.append("<div></div>"),$e.reconcile(e,s,t.children(),n)}))}),Promise.all(r)}(e,t??e.$container,n)}(t,e,r).then(()=>{s||x(r)}))}const te={};function ne(e,t){te[e]=t}function re(e){return te[e]}const se=25e3,oe="_connecting_process";class ie extends Error{constructor(e){"string"==typeof e&&(e={msg:e,is_error:!0,header:"Error"}),super(e.msg),this.msg=e.msg,this.header=e.header,this.is_error=e.is_error,this.html=e.html}}class le{constructor({name:e,url:t}){this.name=e,this.url=t,this.content=null}async load(e=!1){return!e&&this.content||(this.content=await new Promise((e,t)=>{$.get(this.url).then(e).catch(()=>{e("")})})),this.content}async text(){return this.load()}static isValid(e){return!(null===e||"object"!=typeof e||Array.isArray(e)||e instanceof File||"string"!=typeof e.url||"string"!=typeof e.name)}}function ae(e){const t=parseInt(e??-1,10);return Number.isNaN(t)?-1:t}class ce{constructor(e,t={}){return this.valuesList=[],this.loaded=!1,this.modelName=e,this.modelQuery=t??{},this._onNoOpenRequests=[],this._isConnected=!1,this._isConnectingProcess=!1,this._autoReconnect=!0,this.socket=null,this.openRequest={},this.modelId=0,this.onUpdate=()=>{},this.onCreate=()=>{},new Proxy(this,{get:(e,t)=>"symbol"==typeof t||isNaN(t)?e[t]:e.valuesList[t],set:(e,t,n)=>isNaN(t)?(e[t]=n,!0):(e.valuesList[t]=n,!0)})}[Symbol.iterator](){let e=-1;return{next:()=>(++e,e<this.valuesList.length?{value:this.valuesList[e],done:!1}:{value:null,done:!0})}}set on_create(e){this.onCreate=e}set on_update(e){this.onUpdate=e}setIds(e){if(null===e||""===e||Array.isArray(e)&&0===e.length)return this.valuesList=[],this.valuesList;if(e instanceof ce)return this.valuesList=structuredClone(e.valuesList),this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;if(e instanceof ue)return this.valuesList=[structuredClone(e)],this.valuesList.forEach(e=>e._setQuerySet(this,!0)),this.valuesList;let t,n=Number.NaN;if(Number.isInteger(e))n=e;else if(e instanceof Array){const n=e.map(e=>parseInt(e));n.some(Number.isNaN)||(t=n)}else if("string"==typeof e){const r=e.split(",").map(e=>parseInt(e));r.some(Number.isNaN)?n=parseInt(e):t=r}if(Number.isNaN(n)){if(t){this.valuesList=this.valuesList.filter(e=>t.includes(e.id));const e=this.getIds();t.filter(t=>!e.includes(t)).forEach(e=>{this.valuesList.push(new(re(this.modelName))({id:e}))})}}else this.new().id=n;return this.valuesList}getIds(){return this.valuesList.map(e=>e.id)}get length(){return this.valuesList.length}byId(e){if(null!==e){const t=ae(e);return this.valuesList.find(e=>e.id===t)??null}return null}setFilter(e){return this.modelQuery=e,this}addFilter(e){return this.modelQuery=Object.assign({},this.modelQuery,e),this}new(e={}){const t=new(re(this.modelName))(e);return t._setQuerySet(this,!1),this.valuesList.push(t),t}load(e=null){return this.valuesList=[],this.modelQuery=e??this.modelQuery,this._sendLoad()}update({modelQuery:e=null,item:t=null}){this.modelQuery=e??this.modelQuery;let n=t?{pk:t.id}:this.modelQuery;return this._sendLoad(n)}delete({pk:e=null,elem:t=null}){if(null===(e=t?t.id:e))throw new Error("pk or elem must be set");const n=d();return this.isConnected().then(()=>new Promise((t,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"delete",event_id:n,args:{model_name:this.modelName,model_query:this.modelQuery,pk:e}})),this.openRequest[n]=[t,r]}))}_sendLoad(e=null){return this.isConnected().then(()=>{const t=d();return new Promise((n,r)=>{this.socket.send(JSON.stringify({event:"model",event_type:"load",event_id:t,args:{model_name:this.modelName,model_query:e??this.modelQuery}})),this.openRequest[t]=[e=>{this.loaded=!0,n(e)},r]})})}_sendListView({modelQuery:e={},cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this.view({modelQuery:e,cbResolve:t,cbReject:n,templateContext:r,eventType:"list_view"})}view({viewName:e="html_list_template",modelQuery:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={},eventType:o="named_view"}){let i=$('<div class="container-fluid">');return this.isConnected().then(()=>{const l=d();this.socket.send(JSON.stringify({event:"model",event_type:o,event_id:l,args:{view_name:e,model_name:this.modelName,model_query:t,template_context:s}})),this.openRequest[l]=[e=>{i.append(e.html),$e.refresh(i),n&&n(e)},e=>{r&&r(e)}]}),i}_sendDetailView({pk:e=null,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){e=ae(e);let s=$('<div class="container-fluid">');return this.isConnected().then(()=>{const o=d();this.socket.send(JSON.stringify({event:"model",event_type:"detail_view",event_id:o,args:{model_name:this.modelName,model_query:this.modelQuery,pk:e,template_context:r}})),this.openRequest[o]=[e=>{s.append(e.html),$e.refresh(s),t&&t(e)},e=>{n&&n(e)}]}),s}getForm({modelObj:e,eventType:t,formName:n,$divForm:r,cbResolve:s,cbReject:o,formId:i}){const l=d(),a=e.id??-1;this.isConnected().then(()=>{this.socket.send(JSON.stringify({event:"model",event_type:t,event_id:l,args:{model_name:this.modelName,pk:a,form_name:n}}))});const c=null===a||-1===a?"create":"edit";this.openRequest[l]=[t=>{r.append(t.html);let o=r.closest("form").addClass(`sdc-model-${c}-form sdc-model-form ${i}`).data("model",e).data("model_pk",a).data("form_name",n);e.addForm(o),o.length>0&&!o[0].hasAttribute("sdc_submit")&&o.attr("sdc_submit","submitModelFormDistributor"),$e.refresh(r).then(()=>null),s&&s(t)},e=>{o&&o(e)}]}async get(e=null,t=!1){if(t){const t=e?.id??e?.pk;return this.byId(t)??this.new(e||this.modelQuery)}if(await this.load(e),1!==this.length)throw new Error(`model query returns ${this.length} but only 1 expected.`);return this.valuesList[0]}detailView({pk:e,cbResolve:t=null,cbReject:n=null,templateContext:r={}}){return this._sendDetailView({pk:e,cbResolve:t,cbReject:n,templateContext:r})}listView({modelQuery:e={},searchValues:t={},cbResolve:n=null,cbReject:r=null,templateContext:s={}}){return this._sendListView({modelQuery:Object.assign({},this.modelQuery,e,{__search_values:t}),cbResolve:n,cbReject:r,templateContext:s})}save({pk:e=null,formName:t="edit_form",data:n=null}={}){const r=ae(e);return this.isConnected().then(()=>{let e;if(r>-1){const t=this.byId(r);if(!t)return Promise.reject(new ie(`Element not found with ID: ${r}`));e=[t]}else e=this.valuesList;let s=[];return e.forEach(e=>{const r=d();s.push(new Promise((s,o)=>{this._readFiles(e).then(i=>{const l=n?{...n}:e.serialize();l.pk=e.id,this.socket.send(JSON.stringify({event:"model",event_type:"save",event_id:r,args:{form_name:t,model_name:this.modelName,model_query:this.modelQuery,data:l,pk:l.pk,files:i}})),this.openRequest[r]=[e=>{let t="string"==typeof e.data.instance?JSON.parse(e.data.instance):e.data.instance;e.data.instance=this._parseServerRes(t),s(e)},o]})}))}),Promise.all(s)})}create({elem:e=null,data:t=null}={}){const n=d();return e||(e=this.new(t)),this.isConnected().then(()=>new Promise((r,s)=>{this._readFiles(e).then(o=>{this.socket.send(JSON.stringify({event:"model",event_type:"create",event_id:n,args:{model_name:this.modelName,model_query:this.modelQuery,data:t??e?.serialize()??{},files:o}})),this.openRequest[n]=[t=>{let n="string"==typeof t.data.instance?JSON.parse(t.data.instance):t.data.instance;e&&(e.id=n[0]?.pk||n[0]?.id),t.data.instance=this._parseServerRes(n)[0],r(t)},s]})}))}isConnected(){return new Promise((e,t)=>{if(this._isConnected)e();else if(this._isConnectingProcess&&this.openRequest[oe]){const[n,r]=this.openRequest[oe];this.openRequest[oe]=[()=>{n(),e()},()=>{r(),t()}]}else this._isConnectingProcess=!0,this.openRequest[oe]=[()=>{},()=>{}],this._connectToServer().then(()=>{e(this._checkConnection())})})}close(){this.socket&&(this._autoReconnect=!1,this.socket.onclose=()=>{},this.socket.close(),delete this.socket),this.valuesList.forEach(e=>{e._onClose()})}_readFiles(e){let t=[],n={};return e?(Object.keys(e.constructor.fields).forEach(r=>{const s=e[r];s instanceof File&&t.push(new Promise(async(e,t)=>{const o=d();this.openRequest[o]=[e,t];const i=await s.arrayBuffer();let l=new Uint8Array(i),a=Math.ceil(l.length/se);n[r]={id:o,file_name:s.name,field_name:r,content_length:s.size};for(let e=0;e<a;++e){const t=Array.from(l.slice(se*e,se*(e+1)));this.socket.send(JSON.stringify({event:"model",event_type:"upload",event_id:o,args:{chunk:t,idx:e,number_of_chunks:a,file_name:s.name,field_name:r,content_length:s.size,content_type:s.type,model_name:this.modelName,model_query:this.modelQuery}}))}}))}),Promise.all(t).then(()=>n)):Promise.resolve(n)}async _onMessage(e){let t=JSON.parse(e.data);if(t.is_error)this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][1](new ie(t)),this._closeOpenRequest(t.event_id)),(t.msg||t.header)&&A("pushErrorMsg",t.header||"",t.msg||""),"connect"===t.type&&(this.openRequest[oe][1](new ie(t)),this._closeOpenRequest(oe),this._autoReconnect=!1,this.socket.close());else{if((t.msg||t.header)&&A("pushMsg",t.header||"",t.msg||""),"connect"===t.type)this._isConnected=!0,this._isConnectingProcess=!1,this.openRequest[oe][0](t),this._closeOpenRequest(oe);else if(["load","named_view","detail_view"].includes(t.type)){const e=JSON.parse(t.args.data);t.args.data=await this._parseServerRes(e)}else if("on_update"===t.type||"on_create"===t.type){const e=JSON.parse(t.args.data);let n,r=await this._parseServerRes(e);n="on_create"===t.type?this.onCreate:this.onUpdate,n(r),t.args.data=r}let e=t.data?.instance;e&&(t.data.instance=JSON.parse(t.data.instance)),this.openRequest.hasOwnProperty(t.event_id)&&(this.openRequest[t.event_id][0](t),this._closeOpenRequest(t.event_id))}}noOpenRequests(){return new Promise(e=>{if(0===Object.keys(this.openRequest).length)return e();this._onNoOpenRequests.push(e)})}_closeOpenRequest(e){delete this.openRequest[e],0===Object.keys(this.openRequest).length&&(this._onNoOpenRequests.forEach(e=>e()),this._onNoOpenRequests=[])}_connectToServer(){return new Promise(e=>{const t=`${this.modelName}`+(this.modelId>0?`/${this.modelId}`:"");"https:"===window.location.protocol?this.socket=new WebSocket(`wss://${window.location.host}/sdc_ws/model/${t}`):this.socket=new WebSocket(`ws://${window.location.host}/sdc_ws/model/${t}`),this.socket.onmessage=this._onMessage.bind(this),this.socket.onclose=e=>{console.error(`SDC Model (${this.modelName}, ${this.modelId}) Socket closed unexpectedly`),this._isConnected=!1;for(const[t,n]of Object.entries(this.openRequest))n[1](e);this.openRequest={},setTimeout(()=>{this._autoReconnect&&this._connectToServer().then(()=>{})},1e3)},this.socket.onerror=e=>{if(console.error(`Model Socket encountered error: ${e} Closing socket`),this._isConnected)try{this.socket.close()}catch(e){}},this.socket.onopen=()=>{e()}})}_checkConnection(){const e=d();return new Promise((t,n)=>{this.socket.send(JSON.stringify({event:"model",event_type:"connect",event_id:e,args:{model_name:this.modelName,model_query:this.modelQuery}})),this.openRequest[e]=[t,n]})}_parseServerRes(e){const t=[];for(const n of e){const e=re(this.modelName);if(!e)throw new Error(`${this.modelName} is no SdcModel. mybe the models ar not importad.`);const r=new e({id:n.pk??n.id,...n.fields}),s=this.byId(r.id);s?(s.setValues(r),t.push(s)):(this.valuesList.push(r),r._setQuerySet(this,!0),t.push(r))}return this.valuesList.sort((e,t)=>e._id-t._id),t}}class ue{static fields={};constructor(e){this._id=null,this._forms=[],this.loaded=!1,this.formId=d(),this.modelName=e}static querySet(e=null,t=null){return t?t.querySet(this.modeName,e):new ce(this.modeName,e)}addForm(e){const t=this._onChange.bind(this);this._forms.push(e),e&&e.on("input.formWatcher change.formWatcher","input, select, textarea",t)}_onChange(e){const{name:t}=e.target;this.constructor.fields[t]&&this[`set${t}`](m(e.target))}_updateForm(e){const t=this;this._forms.forEach(n=>{n.find(`[name="${e}"]`).each(function(){p(this,t[e])})})}setValues(e={}){throw new Error("setValues() must be implemented by subclass")}_setQuerySet(e,t){this._querySet=new WeakRef(e),this.loaded=t}save({formName:e="edit_form",data:t=null}={}){return this._querySet.deref().save({pk:this.id,formName:e,data:t})}create({data:e=null}={}){return this._querySet.deref().create({elem:this,data:e})}delete(){return this._querySet.deref().delete({elem:this})}load(){return this._querySet.deref().update({item:this})}get id(){return this._id}set pk(e){this._id=e}get pk(){return this._id}close(){return this._querySet.deref().close()}_onClose(){Object.keys(this.constructor.fields).filter(e=>this[`_${e}`]instanceof ce).forEach(e=>this[`_${e}`].close())}detailView({cbResolve:e=null,cbReject:t=null,templateContext:n={}}){return this._querySet.deref().detailView({pk:this.id,cbResolve:e,cbReject:t,templateContext:n})}serialize(){return Object.entries(this.constructor.fields).reduce((e,[t,n])=>{const r=this[t];if(r instanceof ce)if(n.many_to_many||n.one_to_many)e[t]=r.getIds();else{const n=r.getIds();n.length>0?e[t]=n[0]:e[t]=null}else n.is_relation&&r instanceof ue?e[t]=r.id??null:e[t]=r;return e},{})}toJson(){const e={};for(let t in this.constructor.fields){const n=this[t];n instanceof File?e[t]=n.name:e[t]=n instanceof ue?n.id:n instanceof ce?n.getIds():n}return e}syncFormToModel(e){return this.syncForm(e)}_resolveForms(e){return e&&e.hasClass(this.formId)?e:$(`.${this.formId}`)}syncModelToForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields;e.each(function(){const e=ae($(this).data("model_pk"));if(t.id===e)for(let e of this.elements){let r=e.name;r&&""!==r&&n[r]&&p(e,t[r])}})}syncForm(e){e=this._resolveForms(e);const t=this,n=this.constructor.fields,r={};function s(e,s){n[e]&&(t[e]=s),r[e]=s}return e.each(function(){const e=ae($(this).data("model_pk"));if(t.id===e||null===t.id&&-1===e){for(let e of this.elements)s(e.name,m(e));return t}}),r}form({cbResolve:e=null,cbReject:t=null}={}){return null===this.id||-1===this.id?this._createForm({cbReject:t,cbResolve:e}):this._editForm({cbReject:t,cbResolve:e})}_createForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"create_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}_editForm({cbResolve:e=null,cbReject:t=null}){let n=$("<div>");return this._querySet.deref().getForm({modelObj:this,eventType:"edit_form",formName:null,$divForm:n,cbResolve:e,cbReject:t,formId:this.formId}),n}namedForm({formName:e,cbResolve:t=null,cbReject:n=null}){let r=$('<div class="container-fluid">');return this._querySet.deref().getForm({modelObj:this,eventType:"named_form",formName:e,$divForm:r,cbResolve:t,cbReject:n,formId:this.formId}),r}validate(e,t){const n=function(e,t){const{type:n,required:r,max_length:s,is_relation:o,many_to_many:i,one_to_many:l,many_to_one:a,one_to_one:c,related_model:u}=t;if(r&&(null==e||""===e))return"This field is required";if(null==e||""===e)return null;if((i||l||a||c)&&(!(e instanceof ce)||e.modelName!==u))return"object"!=typeof e&&Number.isNaN(parseInt(e))?"Must be object or ID":null;switch(n){case"CharField":case"TextField":if("string"!=typeof e)return"Must be a string";if(s&&e.length>s)return`Max length is ${s}`;break;case"IntegerField":case"AutoField":case"BigIntegerField":if(!Number.isInteger(e))return"Must be an integer";break;case"FloatField":case"DecimalField":if("number"!=typeof e)return"Must be a number";break;case"BooleanField":if("boolean"!=typeof e)return"Must be a boolean";break;case"DateField":case"DateTimeField":if(isNaN(Date.parse(e)))return"Must be a valid date";break;case"EmailField":if("string"!=typeof e||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e))return"Invalid email";break;case"URLField":try{new URL(e)}catch{return"Invalid URL"}break;case"UUIDField":if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(e))return"Invalid UUID";break;case"JSONField":if("object"!=typeof e)return"Must be JSON object";break;case"FileField":if(!(le.isValid(e)||e instanceof File||e instanceof le))return"Must be a valid file"}return null}(e,t);if(n)throw new Error(n)}parseValue(e,t){const{type:n}=t;switch(n){case"CharField":case"TeextField":case"UUIDField":case"EmailField":return`${e}`;case"IntegerField":case"AutoField":case"BigIntegerField":return parseInt(e,10);case"FloatField":case"DecimalField":if("number"!=typeof e)return"Must be a number";break;case"BooleanField":return!!e;case"DateField":case"DateTimeField":return Date.parse(e);case"URLField":return new URL(e);case"FileField":if(null==e)return null;if("string"==typeof e)return null;if(le.isValid(e))return new le(e);if(e instanceof le)return new le(e);if("undefined"!=typeof File&&e instanceof File)return t.max_size&&e.size>t.max_size?`File too large (max ${t.max_size} bytes)`:t.allowed_types&&!t.allowed_types.includes(e.type)?`Invalid file type (${e.type})`:e;break;case"JSONField":if("object"==typeof e)return e;if("string"==typeof e)return JSON.parse(e)}return e}}let de=!1,he=!1,fe=null,me={};function pe(){return window.SERVER_CALL_VIA_WEB_SOCKET?new Promise(e=>de?e():he?void setTimeout(()=>{pe().then(()=>{e()})},200):e(ye())):Promise.resolve(!0)}function _e(){window.SERVER_CALL_VIA_WEB_SOCKET&&function(){if(de){de=!1;try{fe.close()}catch(e){}}}()}function ye(){return he=!0,new Promise(e=>{fe="https:"===window.location.protocol?new WebSocket(`wss://${window.location.host}/sdc_ws/ws/`):new WebSocket(`ws://${window.location.host}/sdc_ws/ws/`),fe.onmessage=function(e){ge(JSON.parse(e.data))},fe.onclose=function(){de&&console.error("SDC Socket closed unexpectedly"),de=!1;for(const[e,t]of Object.entries(me))t[1]({}),delete me[e];setTimeout(()=>{ye()},1e3)},fe.onerror=function(e){if(console.error("Socket encountered error: ",e.message,"Closing socket"),de)try{fe.close()}catch(e){}},fe.onopen=function(){de=!0,he=!1,e()}})}function ge(e){if(e||(e={}),e.is_error)(e.msg||e.header)&&A("pushErrorMsg",e.header||"",e.msg||""),e.id&&me[e.id]&&(me[e.id][1](e.data||null),delete me[e.id]);else if((e.msg||e.header)&&A("pushMsg",e.header||"",e.msg||""),e.type&&"sdc_recall"===e.type)e.id&&me[e.id]&&(me[e.id][0](e.data),delete me[e.id]);else if(e.type&&"sdc_event"===e.type){let t=e.event;t&&A(t,e.payload)}else e.type&&"sdc_redirect"===e.type&&A("onNavLink",e.link)}class ve{constructor(){this._uuid=d(),this.contentUrl="",this.contentReload=!1,this.parsedContentUrl=null,this.events=[],this.load_async=!1,this._isEventsSet=!1,this._allEvents=null,this._urlParams=[],this._models=[],this._cssUrls=[],this.afterShow=()=>{console.warn("afterShow is deprecated!!")},this._mixins={},this._tagName=Object.getPrototypeOf(this)._tagName??"",this._childController={},this._parentController=null,this._onLoadDone=!1,this.$container=null,this._isMixin=!1}_runLifecycle(e,t){$e.DEBUG&&!this._isMixin&&console.debug(e,this._tagName);let n=[];if(!this._isMixin){this._isMixin=!0;for(let r in this._mixins){let s=this._mixins[r];"function"==typeof s[e]&&n.push(s[e].apply(this,t))}return Promise.all(n).then(()=>{this._isMixin=!1})}}onInit(){$e.DEBUG&&!this._isMixin&&console.debug(Array.apply(null,arguments),this._tagName)}get parentController(){return this._parentController}get childController(){return this._childController}onLoad(){return this._runLifecycle("onLoad",arguments)}willShow(){return this._runLifecycle("willShow",arguments)}onRefresh(){return this._runLifecycle("onRefresh",arguments)}onRemove(){return this._runLifecycle("onRemove",arguments),!0}noOpenModelRequests(){return Promise.all(this._models.map(e=>e.noOpenRequests()))}remove(){for(const e of this._models)e.close();let e=this._childController;for(let t in e)if(e.hasOwnProperty(t))for(let n of e[t])if(!n.remove())return!1;if(!this.onRemove||this.onRemove()){M(this);const e=i(this._tagName);if(this._parentController._childController[e]){let t=this._parentController._childController[e];for(let e=0;e<t.length;e++)t[e]===this&&t.splice(e,1)}return this.$container.remove(),!0}return!1}controller_name(){return this._tagName.replace(/-./g,e=>` ${e[1].toUpperCase()}`).replace(/^./g,e=>`${e.toUpperCase()}`)}addEvent(e,t,n){this.getEvents(),this._allEvents[e]=this._allEvents[e]||{},this._allEvents[e][t]=n}getEvents(){if(this._allEvents)return this._allEvents;let e=[];e=e.concat(this.events);for(let t in this._mixins){let n=this._mixins[t];Array.isArray(n.events)&&(e=e.concat(n.events))}return this._allEvents=_.merge(...e)}post(e,t){return $e.post(this,e,t)}get(e,t){return $e.get(this,e,t)}submitForm(e,t,n){return $e.submitFormAndUpdateView(this,e,t,n)}serverCall(e,t){let n=this.contentUrl.match(/sdc_view\/([^/]+)/i);if(n&&!(n.length<2))return function(e,t,n,r,s){return window.SERVER_CALL_VIA_WEB_SOCKET?function(e,t,n,r){let s=d();return pe().then(()=>{fe.send(JSON.stringify({event:"sdc_call",id:s,controller:t,app:e,function:n,args:r}))}),new Promise((e,t)=>{me[s]=[e,t]})}(e,t,r,s):function(e,t,n){return"object"!=typeof n&&Array.isArray(n)&&null===n&&(n={arg0:n}),n={data:JSON.stringify(n),_sdc_func_name:t,_method:"sdc_server_call"},$.post({url:e,data:n,beforeSend:function(e,t){e.setRequestHeader("X-CSRFToken",window.CSRF_TOKEN)}}).then(e=>{const t=e._return_data;return ge(t),t}).catch(e=>{const t=e.responseJSON;throw t.is_error=!0,ge(t),e})}(n,r,s)}(n[1],this._tagName,this.parsedContentUrl??this.contentUrl,e,t);console.error("To use the serverCall function the contentUrl must be set: "+this.name)}querySet(e,t={}){const n=new ce(e,t);return this._models.push(n),n}newModel(e,t={}){return console.warn("newModel is deprecated and will soon be removed"),this.querySet(e,t)}find(e){return this.$container.find(e)}refresh(){return $e.refresh(this.$container,this)}reload(){return $e.reloadController(this)}reconcile(e,t=null){return $e.reconcile(this,e,t)}submitModelFormDistributor(e,t){return"function"==typeof this._submitModelForm?this._submitModelForm(e,t):"function"==typeof this.submitModelForm?this.submitModelForm(e,t):this.defaultSubmitModelForm(e,t)}iterateAllChildren(){let e=this._childController,t=[];for(let n in e)if(e.hasOwnProperty(n))for(let r of e[n])t.push(r),t.push(...r.iterateAllChildren());return t}defaultSubmitModelForm(e,t){if(!this._isMixin){t.stopPropagation(),t.preventDefault();let{model:n,form_name:r}=e.data(),s=n.syncForm(e);return new Promise((t,o)=>{let i;i=null!==n.id&&n.id>=0?n.save({formName:r,data:s}):n.create({data:s}),i.then(n=>{h(e),this.submit_model_form_success&&this.submit_model_form_success(n[0]);for(const e of this.iterateAllChildren())e.submit_model_form_success&&e.submit_model_form_success(n[0]);t(n)}).catch(t=>{this.reconcile($(`<div class="container-fluid">${t.html}</div>`),e.find(".container-fluid").first()),this.submit_model_form_error&&this.submit_model_form_error(t);for(const e of this.iterateAllChildren())e.submit_model_form_error&&e.submit_model_form_error(t);o(t)})})}return Promise.resolve()}}const we={classname:"class"};window.sdcDom=function(e,t,...n){if(!e)return"";const r=function(e,t){let n,r=!1;if("string"==typeof e)n=$(document.createElement(e));else{const t=`this.${e.name}`;n=$(document.createElement(t)),n.data("handler",e),r=!0}return t&&Object.entries(t).forEach(([e,t])=>{e.startsWith("on")?n[0].addEventListener(e.substring(2).toLowerCase(),t):(we[e.toLowerCase()]&&(e=we[e.toLowerCase()]),n[0].setAttribute(e,t))}),r&&n.addClass("_bind_to_update_handler _with_handler"),n}(e,t);for(const e of n)r.append(e);return r};let be,$e={CSRF_TOKEN:window.CSRF_TOKEN||"",LANGUAGE_CODE:window.LANGUAGE_CODE||"en",DEBUG:window.DEBUG||!1,VERSION:window.VERSION||"0.0",tagNames:[],Global:O,rootController:null,globalRootController:null,_isInit:!1,_origin_trigger:null,_globalControllerClasses:[],init_sdc:()=>{$e._isInit||($e._isInit=!0,$e._origin_trigger?_e():($e._origin_trigger=$.fn.trigger,$.fn.trigger=function(e){const t={}.hasOwnProperty.call(e,"type")?e.type:e;return b.includes(t)||(b.push(t),$(window).on(t,N)),$e._origin_trigger.call(this,e)},$e.updateJquery()),pe(),function(){const e=$(window);b.forEach(t=>{e.off(t).on(t,N)})}(),$e.rootController=$e.rootController||new ve,$e.globalRootController=$e.globalRootController||new ve),$e.tagNames=Object.keys(S);const e=$("<div></div>");O.forEach(t=>{const n=S[t][0];e.append(`<${n.prototype._tagName}></${n.prototype._tagName}>`)});const{refreshProcess:n}=I(null,$e.rootController);return H($e.tagNames,e,$e.globalRootController,n).then(()=>H($e.tagNames,(t||(t=$("body")),t),$e.rootController,n).then(e=>(x(n),e)))},updateJquery:()=>{$.fn.safeReplace=function(e){return $e.safeReplace($(this),e)},$.fn.safeEmpty=function(){return $e.safeEmpty($(this))},$.fn.safeRemove=function(){return $e.safeRemove($(this))}},controllerToTag:e=>o(e.name).replace(/-controller$/,""),registerGlobal:e=>{$e.register(e);let t=e.prototype._tagName;O.push(t)},cleanCache:()=>{U={}},register:(e,t=!1)=>{let n=$e.controllerToTag(e);return!S[n]||t?(S[n]=[e,[]],e.prototype._tagName=n,{addMixin:(...e)=>{for(let t of e){let e;"string"==typeof t?e=o(t):t&&(e=$e.controllerToTag(t)),S[n][1].push(e)}}}):{addMixin:(...e)=>{}}},post:(e,t,n)=>(n||(n={}),n.CSRF_TOKEN=$e.CSRF_TOKEN,$e.ajax(e,t,n,$.post)),get:(e,t,n)=>$e.ajax(e,t,n,$.get),ajax:(e,t,n,r)=>{n||(n={}),n.VERSION=$e.VERSION,n._method=n._method||"api";const s=new Promise((o,i)=>r(t,n).then((t,n,r)=>{o(t,n,r),"redirect"===t.status?A("onNavLink",t["url-link"]):s.then(()=>{$e.refresh(e.$container)})}).catch(i));return s},submitFormAndUpdateView:(e,t,n,r)=>{let s=new FormData(t);const o=e=>{e["url-link"]?A("onNavLink",e["url-link"]):window.location.href=e.url},i=new Promise((l,c)=>{a(s,n||t.action,r||t.method).then((t,n,r)=>{l(t,n,r),"redirect"===t.status?o(t):i.then(()=>{$e.refresh(e.$container,e)})}).catch((e,t,n)=>{301===e.status?(e=e.responseJSON,o(e),l(e,t,n)):c(e,t,n)})});return i},submitForm:(e,t,n)=>{let r=new FormData(e);return new Promise((s,o)=>{a(r,t||e.action,n||e.method).then(s).catch(o)})},getController:e=>G(e),safeEmpty:e=>(e.children().each(function(e,t){let n=$(t);$e.safeRemove(n)}),e),safeReplace:(e,t)=>(t.insertBefore(e),$e.safeRemove(e)),safeRemove:e=>(e.each(function(){let e=$(this);e.data(`${D}`)&&e.data(`${D}`).remove()}),e.find(`.${J}`).each(function(){const e=$(this).data(`${D}`);e&&e.remove()}),e.remove()),reloadController:e=>function(e){if(e.contentUrl){let t=W(e);return e.contentUrl=t.url,Q(e,t.args)}return new Promise(e=>{e($())})}(e).then(t=>{let n=$(t);return $e.reconcile(e,n)}),reconcile:(e,t,n=null,r=null)=>{if(!n){let n=e.$container.clone().empty();n.data(D,null),n.removeClass(J),n.append(t),t=n}n=n??e.$container;const{refreshProcess:s,isRunningProcess:o}=I(r,e);return ee(t,e,s).then(()=>{var r;return Y(t,n),(r=e)._childController={},r.find(`.${J}`).each(function(){const e=G($(this));e===r&&k(r,e)}),o||x(s),e})},refresh:(e,t=null)=>ee(e,t)},Re=[];function Ne(){if(!jest)throw new Error("JEST is not defined");0===Re.length&&(be=$.ajax.bind($),Re.push(jest.spyOn($,"ajax")),Re[0].mockImplementation(function(e){return be(e).then(e=>e).catch(e=>e)}))}const Ce=_e,Oe={get_controller:async function(e,t={},n=""){Ne();const r=$("body");$e.updateJquery(),r.safeEmpty();const s=$(`<${e}>${n}</${e}>`);for(const[e,n]of Object.entries(t))s.data(e,n);const o=$("<div></div>").append(s);return r.append(o),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc(),$e.getController(s)},getCsrfToken:function(){return function(e){if(document.cookie&&""!==document.cookie){const t=document.cookie.split(";");for(let n=0;n<t.length;n++){const r=t[n].trim();if(r.substring(0,10)===e+"=")return decodeURIComponent(r.substring(10))}}return""}("csrftoken")},controllerFromTestHtml:async function(e,t=null){Ne();const n=$("body");$e.updateJquery(),n.safeEmpty().append(e),$e._isInit=!1,$e.cleanCache(),await $e.init_sdc();let r=$e.rootController.iterateAllChildren();if(!t)return r;const s=r[0].onRefresh,o=jest.spyOn(r[0],"onRefresh");return new Promise(e=>{o.mockImplementation(function(){o.mockRestore();const t=s.apply(r[0],arguments);return e(r),t})})}};export{ve as AbstractSDC,ue as SdcModel,ce as SdcQuerySet,M as allOff,$e as app,u as checkIfParamNumberBoolOrString,h as clearErrorsInForm,F as controllerFactory,q as on,ne as registerModel,P as runControlFlowFunctions,f as setErrorsInForm,T as setEvent,Ce as socketReconnect,Oe as test_utils,A as trigger};
|
package/package.json
CHANGED
|
@@ -150,7 +150,7 @@ export class SdcQuerySet {
|
|
|
150
150
|
*/
|
|
151
151
|
setIds(ids) {
|
|
152
152
|
|
|
153
|
-
if (ids === null || Array.isArray(ids) && ids.length === 0) {
|
|
153
|
+
if (ids === null || ids === "" || Array.isArray(ids) && ids.length === 0) {
|
|
154
154
|
this.valuesList = [];
|
|
155
155
|
return this.valuesList;
|
|
156
156
|
} else if (ids instanceof SdcQuerySet) {
|
|
@@ -171,7 +171,7 @@ export class SdcQuerySet {
|
|
|
171
171
|
if (!tempNumList.some(Number.isNaN)) {
|
|
172
172
|
numList = tempNumList;
|
|
173
173
|
}
|
|
174
|
-
} else if (ids
|
|
174
|
+
} else if (typeof ids === "string") {
|
|
175
175
|
const tempNumList = ids.split(',').map((x) => parseInt(x));
|
|
176
176
|
if (!tempNumList.some(Number.isNaN)) {
|
|
177
177
|
numList = tempNumList
|
|
@@ -943,6 +943,9 @@ export class SdcQuerySet {
|
|
|
943
943
|
const newModels = []
|
|
944
944
|
for (const x of results) {
|
|
945
945
|
const ModelClass = getModel(this.modelName);
|
|
946
|
+
if(!ModelClass) {
|
|
947
|
+
throw new Error(`${this.modelName} is no SdcModel. mybe the models ar not importad.`);
|
|
948
|
+
}
|
|
946
949
|
const newModel = new ModelClass({'id': x.pk ?? x.id, ...x.fields});
|
|
947
950
|
const currentModel = this.byId(newModel.id);
|
|
948
951
|
if (currentModel) {
|
|
@@ -1221,7 +1224,7 @@ export default class SdcModel {
|
|
|
1221
1224
|
* @param {object} options
|
|
1222
1225
|
* @returns {*}
|
|
1223
1226
|
*/
|
|
1224
|
-
form({cbResolve = null, cbReject = null}) {
|
|
1227
|
+
form({cbResolve = null, cbReject = null} = {}) {
|
|
1225
1228
|
if (this.id === null || this.id === -1) {
|
|
1226
1229
|
return this._createForm({cbReject, cbResolve});
|
|
1227
1230
|
}
|
|
@@ -1420,7 +1423,7 @@ function validateField(value, config) {
|
|
|
1420
1423
|
}
|
|
1421
1424
|
}
|
|
1422
1425
|
|
|
1423
|
-
if (value === null || value === undefined) {
|
|
1426
|
+
if (value === null || value === undefined || value === "") {
|
|
1424
1427
|
return null;
|
|
1425
1428
|
}
|
|
1426
1429
|
|