input-number.component.mjs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { ChangeDetectionStrategy, Component, HostListener, Input, Optional, forwardRef, inject, } from '@angular/core';
  2. import { AsyncPipe, DecimalPipe, NgClass } from '@angular/common';
  3. import { InputComponent } from '../input/input.component';
  4. import { provideControlContainer, provideValueAccessor } from '../utils/form.util';
  5. import { integerValidator } from '../utils/validators.util';
  6. import { LabelComponent } from '../label/label.component';
  7. import { IconComponent } from '../../components/atoms/icon/icon.component';
  8. import { FormErrorComponent } from '../error/error.component';
  9. import * as i0 from "@angular/core";
  10. import * as i1 from "@angular/forms";
  11. export class InputNumberComponent extends InputComponent {
  12. constructor(formGroupDirective) {
  13. super(formGroupDirective);
  14. this.formGroupDirective = formGroupDirective;
  15. this.decimalPipe = inject(DecimalPipe);
  16. this.validate = 'integer';
  17. }
  18. onFocusOut() {
  19. this.formatNumber();
  20. this.triggerTouched();
  21. }
  22. onFocusIn() {
  23. this.reverseFormatNumber();
  24. }
  25. ngOnInit() {
  26. if (this.formControl && this.validate === 'integer')
  27. this.formControl.addValidators(integerValidator());
  28. }
  29. ngAfterViewInit() {
  30. this.formatNumber();
  31. this.triggerChangeDetection();
  32. }
  33. formatNumber() {
  34. try {
  35. this.value = this.decimalPipe.transform(this.value, '1.0-2') || '';
  36. }
  37. catch (_error) {
  38. return;
  39. }
  40. }
  41. reverseFormatNumber() {
  42. this.value = !isNaN(parseFloat(this.value.replace(/[^0-9.-]/g, '')))
  43. ? parseFloat(this.value.replace(/[^0-9.-]/g, ''))
  44. : '';
  45. }
  46. static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: InputNumberComponent, deps: [{ token: i1.FormGroupDirective, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
  47. static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.5", type: InputNumberComponent, isStandalone: true, selector: "ct-input-number", inputs: { validate: "validate" }, host: { listeners: { "focusout": "onFocusOut()", "focusin": "onFocusIn()" } }, providers: [provideValueAccessor(forwardRef(() => InputNumberComponent)), DecimalPipe], usesInheritance: true, ngImport: i0, template: "<div\n class=\"flex\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [ngClass]=\"{\n 'items-center gap-4': disposition === 'horizontal',\n 'flex-col gap-0.5 items-start': disposition === 'vertical'\n }\">\n @if (label) {\n <ct-form-label [text]=\"label\" [hasError]=\"hasErrors(formControl)\" [showError]=\"showError\" />\n }\n <div\n class=\"relative inline-block rounded-md text-on-surface dark:text-on-surface-dark\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\">\n <input\n tabindex=\"0\"\n [type]=\"type\"\n [min]=\"min\"\n [max]=\"max\"\n class=\"h-9 rounded-md border bg-primary-50 font-primary text-sm outline-primary hover:border-neutral-600 dark:bg-primary-950 dark:outline-primary-dark focus:dark:border-primary-dark\"\n [class.px-4]=\"!icon || !symbol\"\n [ngClass]=\"{\n 'px-4': !icon,\n 'pr-4 pl-10': icon && iconPosition === 'left',\n 'pl-4 pr-10': (icon && iconPosition === 'right') || symbol || canDelete\n }\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [class.border-neutral-300]=\"!hasErrors(formControl) || !showError\"\n [class.border-error]=\"hasErrors(formControl) && showError\"\n [class.border-success]=\"formControl && formControl.valid && showError\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n (input)=\"input($event)\" />\n @if (icon) {\n <ct-icon\n class=\"absolute top-2\"\n [class.left-3]=\"iconPosition === 'left'\"\n [class.right-3]=\"iconPosition === 'right'\"\n [icon]=\"icon\" />\n }\n @if (symbol) {\n <span class=\"absolute right-3 top-2.5 text-xs text-neutral-600 dark:text-neutral-300\">{{ symbol }}</span>\n }\n @if (showDelete$ | async) {\n <ct-icon class=\"absolute right-3 top-2.5 cursor-pointer\" icon=\"x-mark\" size=\"sm\" (click)=\"clearValue()\" />\n }\n </div>\n @if (formControl) {\n <ct-form-alert\n [fullSize]=\"fullSize\"\n [hasErrors]=\"hasErrors(formControl)\"\n [helper]=\"helper\"\n [errors]=\"formControl.errors ?? {}\"\n size=\"xs\" />\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: LabelComponent, selector: "ct-form-label", inputs: ["text", "type", "formControlName", "hasError", "showError"] }, { kind: "component", type: IconComponent, selector: "ct-icon", inputs: ["icon", "fill", "strokeWidth", "strokeColor", "size", "variant"] }, { kind: "component", type: FormErrorComponent, selector: "ct-form-alert", inputs: ["errors", "size", "hasErrors", "fullSize", "helper", "errorMessages"] }], viewProviders: [provideControlContainer()], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
  48. }
  49. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: InputNumberComponent, decorators: [{
  50. type: Component,
  51. args: [{ selector: 'ct-input-number', standalone: true, imports: [NgClass, AsyncPipe, LabelComponent, IconComponent, FormErrorComponent], providers: [provideValueAccessor(forwardRef(() => InputNumberComponent)), DecimalPipe], viewProviders: [provideControlContainer()], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"flex\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [ngClass]=\"{\n 'items-center gap-4': disposition === 'horizontal',\n 'flex-col gap-0.5 items-start': disposition === 'vertical'\n }\">\n @if (label) {\n <ct-form-label [text]=\"label\" [hasError]=\"hasErrors(formControl)\" [showError]=\"showError\" />\n }\n <div\n class=\"relative inline-block rounded-md text-on-surface dark:text-on-surface-dark\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\">\n <input\n tabindex=\"0\"\n [type]=\"type\"\n [min]=\"min\"\n [max]=\"max\"\n class=\"h-9 rounded-md border bg-primary-50 font-primary text-sm outline-primary hover:border-neutral-600 dark:bg-primary-950 dark:outline-primary-dark focus:dark:border-primary-dark\"\n [class.px-4]=\"!icon || !symbol\"\n [ngClass]=\"{\n 'px-4': !icon,\n 'pr-4 pl-10': icon && iconPosition === 'left',\n 'pl-4 pr-10': (icon && iconPosition === 'right') || symbol || canDelete\n }\"\n [class.w-fit]=\"!fullSize\"\n [class.w-full]=\"fullSize\"\n [class.border-neutral-300]=\"!hasErrors(formControl) || !showError\"\n [class.border-error]=\"hasErrors(formControl) && showError\"\n [class.border-success]=\"formControl && formControl.valid && showError\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n (input)=\"input($event)\" />\n @if (icon) {\n <ct-icon\n class=\"absolute top-2\"\n [class.left-3]=\"iconPosition === 'left'\"\n [class.right-3]=\"iconPosition === 'right'\"\n [icon]=\"icon\" />\n }\n @if (symbol) {\n <span class=\"absolute right-3 top-2.5 text-xs text-neutral-600 dark:text-neutral-300\">{{ symbol }}</span>\n }\n @if (showDelete$ | async) {\n <ct-icon class=\"absolute right-3 top-2.5 cursor-pointer\" icon=\"x-mark\" size=\"sm\" (click)=\"clearValue()\" />\n }\n </div>\n @if (formControl) {\n <ct-form-alert\n [fullSize]=\"fullSize\"\n [hasErrors]=\"hasErrors(formControl)\"\n [helper]=\"helper\"\n [errors]=\"formControl.errors ?? {}\"\n size=\"xs\" />\n }\n</div>\n" }]
  52. }], ctorParameters: () => [{ type: i1.FormGroupDirective, decorators: [{
  53. type: Optional
  54. }] }], propDecorators: { validate: [{
  55. type: Input
  56. }], onFocusOut: [{
  57. type: HostListener,
  58. args: ['focusout']
  59. }], onFocusIn: [{
  60. type: HostListener,
  61. args: ['focusin']
  62. }] } });
  63. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtbnVtYmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NpcmNsZXRvbmUvc3JjL2xpYi9mb3Jtcy9pbnB1dC1udW1iZXIvaW5wdXQtbnVtYmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NpcmNsZXRvbmUvc3JjL2xpYi9mb3Jtcy9pbnB1dC9pbnB1dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLFFBQVEsRUFDUixVQUFVLEVBQ1YsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7QUFXOUQsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGNBQWM7SUFLdEQsWUFBMkMsa0JBQXNDO1FBQy9FLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRGUsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUpoRSxnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxQyxhQUFRLEdBQThCLFNBQVMsQ0FBQztJQUl6RCxDQUFDO0lBR1EsVUFBVTtRQUNqQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFHRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTO1lBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNyRSxDQUFDO1FBQUMsT0FBTyxNQUFNLEVBQUUsQ0FBQztZQUNoQixPQUFPO1FBQ1QsQ0FBQztJQUNILENBQUM7SUFFRCxtQkFBbUI7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbEUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDakQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNULENBQUM7OEdBekNVLG9CQUFvQjtrR0FBcEIsb0JBQW9CLCtLQUpwQixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLGlEQ3pCeEYsZ3BFQTBEQSw0Q0RuQ1ksT0FBTywrRUFBRSxTQUFTLDhDQUFFLGNBQWMsZ0lBQUUsYUFBYSwrSEFBRSxrQkFBa0IsK0hBR2hFLENBQUMsdUJBQXVCLEVBQUUsQ0FBQzs7MkZBRy9CLG9CQUFvQjtrQkFUaEMsU0FBUzsrQkFDRSxpQkFBaUIsY0FDZixJQUFJLFdBQ1AsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsa0JBQWtCLENBQUMsYUFFckUsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLHFCQUFxQixDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsaUJBQ3ZFLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxtQkFDekIsdUJBQXVCLENBQUMsTUFBTTs7MEJBT2xDLFFBQVE7eUNBRlosUUFBUTtzQkFBaEIsS0FBSztnQkFPRyxVQUFVO3NCQURsQixZQUFZO3VCQUFDLFVBQVU7Z0JBT3hCLFNBQVM7c0JBRFIsWUFBWTt1QkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgZm9yd2FyZFJlZixcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFzeW5jUGlwZSwgRGVjaW1hbFBpcGUsIE5nQ2xhc3MgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybUdyb3VwRGlyZWN0aXZlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSW5wdXRDb21wb25lbnQgfSBmcm9tICcuLi9pbnB1dC9pbnB1dC5jb21wb25lbnQnO1xuaW1wb3J0IHsgcHJvdmlkZUNvbnRyb2xDb250YWluZXIsIHByb3ZpZGVWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnLi4vdXRpbHMvZm9ybS51dGlsJztcbmltcG9ydCB7IGludGVnZXJWYWxpZGF0b3IgfSBmcm9tICcuLi91dGlscy92YWxpZGF0b3JzLnV0aWwnO1xuaW1wb3J0IHsgTGFiZWxDb21wb25lbnQgfSBmcm9tICcuLi9sYWJlbC9sYWJlbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWNvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvYXRvbXMvaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBGb3JtRXJyb3JDb21wb25lbnQgfSBmcm9tICcuLi9lcnJvci9lcnJvci5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjdC1pbnB1dC1udW1iZXInLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbTmdDbGFzcywgQXN5bmNQaXBlLCBMYWJlbENvbXBvbmVudCwgSWNvbkNvbXBvbmVudCwgRm9ybUVycm9yQ29tcG9uZW50XSxcbiAgdGVtcGxhdGVVcmw6ICcuLi9pbnB1dC9pbnB1dC5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW3Byb3ZpZGVWYWx1ZUFjY2Vzc29yKGZvcndhcmRSZWYoKCkgPT4gSW5wdXROdW1iZXJDb21wb25lbnQpKSwgRGVjaW1hbFBpcGVdLFxuICB2aWV3UHJvdmlkZXJzOiBbcHJvdmlkZUNvbnRyb2xDb250YWluZXIoKV0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBJbnB1dE51bWJlckNvbXBvbmVudCBleHRlbmRzIElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWNpbWFsUGlwZSA9IGluamVjdChEZWNpbWFsUGlwZSk7XG4gIHByaXZhdGUgcmF3VmFsdWUhOiBudW1iZXI7XG4gIEBJbnB1dCgpIHZhbGlkYXRlOiAnaW50ZWdlcicgfCAnY3JlZGl0LWNhcmQnID0gJ2ludGVnZXInO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIHByb3RlY3RlZCBvdmVycmlkZSBmb3JtR3JvdXBEaXJlY3RpdmU6IEZvcm1Hcm91cERpcmVjdGl2ZSkge1xuICAgIHN1cGVyKGZvcm1Hcm91cERpcmVjdGl2ZSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1c291dCcpXG4gIG92ZXJyaWRlIG9uRm9jdXNPdXQoKSB7XG4gICAgdGhpcy5mb3JtYXROdW1iZXIoKTtcbiAgICB0aGlzLnRyaWdnZXJUb3VjaGVkKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1c2luJylcbiAgb25Gb2N1c0luKCkge1xuICAgIHRoaXMucmV2ZXJzZUZvcm1hdE51bWJlcigpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2wgJiYgdGhpcy52YWxpZGF0ZSA9PT0gJ2ludGVnZXInKSB0aGlzLmZvcm1Db250cm9sLmFkZFZhbGlkYXRvcnMoaW50ZWdlclZhbGlkYXRvcigpKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZvcm1hdE51bWJlcigpO1xuICAgIHRoaXMudHJpZ2dlckNoYW5nZURldGVjdGlvbigpO1xuICB9XG5cbiAgZm9ybWF0TnVtYmVyKCkge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbHVlID0gdGhpcy5kZWNpbWFsUGlwZS50cmFuc2Zvcm0odGhpcy52YWx1ZSwgJzEuMC0yJykgfHwgJyc7XG4gICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgcmV2ZXJzZUZvcm1hdE51bWJlcigpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gIWlzTmFOKHBhcnNlRmxvYXQodGhpcy52YWx1ZS5yZXBsYWNlKC9bXjAtOS4tXS9nLCAnJykpKVxuICAgICAgPyBwYXJzZUZsb2F0KHRoaXMudmFsdWUucmVwbGFjZSgvW14wLTkuLV0vZywgJycpKVxuICAgICAgOiAnJztcbiAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImZsZXhcIlxuICBbY2xhc3Mudy1maXRdPVwiIWZ1bGxTaXplXCJcbiAgW2NsYXNzLnctZnVsbF09XCJmdWxsU2l6ZVwiXG4gIFtuZ0NsYXNzXT1cIntcbiAgICAnaXRlbXMtY2VudGVyIGdhcC00JzogZGlzcG9zaXRpb24gPT09ICdob3Jpem9udGFsJyxcbiAgICAnZmxleC1jb2wgZ2FwLTAuNSBpdGVtcy1zdGFydCc6IGRpc3Bvc2l0aW9uID09PSAndmVydGljYWwnXG4gIH1cIj5cbiAgQGlmIChsYWJlbCkge1xuICAgIDxjdC1mb3JtLWxhYmVsIFt0ZXh0XT1cImxhYmVsXCIgW2hhc0Vycm9yXT1cImhhc0Vycm9ycyhmb3JtQ29udHJvbClcIiBbc2hvd0Vycm9yXT1cInNob3dFcnJvclwiIC8+XG4gIH1cbiAgPGRpdlxuICAgIGNsYXNzPVwicmVsYXRpdmUgaW5saW5lLWJsb2NrIHJvdW5kZWQtbWQgdGV4dC1vbi1zdXJmYWNlIGRhcms6dGV4dC1vbi1zdXJmYWNlLWRhcmtcIlxuICAgIFtjbGFzcy53LWZpdF09XCIhZnVsbFNpemVcIlxuICAgIFtjbGFzcy53LWZ1bGxdPVwiZnVsbFNpemVcIj5cbiAgICA8aW5wdXRcbiAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICBbdHlwZV09XCJ0eXBlXCJcbiAgICAgIFttaW5dPVwibWluXCJcbiAgICAgIFttYXhdPVwibWF4XCJcbiAgICAgIGNsYXNzPVwiaC05IHJvdW5kZWQtbWQgYm9yZGVyIGJnLXByaW1hcnktNTAgZm9udC1wcmltYXJ5IHRleHQtc20gb3V0bGluZS1wcmltYXJ5IGhvdmVyOmJvcmRlci1uZXV0cmFsLTYwMCBkYXJrOmJnLXByaW1hcnktOTUwIGRhcms6b3V0bGluZS1wcmltYXJ5LWRhcmsgZm9jdXM6ZGFyazpib3JkZXItcHJpbWFyeS1kYXJrXCJcbiAgICAgIFtjbGFzcy5weC00XT1cIiFpY29uIHx8ICFzeW1ib2xcIlxuICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAncHgtNCc6ICFpY29uLFxuICAgICAgICAncHItNCBwbC0xMCc6IGljb24gJiYgaWNvblBvc2l0aW9uID09PSAnbGVmdCcsXG4gICAgICAgICdwbC00IHByLTEwJzogKGljb24gJiYgaWNvblBvc2l0aW9uID09PSAncmlnaHQnKSB8fCBzeW1ib2wgfHwgY2FuRGVsZXRlXG4gICAgICB9XCJcbiAgICAgIFtjbGFzcy53LWZpdF09XCIhZnVsbFNpemVcIlxuICAgICAgW2NsYXNzLnctZnVsbF09XCJmdWxsU2l6ZVwiXG4gICAgICBbY2xhc3MuYm9yZGVyLW5ldXRyYWwtMzAwXT1cIiFoYXNFcnJvcnMoZm9ybUNvbnRyb2wpIHx8ICFzaG93RXJyb3JcIlxuICAgICAgW2NsYXNzLmJvcmRlci1lcnJvcl09XCJoYXNFcnJvcnMoZm9ybUNvbnRyb2wpICYmIHNob3dFcnJvclwiXG4gICAgICBbY2xhc3MuYm9yZGVyLXN1Y2Nlc3NdPVwiZm9ybUNvbnRyb2wgJiYgZm9ybUNvbnRyb2wudmFsaWQgJiYgc2hvd0Vycm9yXCJcbiAgICAgIFt2YWx1ZV09XCJ2YWx1ZVwiXG4gICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgKGlucHV0KT1cImlucHV0KCRldmVudClcIiAvPlxuICAgIEBpZiAoaWNvbikge1xuICAgICAgPGN0LWljb25cbiAgICAgICAgY2xhc3M9XCJhYnNvbHV0ZSB0b3AtMlwiXG4gICAgICAgIFtjbGFzcy5sZWZ0LTNdPVwiaWNvblBvc2l0aW9uID09PSAnbGVmdCdcIlxuICAgICAgICBbY2xhc3MucmlnaHQtM109XCJpY29uUG9zaXRpb24gPT09ICdyaWdodCdcIlxuICAgICAgICBbaWNvbl09XCJpY29uXCIgLz5cbiAgICB9XG4gICAgQGlmIChzeW1ib2wpIHtcbiAgICAgIDxzcGFuIGNsYXNzPVwiYWJzb2x1dGUgcmlnaHQtMyB0b3AtMi41IHRleHQteHMgdGV4dC1uZXV0cmFsLTYwMCBkYXJrOnRleHQtbmV1dHJhbC0zMDBcIj57eyBzeW1ib2wgfX08L3NwYW4+XG4gICAgfVxuICAgIEBpZiAoc2hvd0RlbGV0ZSQgfCBhc3luYykge1xuICAgICAgPGN0LWljb24gY2xhc3M9XCJhYnNvbHV0ZSByaWdodC0zIHRvcC0yLjUgY3Vyc29yLXBvaW50ZXJcIiBpY29uPVwieC1tYXJrXCIgc2l6ZT1cInNtXCIgKGNsaWNrKT1cImNsZWFyVmFsdWUoKVwiIC8+XG4gICAgfVxuICA8L2Rpdj5cbiAgQGlmIChmb3JtQ29udHJvbCkge1xuICAgIDxjdC1mb3JtLWFsZXJ0XG4gICAgICBbZnVsbFNpemVdPVwiZnVsbFNpemVcIlxuICAgICAgW2hhc0Vycm9yc109XCJoYXNFcnJvcnMoZm9ybUNvbnRyb2wpXCJcbiAgICAgIFtoZWxwZXJdPVwiaGVscGVyXCJcbiAgICAgIFtlcnJvcnNdPVwiZm9ybUNvbnRyb2wuZXJyb3JzID8/IHt9XCJcbiAgICAgIHNpemU9XCJ4c1wiIC8+XG4gIH1cbjwvZGl2PlxuIl19