Files
rspade_system/storage-working/rsx-tmp/babel_edeb2fab17b1036296c57437e65911ea.js
root 78553d4edf Fix code quality violations for publish
Remove unused blade settings pages not linked from UI
Convert remaining frontend pages to SPA actions
Convert settings user_settings and general to SPA actions
Convert settings profile pages to SPA actions
Convert contacts and projects add/edit pages to SPA actions
Convert clients add/edit page to SPA action with loading pattern
Refactor component scoped IDs from $id to $sid
Fix jqhtml comment syntax and implement universal error component system
Update all application code to use new unified error system
Remove all backwards compatibility - unified error system complete
Phase 5: Remove old response classes
Phase 3-4: Ajax response handler sends new format, old helpers deprecated
Phase 2: Add client-side unified error foundation
Phase 1: Add server-side unified error foundation
Add unified Ajax error response system with constants

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 04:35:01 +00:00

219 lines
24 KiB
JavaScript
Executable File

"use strict";
/**
* Pin_Verification_Form
*
* Specialized 6-digit PIN entry form with auto-navigation between inputs.
* See pin_verification_form.jqhtml for full documentation.
*
* JavaScript Responsibilities:
* - Auto-advances to next input when digit is entered
* - Smart backspace: clears current box and moves to previous
* - Paste support: distributes pasted digits across all 6 inputs
* - Arrow key navigation between inputs
* - Numeric-only input validation
* - Select-all on focus for easy digit replacement
* - Validates all 6 digits entered before allowing submission
* - Provides val() getter/setter for programmatic PIN access
*/
class Pin_Verification_Form extends Rsx_Form {
on_create() {
super.on_create();
this.pin_length = 6;
}
/**
* Get or set the PIN value
* @param {string} [value] - If provided, sets the PIN (distributes across inputs)
* @returns {string} Current PIN value when called as getter
*/
val(value) {
if (arguments.length === 0) {
// Getter - collect all digits
let pin = '';
for (let i = 0; i < this.pin_length; i++) {
pin += this.$sid(`digit_${i}`).val() || '';
}
return pin;
} else {
// Setter - distribute digits across inputs
const digits = str(value || '').replace(/[^0-9]/g, '');
for (let i = 0; i < this.pin_length; i++) {
this.$sid(`digit_${i}`).val(digits[i] || '');
}
// Focus first empty input or last input
const first_empty = this._find_first_empty_index();
if (first_empty !== -1) {
this.$sid(`digit_${first_empty}`)[0].focus();
} else {
this.$sid(`digit_${this.pin_length - 1}`)[0].focus();
}
}
}
/**
* Find the first empty input index
* @returns {number} Index of first empty input, or -1 if all filled
*/
_find_first_empty_index() {
for (let i = 0; i < this.pin_length; i++) {
if (!this.$sid(`digit_${i}`).val()) {
return i;
}
}
return -1;
}
/**
* Move focus to specific input index
* @param {number} index
*/
_focus_input(index) {
if (index >= 0 && index < this.pin_length) {
const $input = this.$sid(`digit_${index}`);
if ($input.exists()) {
$input[0].focus();
// Select the content if there is any
$input[0].select();
}
}
}
/**
* Handle paste event - distribute digits across inputs
* @param {ClipboardEvent} e
* @param {number} start_index
*/
_handle_paste(e, start_index) {
e.preventDefault();
// Get pasted data
const paste = (e.originalEvent || e).clipboardData.getData('text');
const digits = paste.replace(/[^0-9]/g, '');
if (!digits) {
return;
}
// Distribute digits starting from current input
for (let i = 0; i < digits.length && start_index + i < this.pin_length; i++) {
this.$sid(`digit_${start_index + i}`).val(digits[i]);
}
// Focus next empty input or last input
const next_index = Math.min(start_index + digits.length, this.pin_length - 1);
this._focus_input(next_index);
}
on_ready() {
super.on_ready();
const that = this;
// Set up event handlers for each input
for (let i = 0; i < this.pin_length; i++) {
const $input = this.$sid(`digit_${i}`);
const index = i;
// Handle input event - auto-advance
$input.on('input', function (e) {
const value = $(this).val();
// Only allow numeric input
const numeric = value.replace(/[^0-9]/g, '');
if (numeric !== value) {
$(this).val(numeric);
}
// If multiple digits were entered (paste), distribute them
if (numeric.length > 1) {
that._handle_paste({
preventDefault: () => {},
originalEvent: {
clipboardData: {
getData: () => numeric
}
}
}, index);
return;
}
// Auto-advance to next input if digit was entered
if (numeric.length === 1 && index < that.pin_length - 1) {
that._focus_input(index + 1);
}
});
// Handle keydown for backspace
$input.on('keydown', function (e) {
// Backspace key
if (e.key === 'Backspace') {
const current_value = $(this).val();
// If current input is empty, move to previous and clear it
if (!current_value && index > 0) {
e.preventDefault();
that.$sid(`digit_${index - 1}`).val('');
that._focus_input(index - 1);
}
// If current input has value, it will be cleared by default behavior
// and we stay on current input
}
// Arrow left
if (e.key === 'ArrowLeft' && index > 0) {
e.preventDefault();
that._focus_input(index - 1);
}
// Arrow right
if (e.key === 'ArrowRight' && index < that.pin_length - 1) {
e.preventDefault();
that._focus_input(index + 1);
}
});
// Handle paste event
$input.on('paste', function (e) {
that._handle_paste(e, index);
});
// Select all on focus for easy replacement
$input.on('focus', function () {
$(this)[0].select();
});
}
// Focus first input on load
this._focus_input(0);
}
/**
* Override submit to validate PIN is complete
*/
async submit() {
const pin = this.val();
// Clear previous errors
this.$sid('error_container').hide().empty();
// Validate PIN is 6 digits
if (pin.length !== this.pin_length) {
this.$sid('error_container').text('Please enter all 6 digits').show();
// Mark inputs as invalid
for (let i = 0; i < this.pin_length; i++) {
if (!this.$sid(`digit_${i}`).val()) {
this.$sid(`digit_${i}`).addClass('is-invalid');
}
}
return;
}
// Remove invalid class from all inputs
for (let i = 0; i < this.pin_length; i++) {
this.$sid(`digit_${i}`).removeClass('is-invalid');
}
// Call parent submit (which will use controller/method if provided)
await super.submit();
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQaW5fVmVyaWZpY2F0aW9uX0Zvcm0iLCJSc3hfRm9ybSIsIm9uX2NyZWF0ZSIsInBpbl9sZW5ndGgiLCJ2YWwiLCJ2YWx1ZSIsImFyZ3VtZW50cyIsImxlbmd0aCIsInBpbiIsImkiLCIkaWQiLCJkaWdpdHMiLCJzdHIiLCJyZXBsYWNlIiwiZmlyc3RfZW1wdHkiLCJfZmluZF9maXJzdF9lbXB0eV9pbmRleCIsImZvY3VzIiwiX2ZvY3VzX2lucHV0IiwiaW5kZXgiLCIkaW5wdXQiLCJleGlzdHMiLCJzZWxlY3QiLCJfaGFuZGxlX3Bhc3RlIiwiZSIsInN0YXJ0X2luZGV4IiwicHJldmVudERlZmF1bHQiLCJwYXN0ZSIsIm9yaWdpbmFsRXZlbnQiLCJjbGlwYm9hcmREYXRhIiwiZ2V0RGF0YSIsIm5leHRfaW5kZXgiLCJNYXRoIiwibWluIiwib25fcmVhZHkiLCJ0aGF0Iiwib24iLCIkIiwibnVtZXJpYyIsImtleSIsImN1cnJlbnRfdmFsdWUiLCJzdWJtaXQiLCJoaWRlIiwiZW1wdHkiLCJ0ZXh0Iiwic2hvdyIsImFkZENsYXNzIiwicmVtb3ZlQ2xhc3MiXSwic291cmNlcyI6WyJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9waW5fdmVyaWZpY2F0aW9uX2Zvcm0uanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQaW5fVmVyaWZpY2F0aW9uX0Zvcm1cbiAqXG4gKiBTcGVjaWFsaXplZCA2LWRpZ2l0IFBJTiBlbnRyeSBmb3JtIHdpdGggYXV0by1uYXZpZ2F0aW9uIGJldHdlZW4gaW5wdXRzLlxuICogU2VlIHBpbl92ZXJpZmljYXRpb25fZm9ybS5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIEF1dG8tYWR2YW5jZXMgdG8gbmV4dCBpbnB1dCB3aGVuIGRpZ2l0IGlzIGVudGVyZWRcbiAqIC0gU21hcnQgYmFja3NwYWNlOiBjbGVhcnMgY3VycmVudCBib3ggYW5kIG1vdmVzIHRvIHByZXZpb3VzXG4gKiAtIFBhc3RlIHN1cHBvcnQ6IGRpc3RyaWJ1dGVzIHBhc3RlZCBkaWdpdHMgYWNyb3NzIGFsbCA2IGlucHV0c1xuICogLSBBcnJvdyBrZXkgbmF2aWdhdGlvbiBiZXR3ZWVuIGlucHV0c1xuICogLSBOdW1lcmljLW9ubHkgaW5wdXQgdmFsaWRhdGlvblxuICogLSBTZWxlY3QtYWxsIG9uIGZvY3VzIGZvciBlYXN5IGRpZ2l0IHJlcGxhY2VtZW50XG4gKiAtIFZhbGlkYXRlcyBhbGwgNiBkaWdpdHMgZW50ZXJlZCBiZWZvcmUgYWxsb3dpbmcgc3VibWlzc2lvblxuICogLSBQcm92aWRlcyB2YWwoKSBnZXR0ZXIvc2V0dGVyIGZvciBwcm9ncmFtbWF0aWMgUElOIGFjY2Vzc1xuICovXG5jbGFzcyBQaW5fVmVyaWZpY2F0aW9uX0Zvcm0gZXh0ZW5kcyBSc3hfRm9ybSB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcbiAgICAgICAgdGhpcy5waW5fbGVuZ3RoID0gNjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3Igc2V0IHRoZSBQSU4gdmFsdWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBQSU4gKGRpc3RyaWJ1dGVzIGFjcm9zcyBpbnB1dHMpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQ3VycmVudCBQSU4gdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXIgLSBjb2xsZWN0IGFsbCBkaWdpdHNcbiAgICAgICAgICAgIGxldCBwaW4gPSAnJztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBwaW4gKz0gdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS52YWwoKSB8fCAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwaW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXIgLSBkaXN0cmlidXRlIGRpZ2l0cyBhY3Jvc3MgaW5wdXRzXG4gICAgICAgICAgICBjb25zdCBkaWdpdHMgPSBzdHIodmFsdWUgfHwgJycpLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS52YWwoZGlnaXRzW2ldIHx8ICcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEZvY3VzIGZpcnN0IGVtcHR5IGlucHV0IG9yIGxhc3QgaW5wdXRcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0X2VtcHR5ID0gdGhpcy5fZmluZF9maXJzdF9lbXB0eV9pbmRleCgpO1xuICAgICAgICAgICAgaWYgKGZpcnN0X2VtcHR5ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke2ZpcnN0X2VtcHR5fWApWzBdLmZvY3VzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke3RoaXMucGluX2xlbmd0aCAtIDF9YClbMF0uZm9jdXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmQgdGhlIGZpcnN0IGVtcHR5IGlucHV0IGluZGV4XG4gICAgICogQHJldHVybnMge251bWJlcn0gSW5kZXggb2YgZmlyc3QgZW1wdHkgaW5wdXQsIG9yIC0xIGlmIGFsbCBmaWxsZWRcbiAgICAgKi9cbiAgICBfZmluZF9maXJzdF9lbXB0eV9pbmRleCgpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1vdmUgZm9jdXMgdG8gc3BlY2lmaWMgaW5wdXQgaW5kZXhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAgICAgKi9cbiAgICBfZm9jdXNfaW5wdXQoaW5kZXgpIHtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLnBpbl9sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKGBkaWdpdF8ke2luZGV4fWApO1xuICAgICAgICAgICAgaWYgKCRpbnB1dC5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICRpbnB1dFswXS5mb2N1cygpO1xuICAgICAgICAgICAgICAgIC8vIFNlbGVjdCB0aGUgY29udGVudCBpZiB0aGVyZSBpcyBhbnlcbiAgICAgICAgICAgICAgICAkaW5wdXRbMF0uc2VsZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgcGFzdGUgZXZlbnQgLSBkaXN0cmlidXRlIGRpZ2l0cyBhY3Jvc3MgaW5wdXRzXG4gICAgICogQHBhcmFtIHtDbGlwYm9hcmRFdmVudH0gZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydF9pbmRleFxuICAgICAqL1xuICAgIF9oYW5kbGVfcGFzdGUoZSwgc3RhcnRfaW5kZXgpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIC8vIEdldCBwYXN0ZWQgZGF0YVxuICAgICAgICBjb25zdCBwYXN0ZSA9IChlLm9yaWdpbmFsRXZlbnQgfHwgZSkuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0Jyk7XG4gICAgICAgIGNvbnN0IGRpZ2l0cyA9IHBhc3RlLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG5cbiAgICAgICAgaWYgKCFkaWdpdHMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERpc3RyaWJ1dGUgZGlnaXRzIHN0YXJ0aW5nIGZyb20gY3VycmVudCBpbnB1dFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZ2l0cy5sZW5ndGggJiYgKHN0YXJ0X2luZGV4ICsgaSkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7c3RhcnRfaW5kZXggKyBpfWApLnZhbChkaWdpdHNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9jdXMgbmV4dCBlbXB0eSBpbnB1dCBvciBsYXN0IGlucHV0XG4gICAgICAgIGNvbnN0IG5leHRfaW5kZXggPSBNYXRoLm1pbihzdGFydF9pbmRleCArIGRpZ2l0cy5sZW5ndGgsIHRoaXMucGluX2xlbmd0aCAtIDEpO1xuICAgICAgICB0aGlzLl9mb2N1c19pbnB1dChuZXh0X2luZGV4KTtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBTZXQgdXAgZXZlbnQgaGFuZGxlcnMgZm9yIGVhY2ggaW5wdXRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gaTtcblxuICAgICAgICAgICAgLy8gSGFuZGxlIGlucHV0IGV2ZW50IC0gYXV0by1hZHZhbmNlXG4gICAgICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gJCh0aGlzKS52YWwoKTtcblxuICAgICAgICAgICAgICAgIC8vIE9ubHkgYWxsb3cgbnVtZXJpYyBpbnB1dFxuICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB2YWx1ZS5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuICAgICAgICAgICAgICAgIGlmIChudW1lcmljICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnZhbChudW1lcmljKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBtdWx0aXBsZSBkaWdpdHMgd2VyZSBlbnRlcmVkIChwYXN0ZSksIGRpc3RyaWJ1dGUgdGhlbVxuICAgICAgICAgICAgICAgIGlmIChudW1lcmljLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5faGFuZGxlX3Bhc3RlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7fSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsRXZlbnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwYm9hcmREYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldERhdGE6ICgpID0+IG51bWVyaWNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEF1dG8tYWR2YW5jZSB0byBuZXh0IGlucHV0IGlmIGRpZ2l0IHdhcyBlbnRlcmVkXG4gICAgICAgICAgICAgICAgaWYgKG51bWVyaWMubGVuZ3RoID09PSAxICYmIGluZGV4IDwgdGhhdC5waW5fbGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9mb2N1c19pbnB1dChpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUga2V5ZG93biBmb3IgYmFja3NwYWNlXG4gICAgICAgICAgICAkaW5wdXQub24oJ2tleWRvd24nLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgLy8gQmFja3NwYWNlIGtleVxuICAgICAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudF92YWx1ZSA9ICQodGhpcykudmFsKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgY3VycmVudCBpbnB1dCBpcyBlbXB0eSwgbW92ZSB0byBwcmV2aW91cyBhbmQgY2xlYXIgaXRcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50X3ZhbHVlICYmIGluZGV4ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC4kaWQoYGRpZ2l0XyR7aW5kZXggLSAxfWApLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll9mb2N1c19pbnB1dChpbmRleCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGN1cnJlbnQgaW5wdXQgaGFzIHZhbHVlLCBpdCB3aWxsIGJlIGNsZWFyZWQgYnkgZGVmYXVsdCBiZWhhdmlvclxuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgd2Ugc3RheSBvbiBjdXJyZW50IGlucHV0XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXJyb3cgbGVmdFxuICAgICAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0Fycm93TGVmdCcgJiYgaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fZm9jdXNfaW5wdXQoaW5kZXggLSAxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcnJvdyByaWdodFxuICAgICAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0Fycm93UmlnaHQnICYmIGluZGV4IDwgdGhhdC5waW5fbGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4ICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBwYXN0ZSBldmVudFxuICAgICAgICAgICAgJGlucHV0Lm9uKCdwYXN0ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICB0aGF0Ll9oYW5kbGVfcGFzdGUoZSwgaW5kZXgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFNlbGVjdCBhbGwgb24gZm9jdXMgZm9yIGVhc3kgcmVwbGFjZW1lbnRcbiAgICAgICAgICAgICRpbnB1dC5vbignZm9jdXMnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAkKHRoaXMpWzBdLnNlbGVjdCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb2N1cyBmaXJzdCBpbnB1dCBvbiBsb2FkXG4gICAgICAgIHRoaXMuX2ZvY3VzX2lucHV0KDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHN1Ym1pdCB0byB2YWxpZGF0ZSBQSU4gaXMgY29tcGxldGVcbiAgICAgKi9cbiAgICBhc3luYyBzdWJtaXQoKSB7XG4gICAgICAgIGNvbnN0IHBpbiA9IHRoaXMudmFsKCk7XG5cbiAgICAgICAgLy8gQ2xlYXIgcHJldmlvdXMgZXJyb3JzXG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcl9jb250YWluZXInKS5oaWRlKCkuZW1wdHkoKTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSBQSU4gaXMgNiBkaWdpdHNcbiAgICAgICAgaWYgKHBpbi5sZW5ndGggIT09IHRoaXMucGluX2xlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2Vycm9yX2NvbnRhaW5lcicpXG4gICAgICAgICAgICAgICAgLnRleHQoJ1BsZWFzZSBlbnRlciBhbGwgNiBkaWdpdHMnKVxuICAgICAgICAgICAgICAgIC5zaG93KCk7XG5cbiAgICAgICAgICAgIC8vIE1hcmsgaW5wdXRzIGFzIGludmFsaWRcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuJGlkKGBkaWdpdF8ke2l9YCkudmFsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS5hZGRDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGludmFsaWQgY2xhc3MgZnJvbSBhbGwgaW5wdXRzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKGBkaWdpdF8ke2l9YCkucmVtb3ZlQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHN1Ym1pdCAod2hpY2ggd2lsbCB1c2UgY29udHJvbGxlci9tZXRob2QgaWYgcHJvdmlkZWQpXG4gICAgICAgIGF3YWl0IHN1cGVyLnN1Ym1pdCgpO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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