Files
rspade_system/storage-broken/rsx-tmp/babel_cache/c18e9930b0b47704493d6efaa669ebdf_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

201 lines
24 KiB
JavaScript
Executable File

"use strict";
/**
* Rsx_Form
*
* Form container with validation, submission, and widget value management.
* See rsx_form.jqhtml for full documentation.
*
* JavaScript Responsibilities:
* - Parses and stores initial form data from $data attribute (JSON or object)
* - Discovers and manages child Widget components via vals() getter/setter
* - Handles form submission via Ajax to controller/method endpoints
* - Applies validation errors to fields using Form_Utils
* - Integrates with Rsx_Tabs for tab-aware error handling
* - Provides seed() functionality for debug/testing
* - Manages form state (values, errors) throughout lifecycle
*/
class Rsx_Form extends Component {
on_create() {
this.data.values = {}; // Current form values {name: value}
this.data.errors = {}; // Validation errors {name: error_message}
this.tabs = null; // Reference to Rsx_Tabs component if present
// Parse initial data from $data attribute (e.g., from $data=$client)
let data = this.args.data;
if (typeof data === 'string') {
try {
// Decode HTML entities before parsing JSON
// This handles cases where JSON is passed through Blade {!! !!} syntax
const decoded = $('<textarea>').html(data).text();
data = json_decode(decoded);
} catch (e) {
console.error('Form: Failed to parse data JSON string', e);
data = {};
}
}
if (data && typeof data === 'object') {
this.data.values = data;
}
}
on_ready() {
const that = this;
// Validate that error container exists
if (!this.$id('error').exists()) {
console.log(this.$.html());
throw new Error('Rsx_Form requires an error container with $id="error". ' + 'Add <div $id="error"></div> to your form template for displaying validation and error messages.');
}
// Set up seed button handler if in debug mode
if (window.rsxapp.debug && this.$id('seed_btn').exists()) {
that.$id('seed_btn').on('click', function () {
that.seed();
});
}
// Find child Rsx_Tabs component if present for error handling integration
const tabs_el = this.$.find('.Rsx_Tabs').first();
if (tabs_el.length) {
that.tabs = tabs_el.component();
}
// Automatically wire all submit buttons to call form submit()
this.$.find('button[type="submit"]').each(function () {
$(this).on('click', function (e) {
e.preventDefault();
that.submit();
});
});
// Notify all fields to load their initial values
// This happens in on_ready to ensure all Form_Field children are initialized
this.vals(this.data.values);
// Hide loading spinner and show form content (without re-rendering)
this.$id('loader').hide();
this.$id('form_content').show();
}
// Getter or setter for all form values, similar to jquery val
vals(values) {
if (values) {
// Setter
this.$.shallowFind('.Widget').each(function () {
let $widget = $(this);
let component = $widget.component();
if (component && 'val' in component) {
let widget_name = $widget.data('name');
if (widget_name in values) {
component.val(values[widget_name]);
}
}
});
return null;
} else {
// Getter
let data = {};
// Get widget values
this.$.shallowFind('.Widget').each(function () {
let $widget = $(this);
let component = $widget.component();
if (component && 'val' in component) {
let widget_name = $widget.data('name');
data[widget_name] = component.val();
}
});
// Also get regular hidden inputs (non-widget inputs)
this.$.find('input[type="hidden"][name]').each(function () {
let $input = $(this);
let name = $input.attr('name');
if (name) {
data[name] = $input.val();
}
});
return data;
}
}
get_error(name) {
return this.data.errors[name];
}
/**
* Render an error in the form's error container
*
* Handles both field-specific validation errors and generic errors.
* Can be called by external handlers (e.g., modal on_submit) or internally
* by the form's own submit() method.
*
* @param {Error|Object} error - Error object from Ajax call
*/
async render_error(error) {
// Handle validation errors - apply to fields
if (error.type === 'form_error' && error.details) {
await Form_Utils.apply_form_errors(this.$, error.details);
// Notify tabs of validation errors for error badges and auto-switching
if (this.tabs) {
this.tabs.handle_validation_errors(error.details);
}
// Form_Utils handles all rendering (inline errors + unmatched errors alert)
// Don't call Rsx.render_error() to avoid duplicate alerts
return;
}
// For non-form errors (fatal, auth, network, etc.), render in form's error container
Rsx.render_error(error, this.$id('error'));
}
async submit() {
// Clear any previous errors
Form_Utils.reset_form_errors(this.$);
this.$id('error').empty();
// Clear tab error badges if tabs are present
if (this.tabs) {
this.tabs.clear_error_badges();
}
// Serialize all field values
let values = this.vals();
// Call submit handler
if (!this.args.controller || !this.args.method) {
console.error('Form: No controller/method provided');
throw new Error('Form configuration error: Missing controller or method');
}
try {
// Build Ajax URL from controller and method
const ajax_url = `/_ajax/${this.args.controller}/${this.args.method}`;
// Call Ajax endpoint - response is directly what PHP returned
const result = await Ajax.call(ajax_url, values);
// Success! Handle result
if (result && result.redirect) {
// Redirect to URL
window.location.href = result.redirect;
} else {
// Success without redirect
console.log('Form submitted successfully', result);
}
} catch (error) {
// Render error (handles both validation and generic errors)
await this.render_error(error);
}
}
async seed() {
const promises = [];
this.$.shallowFind('.Form_Field').each(function () {
let component = $(this).component();
if (component && 'seed' in component) {
promises.push(component.seed());
}
});
await Promise.all(promises);
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfRm9ybSIsIkpxaHRtbF9Db21wb25lbnQiLCJvbl9jcmVhdGUiLCJkYXRhIiwidmFsdWVzIiwiZXJyb3JzIiwidGFicyIsImFyZ3MiLCJkZWNvZGVkIiwiJCIsImh0bWwiLCJ0ZXh0IiwianNvbl9kZWNvZGUiLCJlIiwiY29uc29sZSIsImVycm9yIiwib25fcmVhZHkiLCJ0aGF0IiwiJGlkIiwiZXhpc3RzIiwibG9nIiwiRXJyb3IiLCJ3aW5kb3ciLCJyc3hhcHAiLCJkZWJ1ZyIsIm9uIiwic2VlZCIsInRhYnNfZWwiLCJmaW5kIiwiZmlyc3QiLCJsZW5ndGgiLCJjb21wb25lbnQiLCJlYWNoIiwicHJldmVudERlZmF1bHQiLCJzdWJtaXQiLCJ2YWxzIiwiaGlkZSIsInNob3ciLCJzaGFsbG93RmluZCIsIiR3aWRnZXQiLCJ3aWRnZXRfbmFtZSIsInZhbCIsIiRpbnB1dCIsIm5hbWUiLCJhdHRyIiwiZ2V0X2Vycm9yIiwicmVuZGVyX2Vycm9yIiwidHlwZSIsImRldGFpbHMiLCJGb3JtX1V0aWxzIiwiYXBwbHlfZm9ybV9lcnJvcnMiLCJoYW5kbGVfdmFsaWRhdGlvbl9lcnJvcnMiLCJSc3giLCJyZXNldF9mb3JtX2Vycm9ycyIsImVtcHR5IiwiY2xlYXJfZXJyb3JfYmFkZ2VzIiwiY29udHJvbGxlciIsIm1ldGhvZCIsImFqYXhfdXJsIiwicmVzdWx0IiwiQWpheCIsImNhbGwiLCJyZWRpcmVjdCIsImxvY2F0aW9uIiwiaHJlZiIsInByb21pc2VzIiwicHVzaCIsIlByb21pc2UiLCJhbGwiXSwic291cmNlcyI6WyJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9yc3hfZm9ybS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJzeF9Gb3JtXG4gKlxuICogRm9ybSBjb250YWluZXIgd2l0aCB2YWxpZGF0aW9uLCBzdWJtaXNzaW9uLCBhbmQgd2lkZ2V0IHZhbHVlIG1hbmFnZW1lbnQuXG4gKiBTZWUgcnN4X2Zvcm0uanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBQYXJzZXMgYW5kIHN0b3JlcyBpbml0aWFsIGZvcm0gZGF0YSBmcm9tICRkYXRhIGF0dHJpYnV0ZSAoSlNPTiBvciBvYmplY3QpXG4gKiAtIERpc2NvdmVycyBhbmQgbWFuYWdlcyBjaGlsZCBXaWRnZXQgY29tcG9uZW50cyB2aWEgdmFscygpIGdldHRlci9zZXR0ZXJcbiAqIC0gSGFuZGxlcyBmb3JtIHN1Ym1pc3Npb24gdmlhIEFqYXggdG8gY29udHJvbGxlci9tZXRob2QgZW5kcG9pbnRzXG4gKiAtIEFwcGxpZXMgdmFsaWRhdGlvbiBlcnJvcnMgdG8gZmllbGRzIHVzaW5nIEZvcm1fVXRpbHNcbiAqIC0gSW50ZWdyYXRlcyB3aXRoIFJzeF9UYWJzIGZvciB0YWItYXdhcmUgZXJyb3IgaGFuZGxpbmdcbiAqIC0gUHJvdmlkZXMgc2VlZCgpIGZ1bmN0aW9uYWxpdHkgZm9yIGRlYnVnL3Rlc3RpbmdcbiAqIC0gTWFuYWdlcyBmb3JtIHN0YXRlICh2YWx1ZXMsIGVycm9ycykgdGhyb3VnaG91dCBsaWZlY3ljbGVcbiAqL1xuY2xhc3MgUnN4X0Zvcm0gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHRoaXMuZGF0YS52YWx1ZXMgPSB7fTsgLy8gQ3VycmVudCBmb3JtIHZhbHVlcyB7bmFtZTogdmFsdWV9XG4gICAgICAgIHRoaXMuZGF0YS5lcnJvcnMgPSB7fTsgLy8gVmFsaWRhdGlvbiBlcnJvcnMge25hbWU6IGVycm9yX21lc3NhZ2V9XG4gICAgICAgIHRoaXMudGFicyA9IG51bGw7IC8vIFJlZmVyZW5jZSB0byBSc3hfVGFicyBjb21wb25lbnQgaWYgcHJlc2VudFxuXG4gICAgICAgIC8vIFBhcnNlIGluaXRpYWwgZGF0YSBmcm9tICRkYXRhIGF0dHJpYnV0ZSAoZS5nLiwgZnJvbSAkZGF0YT0kY2xpZW50KVxuICAgICAgICBsZXQgZGF0YSA9IHRoaXMuYXJncy5kYXRhO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gRGVjb2RlIEhUTUwgZW50aXRpZXMgYmVmb3JlIHBhcnNpbmcgSlNPTlxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaGFuZGxlcyBjYXNlcyB3aGVyZSBKU09OIGlzIHBhc3NlZCB0aHJvdWdoIEJsYWRlIHshISAhIX0gc3ludGF4XG4gICAgICAgICAgICAgICAgY29uc3QgZGVjb2RlZCA9ICQoJzx0ZXh0YXJlYT4nKS5odG1sKGRhdGEpLnRleHQoKTtcbiAgICAgICAgICAgICAgICBkYXRhID0ganNvbl9kZWNvZGUoZGVjb2RlZCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRm9ybTogRmFpbGVkIHRvIHBhcnNlIGRhdGEgSlNPTiBzdHJpbmcnLCBlKTtcbiAgICAgICAgICAgICAgICBkYXRhID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGF0YSAmJiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZXMgPSBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIHRoYXQgZXJyb3IgY29udGFpbmVyIGV4aXN0c1xuICAgICAgICBpZiAoIXRoaXMuJGlkKCdlcnJvcicpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLiQuaHRtbCgpKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnUnN4X0Zvcm0gcmVxdWlyZXMgYW4gZXJyb3IgY29udGFpbmVyIHdpdGggJGlkPVwiZXJyb3JcIi4gJyArXG4gICAgICAgICAgICAgICAgICAgICdBZGQgPGRpdiAkaWQ9XCJlcnJvclwiPjwvZGl2PiB0byB5b3VyIGZvcm0gdGVtcGxhdGUgZm9yIGRpc3BsYXlpbmcgdmFsaWRhdGlvbiBhbmQgZXJyb3IgbWVzc2FnZXMuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB1cCBzZWVkIGJ1dHRvbiBoYW5kbGVyIGlmIGluIGRlYnVnIG1vZGVcbiAgICAgICAgaWYgKHdpbmRvdy5yc3hhcHAuZGVidWcgJiYgdGhpcy4kaWQoJ3NlZWRfYnRuJykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIHRoYXQuJGlkKCdzZWVkX2J0bicpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGF0LnNlZWQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluZCBjaGlsZCBSc3hfVGFicyBjb21wb25lbnQgaWYgcHJlc2VudCBmb3IgZXJyb3IgaGFuZGxpbmcgaW50ZWdyYXRpb25cbiAgICAgICAgY29uc3QgdGFic19lbCA9IHRoaXMuJC5maW5kKCcuUnN4X1RhYnMnKS5maXJzdCgpO1xuICAgICAgICBpZiAodGFic19lbC5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoYXQudGFicyA9IHRhYnNfZWwuY29tcG9uZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IHdpcmUgYWxsIHN1Ym1pdCBidXR0b25zIHRvIGNhbGwgZm9ybSBzdWJtaXQoKVxuICAgICAgICB0aGlzLiQuZmluZCgnYnV0dG9uW3R5cGU9XCJzdWJtaXRcIl0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICQodGhpcykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhhdC5zdWJtaXQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBOb3RpZnkgYWxsIGZpZWxkcyB0byBsb2FkIHRoZWlyIGluaXRpYWwgdmFsdWVzXG4gICAgICAgIC8vIFRoaXMgaGFwcGVucyBpbiBvbl9yZWFkeSB0byBlbnN1cmUgYWxsIEZvcm1fRmllbGQgY2hpbGRyZW4gYXJlIGluaXRpYWxpemVkXG4gICAgICAgIHRoaXMudmFscyh0aGlzLmRhdGEudmFsdWVzKTtcblxuICAgICAgICAvLyBIaWRlIGxvYWRpbmcgc3Bpbm5lciBhbmQgc2hvdyBmb3JtIGNvbnRlbnQgKHdpdGhvdXQgcmUtcmVuZGVyaW5nKVxuICAgICAgICB0aGlzLiRpZCgnbG9hZGVyJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgnZm9ybV9jb250ZW50Jykuc2hvdygpO1xuICAgIH1cblxuICAgIC8vIEdldHRlciBvciBzZXR0ZXIgZm9yIGFsbCBmb3JtIHZhbHVlcywgc2ltaWxhciB0byBqcXVlcnkgdmFsXG4gICAgdmFscyh2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG5cbiAgICAgICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLldpZGdldCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkd2lkZ2V0ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJHdpZGdldC5jb21wb25lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50ICYmICd2YWwnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgd2lkZ2V0X25hbWUgPSAkd2lkZ2V0LmRhdGEoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpZGdldF9uYW1lIGluIHZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50LnZhbCh2YWx1ZXNbd2lkZ2V0X25hbWVdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgbGV0IGRhdGEgPSB7fTtcblxuICAgICAgICAgICAgLy8gR2V0IHdpZGdldCB2YWx1ZXNcbiAgICAgICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLldpZGdldCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkd2lkZ2V0ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJHdpZGdldC5jb21wb25lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50ICYmICd2YWwnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgd2lkZ2V0X25hbWUgPSAkd2lkZ2V0LmRhdGEoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVt3aWRnZXRfbmFtZV0gPSBjb21wb25lbnQudmFsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEFsc28gZ2V0IHJlZ3VsYXIgaGlkZGVuIGlucHV0cyAobm9uLXdpZGdldCBpbnB1dHMpXG4gICAgICAgICAgICB0aGlzLiQuZmluZCgnaW5wdXRbdHlwZT1cImhpZGRlblwiXVtuYW1lXScpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkaW5wdXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBuYW1lID0gJGlucHV0LmF0dHIoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhW25hbWVdID0gJGlucHV0LnZhbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9lcnJvcihuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZXJyb3JzW25hbWVdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbmRlciBhbiBlcnJvciBpbiB0aGUgZm9ybSdzIGVycm9yIGNvbnRhaW5lclxuICAgICAqXG4gICAgICogSGFuZGxlcyBib3RoIGZpZWxkLXNwZWNpZmljIHZhbGlkYXRpb24gZXJyb3JzIGFuZCBnZW5lcmljIGVycm9ycy5cbiAgICAgKiBDYW4gYmUgY2FsbGVkIGJ5IGV4dGVybmFsIGhhbmRsZXJzIChlLmcuLCBtb2RhbCBvbl9zdWJtaXQpIG9yIGludGVybmFsbHlcbiAgICAgKiBieSB0aGUgZm9ybSdzIG93biBzdWJtaXQoKSBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfE9iamVjdH0gZXJyb3IgLSBFcnJvciBvYmplY3QgZnJvbSBBamF4IGNhbGxcbiAgICAgKi9cbiAgICBhc3luYyByZW5kZXJfZXJyb3IoZXJyb3IpIHtcbiAgICAgICAgLy8gSGFuZGxlIHZhbGlkYXRpb24gZXJyb3JzIC0gYXBwbHkgdG8gZmllbGRzXG4gICAgICAgIGlmIChlcnJvci50eXBlID09PSAnZm9ybV9lcnJvcicgJiYgZXJyb3IuZGV0YWlscykge1xuICAgICAgICAgICAgYXdhaXQgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyh0aGlzLiQsIGVycm9yLmRldGFpbHMpO1xuXG4gICAgICAgICAgICAvLyBOb3RpZnkgdGFicyBvZiB2YWxpZGF0aW9uIGVycm9ycyBmb3IgZXJyb3IgYmFkZ2VzIGFuZCBhdXRvLXN3aXRjaGluZ1xuICAgICAgICAgICAgaWYgKHRoaXMudGFicykge1xuICAgICAgICAgICAgICAgIHRoaXMudGFicy5oYW5kbGVfdmFsaWRhdGlvbl9lcnJvcnMoZXJyb3IuZGV0YWlscyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEZvcm1fVXRpbHMgaGFuZGxlcyBhbGwgcmVuZGVyaW5nIChpbmxpbmUgZXJyb3JzICsgdW5tYXRjaGVkIGVycm9ycyBhbGVydClcbiAgICAgICAgICAgIC8vIERvbid0IGNhbGwgUnN4LnJlbmRlcl9lcnJvcigpIHRvIGF2b2lkIGR1cGxpY2F0ZSBhbGVydHNcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvciBub24tZm9ybSBlcnJvcnMgKGZhdGFsLCBhdXRoLCBuZXR3b3JrLCBldGMuKSwgcmVuZGVyIGluIGZvcm0ncyBlcnJvciBjb250YWluZXJcbiAgICAgICAgUnN4LnJlbmRlcl9lcnJvcihlcnJvciwgdGhpcy4kaWQoJ2Vycm9yJykpO1xuICAgIH1cblxuICAgIGFzeW5jIHN1Ym1pdCgpIHtcbiAgICAgICAgLy8gQ2xlYXIgYW55IHByZXZpb3VzIGVycm9yc1xuICAgICAgICBGb3JtX1V0aWxzLnJlc2V0X2Zvcm1fZXJyb3JzKHRoaXMuJCk7XG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcicpLmVtcHR5KCk7XG5cbiAgICAgICAgLy8gQ2xlYXIgdGFiIGVycm9yIGJhZGdlcyBpZiB0YWJzIGFyZSBwcmVzZW50XG4gICAgICAgIGlmICh0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIHRoaXMudGFicy5jbGVhcl9lcnJvcl9iYWRnZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlcmlhbGl6ZSBhbGwgZmllbGQgdmFsdWVzXG4gICAgICAgIGxldCB2YWx1ZXMgPSB0aGlzLnZhbHMoKTtcblxuICAgICAgICAvLyBDYWxsIHN1Ym1pdCBoYW5kbGVyXG4gICAgICAgIGlmICghdGhpcy5hcmdzLmNvbnRyb2xsZXIgfHwgIXRoaXMuYXJncy5tZXRob2QpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Zvcm06IE5vIGNvbnRyb2xsZXIvbWV0aG9kIHByb3ZpZGVkJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Zvcm0gY29uZmlndXJhdGlvbiBlcnJvcjogTWlzc2luZyBjb250cm9sbGVyIG9yIG1ldGhvZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEJ1aWxkIEFqYXggVVJMIGZyb20gY29udHJvbGxlciBhbmQgbWV0aG9kXG4gICAgICAgICAgICBjb25zdCBhamF4X3VybCA9IGAvX2FqYXgvJHt0aGlzLmFyZ3MuY29udHJvbGxlcn0vJHt0aGlzLmFyZ3MubWV0aG9kfWA7XG5cbiAgICAgICAgICAgIC8vIENhbGwgQWpheCBlbmRwb2ludCAtIHJlc3BvbnNlIGlzIGRpcmVjdGx5IHdoYXQgUEhQIHJldHVybmVkXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBBamF4LmNhbGwoYWpheF91cmwsIHZhbHVlcyk7XG5cbiAgICAgICAgICAgIC8vIFN1Y2Nlc3MhIEhhbmRsZSByZXN1bHRcbiAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LnJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgLy8gUmVkaXJlY3QgdG8gVVJMXG4gICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSByZXN1bHQucmVkaXJlY3Q7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3Mgd2l0aG91dCByZWRpcmVjdFxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdGb3JtIHN1Ym1pdHRlZCBzdWNjZXNzZnVsbHknLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gUmVuZGVyIGVycm9yIChoYW5kbGVzIGJvdGggdmFsaWRhdGlvbiBhbmQgZ2VuZXJpYyBlcnJvcnMpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcl9lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgICAgICB0aGlzLiQuc2hhbGxvd0ZpbmQoJy5Gb3JtX0ZpZWxkJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJCh0aGlzKS5jb21wb25lbnQoKTtcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3NlZWQnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goY29tcG9uZW50LnNlZWQoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLFFBQVEsU0FBU0MsZ0JBQWdCLENBQUM7RUFDcENDLFNBQVNBLENBQUEsRUFBRztJQUNSLElBQUksQ0FBQ0MsSUFBSSxDQUFDQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixJQUFJLENBQUNELElBQUksQ0FBQ0UsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsSUFBSSxDQUFDQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7O0lBRWxCO0lBQ0EsSUFBSUgsSUFBSSxHQUFHLElBQUksQ0FBQ0ksSUFBSSxDQUFDSixJQUFJO0lBRXpCLElBQUksT0FBT0EsSUFBSSxLQUFLLFFBQVEsRUFBRTtNQUMxQixJQUFJO1FBQ0E7UUFDQTtRQUNBLE1BQU1LLE9BQU8sR0FBR0MsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDQyxJQUFJLENBQUNQLElBQUksQ0FBQyxDQUFDUSxJQUFJLENBQUMsQ0FBQztRQUNqRFIsSUFBSSxHQUFHUyxXQUFXLENBQUNKLE9BQU8sQ0FBQztNQUMvQixDQUFDLENBQUMsT0FBT0ssQ0FBQyxFQUFFO1FBQ1JDLE9BQU8sQ0FBQ0MsS0FBSyxD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