Files
rspade_system/storage-working/rsx-tmp/babel_cache/370df409369e6f4acd1a7997b5f6932d_modern.js
root 9ebcc359ae Fix code quality violations and enhance ROUTE-EXISTS-01 rule
Implement JQHTML function cache ID system and fix bundle compilation
Implement underscore prefix for system tables
Fix JS syntax linter to support decorators and grant exception to Task system
SPA: Update planning docs and wishlists with remaining features
SPA: Document Navigation API abandonment and future enhancements
Implement SPA browser integration with History API (Phase 1)
Convert contacts view page to SPA action
Convert clients pages to SPA actions and document conversion procedure
SPA: Merge GET parameters and update documentation
Implement SPA route URL generation in JavaScript and PHP
Implement SPA bootstrap controller architecture
Add SPA routing manual page (rsx:man spa)
Add SPA routing documentation to CLAUDE.md
Phase 4 Complete: Client-side SPA routing implementation
Update get_routes() consumers for unified route structure
Complete SPA Phase 3: PHP-side route type detection and is_spa flag
Restore unified routes structure and Manifest_Query class
Refactor route indexing and add SPA infrastructure
Phase 3 Complete: SPA route registration in manifest
Implement SPA Phase 2: Extract router code and test decorators
Rename Jqhtml_Component to Component and complete SPA foundation setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 17:48:15 +00:00

191 lines
19 KiB
JavaScript
Executable File

"use strict";
// @FILE-SUBCLASS-01-EXCEPTION
/**
* Base class for JavaScript ORM models
*
* Provides core functionality for fetching records from backend PHP models.
* All model stubs generated by the manifest extend this base class.
*
* Example usage:
* // Fetch single record
* const user = await User_Model.fetch(123);
*
* // Fetch multiple records
* const users = await User_Model.fetch([1, 2, 3]);
*
* // Create instance with data
* const user = new User_Model({id: 1, name: 'John'});
*
* @Instantiatable
*/
class Rsx_Js_Model {
/**
* Constructor - Initialize model instance with data
*
* @param {Object} data - Key-value pairs to populate the model
*/
constructor() {
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
// This provides typed model objects instead of plain JSON, with methods and type checking.
// This constructor filters out the __MODEL marker that was used to identify which class
// to instantiate, keeping only the actual data properties on the instance.
const {
__MODEL,
...modelData
} = data;
Object.assign(this, modelData);
}
/**
* Fetch record(s) from the backend model
*
* This method mirrors the PHP Model::fetch() functionality.
* The backend model must have a fetch() method with the
* #[Ajax_Endpoint_Model_Fetch] annotation to be callable.
*
* @param {number|Array} id - Single ID or array of IDs to fetch
* @returns {Promise} - Single model instance, array of instances, or false
*/
static async fetch(id) {
const CurrentClass = this;
// Get the model class name from the current class
const modelName = CurrentClass.name;
const response = await $.ajax({
url: `/_fetch/${modelName}`,
method: 'POST',
data: {
id: id
},
dataType: 'json'
});
// Handle response based on type
if (response === false) {
return false;
}
// Use _instantiate_models_recursive to handle ORM instantiation
// This will automatically detect __MODEL properties and create appropriate instances
return Rsx_Js_Model._instantiate_models_recursive(response);
}
/**
* Get the model class name
* Used internally for API calls
*
* @returns {string} The class name
*/
static getModelName() {
const CurrentClass = this;
return CurrentClass.name;
}
/**
* Refresh this instance with latest data from server
*
* @returns {Promise} Updated instance or false if not found
*/
async refresh() {
const that = this;
if (!that.id) {
shouldnt_happen('Cannot refresh model without id property');
}
const fresh = await that.constructor.fetch(that.id);
if (fresh === false) {
return false;
}
// Update this instance with fresh data
Object.assign(that, fresh);
return that;
}
/**
* Convert model instance to plain object
* Useful for serialization or sending to APIs
*
* @returns {Object} Plain object representation
*/
toObject() {
const that = this;
const obj = {};
for (const key in that) {
if (that.hasOwnProperty(key) && typeof that[key] !== 'function') {
obj[key] = that[key];
}
}
return obj;
}
/**
* Convert model instance to JSON string
*
* @returns {string} JSON representation
*/
toJSON() {
const that = this;
return JSON.stringify(that.toObject());
}
/**
* Recursively instantiate ORM models in response data
*
* Looks for objects with __MODEL property and instantiates the appropriate
* JavaScript model class if it exists in the global scope.
*
* @param {*} data - The data to process (can be any type)
* @returns {*} The data with ORM objects instantiated
*/
static _instantiate_models_recursive(data) {
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
// This provides typed model objects instead of plain JSON, with methods and type checking.
// This recursive processor scans all API response data looking for __MODEL markers.
// When found, it attempts to instantiate the appropriate JavaScript model class,
// converting {__MODEL: "User_Model", id: 1, name: "John"} into new User_Model({...}).
// Works recursively through arrays and nested objects to handle complex data structures.
// Handle null/undefined
if (data === null || data === undefined) {
return data;
}
// Handle arrays - recursively process each element
if (Array.isArray(data)) {
return data.map(item => Rsx_Js_Model._instantiate_models_recursive(item));
}
// Handle objects
if (typeof data === 'object') {
// Check if this object has a __MODEL property
if (data.__MODEL && typeof data.__MODEL === 'string') {
// Try to find the model class in the global scope
const ModelClass = window[data.__MODEL];
// If the model class exists and extends Rsx_Js_Model, instantiate it
// Dynamic model resolution requires checking class existence - @JS-DEFENSIVE-01-EXCEPTION
if (ModelClass && ModelClass.prototype instanceof Rsx_Js_Model) {
return new ModelClass(data);
}
}
// Recursively process all object properties
const result = {};
for (const key in data) {
if (data.hasOwnProperty(key)) {
result[key] = Rsx_Js_Model._instantiate_models_recursive(data[key]);
}
}
return result;
}
// Return primitive values as-is
return data;
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfSnNfTW9kZWwiLCJjb25zdHJ1Y3RvciIsImRhdGEiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJfX01PREVMIiwibW9kZWxEYXRhIiwiT2JqZWN0IiwiYXNzaWduIiwiZmV0Y2giLCJpZCIsIkN1cnJlbnRDbGFzcyIsIm1vZGVsTmFtZSIsIm5hbWUiLCJyZXNwb25zZSIsIiQiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YVR5cGUiLCJfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSIsImdldE1vZGVsTmFtZSIsInJlZnJlc2giLCJ0aGF0Iiwic2hvdWxkbnRfaGFwcGVuIiwiZnJlc2giLCJ0b09iamVjdCIsIm9iaiIsImtleSIsImhhc093blByb3BlcnR5IiwidG9KU09OIiwiSlNPTiIsInN0cmluZ2lmeSIsIkFycmF5IiwiaXNBcnJheSIsIm1hcCIsIml0ZW0iLCJNb2RlbENsYXNzIiwid2luZG93IiwicHJvdG90eXBlIiwicmVzdWx0Il0sInNvdXJjZXMiOlsiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9Kc19Nb2RlbC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBARklMRS1TVUJDTEFTUy0wMS1FWENFUFRJT05cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBKYXZhU2NyaXB0IE9STSBtb2RlbHNcbiAqXG4gKiBQcm92aWRlcyBjb3JlIGZ1bmN0aW9uYWxpdHkgZm9yIGZldGNoaW5nIHJlY29yZHMgZnJvbSBiYWNrZW5kIFBIUCBtb2RlbHMuXG4gKiBBbGwgbW9kZWwgc3R1YnMgZ2VuZXJhdGVkIGJ5IHRoZSBtYW5pZmVzdCBleHRlbmQgdGhpcyBiYXNlIGNsYXNzLlxuICpcbiAqIEV4YW1wbGUgdXNhZ2U6XG4gKiAgIC8vIEZldGNoIHNpbmdsZSByZWNvcmRcbiAqICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXJfTW9kZWwuZmV0Y2goMTIzKTtcbiAqXG4gKiAgIC8vIEZldGNoIG11bHRpcGxlIHJlY29yZHNcbiAqICAgY29uc3QgdXNlcnMgPSBhd2FpdCBVc2VyX01vZGVsLmZldGNoKFsxLCAyLCAzXSk7XG4gKlxuICogICAvLyBDcmVhdGUgaW5zdGFuY2Ugd2l0aCBkYXRhXG4gKiAgIGNvbnN0IHVzZXIgPSBuZXcgVXNlcl9Nb2RlbCh7aWQ6IDEsIG5hbWU6ICdKb2huJ30pO1xuICpcbiAqICBASW5zdGFudGlhdGFibGVcbiAqL1xuY2xhc3MgUnN4X0pzX01vZGVsIHtcbiAgICAvKipcbiAgICAgKiBDb25zdHJ1Y3RvciAtIEluaXRpYWxpemUgbW9kZWwgaW5zdGFuY2Ugd2l0aCBkYXRhXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YSAtIEtleS12YWx1ZSBwYWlycyB0byBwb3B1bGF0ZSB0aGUgbW9kZWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihkYXRhID0ge30pIHtcbiAgICAgICAgLy8gX19NT0RFTCBTWVNURU06IEVuYWJsZXMgYXV0b21hdGljIE9STSBpbnN0YW50aWF0aW9uIHdoZW4gZmV0Y2hpbmcgZnJvbSBQSFAgbW9kZWxzLlxuICAgICAgICAvLyBQSFAgbW9kZWxzIGFkZCBcIl9fTU9ERUxcIjogXCJDbGFzc05hbWVcIiB0byBKU09OLCBKYXZhU2NyaXB0IHVzZXMgaXQgdG8gY3JlYXRlIHByb3BlciBpbnN0YW5jZXMuXG4gICAgICAgIC8vIFRoaXMgcHJvdmlkZXMgdHlwZWQgbW9kZWwgb2JqZWN0cyBpbnN0ZWFkIG9mIHBsYWluIEpTT04sIHdpdGggbWV0aG9kcyBhbmQgdHlwZSBjaGVja2luZy5cblxuICAgICAgICAvLyBUaGlzIGNvbnN0cnVjdG9yIGZpbHRlcnMgb3V0IHRoZSBfX01PREVMIG1hcmtlciB0aGF0IHdhcyB1c2VkIHRvIGlkZW50aWZ5IHdoaWNoIGNsYXNzXG4gICAgICAgIC8vIHRvIGluc3RhbnRpYXRlLCBrZWVwaW5nIG9ubHkgdGhlIGFjdHVhbCBkYXRhIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlLlxuICAgICAgICBjb25zdCB7IF9fTU9ERUwsIC4uLm1vZGVsRGF0YSB9ID0gZGF0YTtcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBtb2RlbERhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIHJlY29yZChzKSBmcm9tIHRoZSBiYWNrZW5kIG1vZGVsXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBtaXJyb3JzIHRoZSBQSFAgTW9kZWw6OmZldGNoKCkgZnVuY3Rpb25hbGl0eS5cbiAgICAgKiBUaGUgYmFja2VuZCBtb2RlbCBtdXN0IGhhdmUgYSBmZXRjaCgpIG1ldGhvZCB3aXRoIHRoZVxuICAgICAqICNbQWpheF9FbmRwb2ludF9Nb2RlbF9GZXRjaF0gYW5ub3RhdGlvbiB0byBiZSBjYWxsYWJsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfEFycmF5fSBpZCAtIFNpbmdsZSBJRCBvciBhcnJheSBvZiBJRHMgdG8gZmV0Y2hcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gLSBTaW5nbGUgbW9kZWwgaW5zdGFuY2UsIGFycmF5IG9mIGluc3RhbmNlcywgb3IgZmFsc2VcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZmV0Y2goaWQpIHtcbiAgICAgICAgY29uc3QgQ3VycmVudENsYXNzID0gdGhpcztcbiAgICAgICAgLy8gR2V0IHRoZSBtb2RlbCBjbGFzcyBuYW1lIGZyb20gdGhlIGN1cnJlbnQgY2xhc3NcbiAgICAgICAgY29uc3QgbW9kZWxOYW1lID0gQ3VycmVudENsYXNzLm5hbWU7XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBgL19mZXRjaC8ke21vZGVsTmFtZX1gLFxuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiB7IGlkOiBpZCB9LFxuICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIHJlc3BvbnNlIGJhc2VkIG9uIHR5cGVcbiAgICAgICAgaWYgKHJlc3BvbnNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXNlIF9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlIHRvIGhhbmRsZSBPUk0gaW5zdGFudGlhdGlvblxuICAgICAgICAvLyBUaGlzIHdpbGwgYXV0b21hdGljYWxseSBkZXRlY3QgX19NT0RFTCBwcm9wZXJ0aWVzIGFuZCBjcmVhdGUgYXBwcm9wcmlhdGUgaW5zdGFuY2VzXG4gICAgICAgIHJldHVybiBSc3hfSnNfTW9kZWwuX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUocmVzcG9uc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbW9kZWwgY2xhc3MgbmFtZVxuICAgICAqIFVzZWQgaW50ZXJuYWxseSBmb3IgQVBJIGNhbGxzXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY2xhc3MgbmFtZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRNb2RlbE5hbWUoKSB7XG4gICAgICAgIGNvbnN0IEN1cnJlbnRDbGFzcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBDdXJyZW50Q2xhc3MubmFtZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWZyZXNoIHRoaXMgaW5zdGFuY2Ugd2l0aCBsYXRlc3QgZGF0YSBmcm9tIHNlcnZlclxuICAgICAqXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFVwZGF0ZWQgaW5zdGFuY2Ugb3IgZmFsc2UgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgYXN5bmMgcmVmcmVzaCgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIGlmICghdGhhdC5pZCkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKCdDYW5ub3QgcmVmcmVzaCBtb2RlbCB3aXRob3V0IGlkIHByb3BlcnR5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmcmVzaCA9IGF3YWl0IHRoYXQuY29uc3RydWN0b3IuZmV0Y2godGhhdC5pZCk7XG5cbiAgICAgICAgaWYgKGZyZXNoID09PSBmYWxzZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIHRoaXMgaW5zdGFuY2Ugd2l0aCBmcmVzaCBkYXRhXG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhhdCwgZnJlc2gpO1xuICAgICAgICByZXR1cm4gdGhhdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IG1vZGVsIGluc3RhbmNlIHRvIHBsYWluIG9iamVjdFxuICAgICAqIFVzZWZ1bCBmb3Igc2VyaWFsaXphdGlvbiBvciBzZW5kaW5nIHRvIEFQSXNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFBsYWluIG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgICAqL1xuICAgIHRvT2JqZWN0KCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgY29uc3Qgb2JqID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoYXQpIHtcbiAgICAgICAgICAgIGlmICh0aGF0Lmhhc093blByb3BlcnR5KGtleSkgJiYgdHlwZW9mIHRoYXRba2V5XSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIG9ialtrZXldID0gdGhhdFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydCBtb2RlbCBpbnN0YW5jZSB0byBKU09OIHN0cmluZ1xuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gSlNPTiByZXByZXNlbnRhdGlvblxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGF0LnRvT2JqZWN0KCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGluc3RhbnRpYXRlIE9STSBtb2RlbHMgaW4gcmVzcG9uc2UgZGF0YVxuICAgICAqXG4gICAgICogTG9va3MgZm9yIG9iamVjdHMgd2l0aCBfX01PREVMIHByb3BlcnR5IGFuZCBpbnN0YW50aWF0ZXMgdGhlIGFwcHJvcHJpYXRlXG4gICAgICogSmF2YVNjcmlwdCBtb2RlbCBjbGFzcyBpZiBpdCBleGlzdHMgaW4gdGhlIGdsb2JhbCBzY29wZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gZGF0YSAtIFRoZSBkYXRhIHRvIHByb2Nlc3MgKGNhbiBiZSBhbnkgdHlwZSlcbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGRhdGEgd2l0aCBPUk0gb2JqZWN0cyBpbnN0YW50aWF0ZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUoZGF0YSkge1xuICAgICAgICAvLyBfX01PREVMIFNZU1RFTTogRW5hYmxlcyBhdXRvbWF0aWMgT1JNIGluc3RhbnRpYXRpb24gd2hlbiBmZXRjaGluZyBmcm9tIFBIUCBtb2RlbHMuXG4gICAgICAgIC8vIFBIUCBtb2RlbHMgYWRkIFwiX19NT0RFTFwiOiBcIkNsYXNzTmFtZVwiIHRvIEpTT04sIEphdmFTY3JpcHQgdXNlcyBpdCB0byBjcmVhdGUgcHJvcGVyIGluc3RhbmNlcy5cbiAgICAgICAgLy8gVGhpcyBwcm92aWRlcyB0eXBlZCBtb2RlbCBvYmplY3RzIGluc3RlYWQgb2YgcGxhaW4gSlNPTiwgd2l0aCBtZXRob2RzIGFuZCB0eXBlIGNoZWNraW5nLlxuXG4gICAgICAgIC8vIFRoaXMgcmVjdXJzaXZlIHByb2Nlc3NvciBzY2FucyBhbGwgQVBJIHJlc3BvbnNlIGRhdGEgbG9va2luZyBmb3IgX19NT0RFTCBtYXJrZXJzLlxuICAgICAgICAvLyBXaGVuIGZvdW5kLCBpdCBhdHRlbXB0cyB0byBpbnN0YW50aWF0ZSB0aGUgYXBwcm9wcmlhdGUgSmF2YVNjcmlwdCBtb2RlbCBjbGFzcyxcbiAgICAgICAgLy8gY29udmVydGluZyB7X19NT0RFTDogXCJVc2VyX01vZGVsXCIsIGlkOiAxLCBuYW1lOiBcIkpvaG5cIn0gaW50byBuZXcgVXNlcl9Nb2RlbCh7Li4ufSkuXG4gICAgICAgIC8vIFdvcmtzIHJlY3Vyc2l2ZWx5IHRocm91Z2ggYXJyYXlzIGFuZCBuZXN0ZWQgb2JqZWN0cyB0byBoYW5kbGUgY29tcGxleCBkYXRhIHN0cnVjdHVyZXMuXG4gICAgICAgIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZFxuICAgICAgICBpZiAoZGF0YSA9PT0gbnVsbCB8fCBkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGFycmF5cyAtIHJlY3Vyc2l2ZWx5IHByb2Nlc3MgZWFjaCBlbGVtZW50XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YS5tYXAoKGl0ZW0pID0+IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShpdGVtKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgb2JqZWN0c1xuICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIG9iamVjdCBoYXMgYSBfX01PREVMIHByb3BlcnR5XG4gICAgICAgICAgICBpZiAoZGF0YS5fX01PREVMICYmIHR5cGVvZiBkYXRhLl9fTU9ERUwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IHRvIGZpbmQgdGhlIG1vZGVsIGNsYXNzIGluIHRoZSBnbG9iYWwgc2NvcGVcbiAgICAgICAgICAgICAgICBjb25zdCBNb2RlbENsYXNzID0gd2luZG93W2RhdGEuX19NT0RFTF07XG5cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgY2xhc3MgZXhpc3RzIGFuZCBleHRlbmRzIFJzeF9Kc19Nb2RlbCwgaW5zdGFudGlhdGUgaXRcbiAgICAgICAgICAgICAgICAvLyBEeW5hbWljIG1vZGVsIHJlc29sdXRpb24gcmVxdWlyZXMgY2hlY2tpbmcgY2xhc3MgZXhpc3RlbmNlIC0gQEpTLURFRkVOU0lWRS0wMS1FWENFUFRJT05cbiAgICAgICAgICAgICAgICBpZiAoTW9kZWxDbGFzcyAmJiBNb2RlbENsYXNzLnByb3RvdHlwZSBpbnN0YW5jZW9mIFJzeF9Kc19Nb2RlbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1vZGVsQ2xhc3MoZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIGFsbCBvYmplY3QgcHJvcGVydGllc1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRba2V5XSA9IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShkYXRhW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gcHJpbWl0aXZlIHZhbHVlcyBhcy1pc1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsWUFBWSxDQUFDO0VBQ2Y7QUFDSjtB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