import * as i0 from '@angular/core';
import { HostListener, Directive, inject, ElementRef, ChangeDetectorRef, Renderer2, signal, effect, booleanAttribute, Input, EventEmitter, Output, forwardRef, Attribute } from '@angular/core';
import { NG_VALIDATORS } from '@angular/forms';
import DOMPurify from 'dompurify';

/**
 * expand textarea to fit content. Doesn't shrink.
 */
class AutosizeTextareaDirective {
    element;
    static maxHeight = 200;
    constructor(element) {
        this.element = element;
    }
    onInput() {
        this.resize();
    }
    ngAfterContentChecked() {
        this.resize();
    }
    resize() {
        const style = this.element.nativeElement.style;
        const scrollHeight = this.element.nativeElement.scrollHeight;
        const actualHeight = this.element.nativeElement.offsetHeight;
        if (AutosizeTextareaDirective.maxHeight < scrollHeight) {
            // we arrived at the max
            style.overflow = 'auto';
            style.height = `${AutosizeTextareaDirective.maxHeight}px`;
        }
        else if (actualHeight < scrollHeight) {
            style.overflow = 'hidden';
            style.height = `${scrollHeight}px`;
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AutosizeTextareaDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: AutosizeTextareaDirective, isStandalone: true, selector: "textarea[apAutosize]", host: { listeners: { "input": "onInput()" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: AutosizeTextareaDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'textarea[apAutosize]',
                    standalone: true,
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { onInput: [{
                type: HostListener,
                args: ['input']
            }] } });

class BaseButtonDirective {
    hostId = undefined;
    hostDataTest = undefined;
    hostType = 'button';
    elementRef = inject(ElementRef);
    changeDetectorRef = inject(ChangeDetectorRef);
    ngOnInit() {
        this.hostDataTest = this.elementRef.nativeElement.getAttribute('data-test');
        this.hostId = this.elementRef.nativeElement.getAttribute('id');
        this.elementRef.nativeElement.removeAttribute('data-test');
        this.elementRef.nativeElement.removeAttribute('id');
    }
    // Sometimes attributes like the id, or the data-test are dynamic and can change between the constructor and the initialization.
    // In order to have the last attributes value we check if it changes, and if it does, we run a mark for check to update the view.
    ngAfterViewInit() {
        const hostDataTest = this.elementRef.nativeElement.getAttribute('data-test');
        const hostId = this.elementRef.nativeElement.getAttribute('id');
        const hostType = this.elementRef.nativeElement.getAttribute('type');
        if (hostDataTest && this.hostDataTest !== hostDataTest) {
            this.hostDataTest = hostDataTest;
            this.elementRef.nativeElement.removeAttribute('data-test');
            this.changeDetectorRef.markForCheck();
        }
        if (hostId && this.hostId !== hostId) {
            this.hostId = hostId;
            this.elementRef.nativeElement.removeAttribute('id');
            this.changeDetectorRef.markForCheck();
        }
        if (hostType && this.hostType !== hostType) {
            this.hostType = hostType;
            this.elementRef.nativeElement.removeAttribute('type');
            this.changeDetectorRef.markForCheck();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BaseButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: BaseButtonDirective, isStandalone: true, selector: "[apBaseButton]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: BaseButtonDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[apBaseButton]',
                    standalone: true,
                }]
        }] });

class CheckboxDirective {
    elementRef = inject((ElementRef));
    renderer = inject(Renderer2);
    // State signals
    _checked = signal(false, ...(ngDevMode ? [{ debugName: "_checked" }] : []));
    _indeterminate = signal(false, ...(ngDevMode ? [{ debugName: "_indeterminate" }] : []));
    // Input signal accessors that work with host bindings
    checked = this._checked.asReadonly();
    indeterminate = this._indeterminate.asReadonly();
    // Input setters with proper aliases for template binding
    // Couldn't be migrated to yet
    set checkedInput(checked) {
        this._checked.set(checked);
        this.updateNativeElementSync();
    }
    set indeterminateInput(indeterminate) {
        if (indeterminate) {
            this._checked.set(false);
        }
        this._indeterminate.set(indeterminate);
        this.updateNativeElementSync();
    }
    updateNativeElementSync() {
        const input = this.elementRef.nativeElement;
        if (input) {
            input.checked = this.checked();
            input.indeterminate = this.indeterminate();
        }
    }
    // Private properties
    listeners = [];
    styleElement;
    checkmarkSvg;
    indeterminateBar;
    constructor() {
        effect(() => {
            if (this.checkmarkSvg && this.indeterminateBar) {
                this.updateCheckmarkVisibility();
            }
        });
    }
    // Custom SVG content
    checkSvgContent = `
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="10" height="10" fill="white">
            <path fill-rule="evenodd" clip-rule="evenodd" d="M14.238 3.337a.92.92 0 0 1 .025 1.301l-7.7 8a.92.92 0 0 1-1.326 0l-3.5-3.636a.92.92 0 1 1 1.326-1.276L5.9 10.674l7.037-7.312a.92.92 0 0 1 1.301-.025Z" />
        </svg>
    `;
    ngOnInit() {
        this.createCheckboxStructure();
        this.setupEventListeners();
    }
    ngOnDestroy() {
        this.listeners.forEach(unlisten => unlisten());
        if (this.styleElement && this.styleElement.parentNode) {
            this.styleElement.parentNode.removeChild(this.styleElement);
        }
        if (this.checkmarkSvg && this.checkmarkSvg.parentNode) {
            this.checkmarkSvg.parentNode.removeChild(this.checkmarkSvg);
        }
        if (this.indeterminateBar && this.indeterminateBar.parentNode) {
            this.indeterminateBar.parentNode.removeChild(this.indeterminateBar);
        }
    }
    createCheckboxStructure() {
        const input = this.elementRef.nativeElement;
        const parent = input.parentElement;
        // Make input's parent use inline-flex for alignment and position relative
        if (parent) {
            this.renderer.setStyle(parent, 'display', 'inline-flex');
            this.renderer.setStyle(parent, 'align-items', 'center');
            this.renderer.setStyle(parent, 'gap', 'var(--ref-spacing-xxs)');
            this.renderer.setStyle(parent, 'position', 'relative');
        }
        this.renderer.addClass(input, 'ap-checkbox-styled');
        this.createCheckmarkSvg();
        this.createIndeterminateBar();
        this.applyCheckboxStyles();
        this.updateCheckmarkVisibility();
    }
    createOverlayElement(element) {
        const parent = this.elementRef.nativeElement.parentElement;
        // Apply common positioning styles
        this.renderer.setStyle(element, 'position', 'absolute');
        this.renderer.setStyle(element, 'top', '50%');
        this.renderer.setStyle(element, 'left', '8px'); // Center over 16px checkbox
        this.renderer.setStyle(element, 'transform', 'translate(-50%, -50%)');
        this.renderer.setStyle(element, 'pointer-events', 'none');
        this.renderer.setStyle(element, 'opacity', '0');
        this.renderer.setStyle(element, 'z-index', '1');
        // Append to parent
        this.renderer.appendChild(parent, element);
    }
    createCheckmarkSvg() {
        // Create SVG element from string
        const tempDiv = this.renderer.createElement('div');
        this.renderer.setProperty(tempDiv, 'innerHTML', this.checkSvgContent);
        this.checkmarkSvg = tempDiv.firstElementChild;
        this.createOverlayElement(this.checkmarkSvg);
    }
    createIndeterminateBar() {
        // Create the indeterminate bar element
        this.indeterminateBar = this.renderer.createElement('span');
        this.renderer.setStyle(this.indeterminateBar, 'height', '1.5px');
        this.renderer.setStyle(this.indeterminateBar, 'background', 'var(--ref-color-white)');
        this.renderer.setStyle(this.indeterminateBar, 'width', '8px');
        this.createOverlayElement(this.indeterminateBar);
    }
    updateCheckmarkVisibility() {
        if (this.checkmarkSvg) {
            const opacity = this.checked() && !this.indeterminate() ? '1' : '0';
            this.renderer.setStyle(this.checkmarkSvg, 'opacity', opacity);
        }
        if (this.indeterminateBar) {
            const opacity = this.indeterminate() && !this.checked() ? '1' : '0';
            this.renderer.setStyle(this.indeterminateBar, 'opacity', opacity);
        }
    }
    setupEventListeners() {
        const input = this.elementRef.nativeElement;
        // Input change listener (native checkbox change)
        const changeListener = this.renderer.listen(input, 'change', () => {
            this.onValueChange();
        });
        this.listeners.push(changeListener);
        // Listen for label clicks to ensure focus is maintained
        const parent = input.parentElement;
        if (parent) {
            const labelClickListener = this.renderer.listen(parent, 'click', (event) => {
                const target = event.target;
                // If clicking on a label that targets our input, ensure focus
                if (target.tagName === 'LABEL' && target.getAttribute('for') === input.id) {
                    // Small delay to ensure the label click is processed first
                    setTimeout(() => {
                        input.focus();
                    }, 0);
                }
            });
            this.listeners.push(labelClickListener);
        }
    }
    applyCheckboxStyles() {
        const styles = `
            /* Minimal checkbox styling */
            input[type="checkbox"].ap-checkbox-styled {
                appearance: none !important;
                -webkit-appearance: none !important;
                -moz-appearance: none !important;
                
                display: inline-block !important;
                width: 16px !important;
                height: 16px !important;
                min-width: 16px !important;
                min-height: 16px !important;
                margin: 0 !important;
                padding: 0 !important;
                border: 1px solid var(--ref-color-grey-60);
                border-radius: var(--sys-border-radius-sm);
                background: var(--ref-color-white);
                box-sizing: border-box;
                cursor: pointer;
                vertical-align: middle;
            }
            
            /* Hover state */
            input[type="checkbox"].ap-checkbox-styled:hover {
                border-color: var(--ref-color-grey-80);
            }
            
            /* Active/pressed state */
            input[type="checkbox"].ap-checkbox-styled:active {
                border-color: var(--ref-color-grey-100);
            }
            
            /* Checked state */
            input[type="checkbox"].ap-checkbox-styled:checked {
                background: var(--ref-color-electric-blue-100);
                border-color: var(--ref-color-electric-blue-100);
            }
            
            /* Checked hover state */
            input[type="checkbox"].ap-checkbox-styled:checked:hover {
                background: var(--ref-color-electric-blue-80);
                border-color: var(--ref-color-electric-blue-100);
            }
            
            /* Checked active/pressed state */
            input[type="checkbox"].ap-checkbox-styled:checked:active {
                background: var(--ref-color-electric-blue-60);
                border-color: var(--ref-color-electric-blue-100);
            }
            
            /* Indeterminate state */
            input[type="checkbox"].ap-checkbox-styled:indeterminate {
                background: var(--ref-color-electric-blue-100);
                border-color: var(--ref-color-electric-blue-100);
            }
            
            /* Disabled state */
            input[type="checkbox"].ap-checkbox-styled:disabled {
                border-color: var(--ref-color-grey-20);
                background: var(--ref-color-grey-10);
                cursor: default;
            }
            
            input[type="checkbox"].ap-checkbox-styled:disabled:checked {
                background: var(--ref-color-grey-20);
            }
            
            /* Focus state */
            @media (hover: hover) {
                input[type="checkbox"].ap-checkbox-styled:focus:not(.disabled) {
                    outline: 3px solid var(--ref-color-electric-blue-100) !important;
                    outline-offset: 1px !important;
                }
            }
            
            /* Label styling */
            input[type="checkbox"].ap-checkbox-styled + label {
                display: flex;
                align-items: center;
                font-family: var(--comp-forms-label-font-family);
                font-size: var(--comp-forms-label-size);
                font-weight: var(--comp-forms-label-font-weight);
                line-height: var(--comp-forms-label-line-height);
                color: var(--comp-forms-label-text-color);
                cursor: pointer;
            }
            
            /* Empty label styling */
            input[type="checkbox"].ap-checkbox-styled + label:empty {
                display: none;
            }
            
            /* Disabled label styling */
            input[type="checkbox"].ap-checkbox-styled:disabled + label {
                color: var(--ref-color-grey-60);
                cursor: default;
            }
        `;
        // Create and append style element
        this.styleElement = this.renderer.createElement('style');
        this.renderer.appendChild(this.styleElement, this.renderer.createText(styles));
        this.renderer.appendChild(document.head, this.styleElement);
    }
    onValueChange() {
        if (!this.elementRef.nativeElement.disabled) {
            const input = this.elementRef.nativeElement;
            if (this.indeterminate()) {
                // When indeterminate, clicking should go to checked state
                this._checked.set(true);
                this._indeterminate.set(false);
                input.checked = true;
                input.indeterminate = false;
            }
            else {
                // Normal toggle behavior
                this._checked.set(input.checked);
            }
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CheckboxDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.3.18", type: CheckboxDirective, isStandalone: true, selector: "input[type=\"checkbox\"][apCheckbox]", inputs: { checkedInput: ["checked", "checkedInput"], indeterminateInput: ["indeterminate", "indeterminateInput", booleanAttribute] }, providers: [], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: CheckboxDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[type="checkbox"][apCheckbox]',
                    standalone: true,
                    providers: [],
                }]
        }], ctorParameters: () => [], propDecorators: { checkedInput: [{
                type: Input,
                args: ['checked']
            }], indeterminateInput: [{
                type: Input,
                args: [{
                        transform: booleanAttribute,
                        alias: 'indeterminate',
                    }]
            }] } });

class DefaultImageDirective {
    src = '';
    default = '';
    updateUrl() {
        if (this.default) {
            this.src = this.default;
        }
        else {
            this.src = 'assets/lib-ui-components/img/default-avatar.png';
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DefaultImageDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: DefaultImageDirective, isStandalone: true, selector: "img[default]", inputs: { src: "src", default: "default" }, host: { listeners: { "error": "updateUrl()" }, properties: { "src": "src" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: DefaultImageDirective, decorators: [{
            type: Directive,
            args: [{
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    selector: 'img[default]',
                    standalone: true,
                    host: {
                        '(error)': 'updateUrl()',
                        '[src]': 'src',
                    },
                }]
        }], propDecorators: { src: [{
                type: Input,
                args: [{
                        required: true,
                    }]
            }], default: [{
                type: Input
            }] } });

/**
 * Removes excess text from element until it fits in elements
 * and appends a ellipsis symbol to end of text. This requires that
 * the elements height be fixed
 *
 * @example
 * ```html
 * <p apEllipsis>Ullamco esse laborum</p>
 * ```
 *
 */
class EllipsisDirective {
    el;
    apEllipsisSeparator = '';
    apEllipsisClip = false;
    apEllipsisIndex = -2;
    apEllipsisChar = '...';
    apEllipsisClickable = false;
    apEllipsisRemovedElementsCount = new EventEmitter();
    apEllipsisRemovedText = new EventEmitter();
    get hasOverflow() {
        const el = this.el.nativeElement;
        return el.scrollHeight > el.offsetHeight || el.scrollWidth > el.offsetWidth;
    }
    constructor(el) {
        this.el = el;
    }
    ngAfterContentChecked() {
        this.clipText();
    }
    clipText() {
        const el = this.el.nativeElement;
        let text = el.innerText;
        let removedText = '';
        if (this.apEllipsisIndex > -1) {
            removedText = text.substring(this.apEllipsisIndex, text.length - 1) + removedText;
            text = text.substring(0, this.apEllipsisIndex);
            el.innerText = `${text}${this.apEllipsisChar}`;
            if (this.apEllipsisClickable) {
                el.addEventListener('click', () => {
                    el.innerText = `${text}${removedText}`;
                });
            }
        }
        else {
            while (this.hasOverflow && text.length > 0) {
                removedText = text[text.length - 1] + removedText;
                text = text.substring(0, text.length - 1);
                el.innerText = `${text}${this.apEllipsisChar}`;
            }
        }
        if (this.apEllipsisSeparator) {
            const removedElementsCount = removedText
                .split(this.apEllipsisSeparator)
                .filter(element => !!element && element.length > 0).length;
            if (removedElementsCount > 0) {
                this.apEllipsisRemovedElementsCount.emit(removedElementsCount);
            }
        }
        if (removedText && removedText.length > 0) {
            this.apEllipsisRemovedText.emit(removedText);
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: EllipsisDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: EllipsisDirective, isStandalone: true, selector: "[apEllipsis]", inputs: { apEllipsisSeparator: "apEllipsisSeparator", apEllipsisClip: "apEllipsisClip", apEllipsisIndex: "apEllipsisIndex", apEllipsisChar: "apEllipsisChar", apEllipsisClickable: "apEllipsisClickable" }, outputs: { apEllipsisRemovedElementsCount: "apEllipsisRemovedElementsCount", apEllipsisRemovedText: "apEllipsisRemovedText" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: EllipsisDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[apEllipsis]',
                    standalone: true,
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { apEllipsisSeparator: [{
                type: Input
            }], apEllipsisClip: [{
                type: Input
            }], apEllipsisIndex: [{
                type: Input
            }], apEllipsisChar: [{
                type: Input
            }], apEllipsisClickable: [{
                type: Input
            }], apEllipsisRemovedElementsCount: [{
                type: Output
            }], apEllipsisRemovedText: [{
                type: Output
            }] } });

// Based on https://scotch.io/tutorials/how-to-implement-a-custom-validator-directive-confirm-password-in-angular-2
class EqualValidatorDirective {
    validateEqual;
    validateEqualReference;
    constructor(validateEqual, validateEqualReference) {
        this.validateEqual = validateEqual;
        this.validateEqualReference = validateEqualReference;
    }
    validate(self) {
        const other = self.root.get(this.validateEqual);
        if (other) {
            if (this.isReference()) {
                if (self.value === other.value) {
                    if (other.errors) {
                        delete other.errors['validateEqual'];
                        if (!Object.keys(other.errors).length) {
                            other.setErrors(null);
                        }
                    }
                    else {
                        other.setErrors(null);
                    }
                }
                else {
                    other.setErrors({ validateEqual: false });
                }
            }
            else if (self.value !== other.value) {
                return { validateEqual: false };
            }
        }
        return null;
    }
    isReference() {
        if (!this.validateEqualReference) {
            return false;
        }
        return this.validateEqualReference === 'true';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: EqualValidatorDirective, deps: [{ token: 'validateEqual', attribute: true }, { token: 'validateEqualReference', attribute: true }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: EqualValidatorDirective, isStandalone: true, selector: "[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]", providers: [
            {
                provide: NG_VALIDATORS,
                useExisting: forwardRef(() => EqualValidatorDirective),
                multi: true,
            },
        ], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: EqualValidatorDirective, decorators: [{
            type: Directive,
            args: [{
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
                    providers: [
                        {
                            provide: NG_VALIDATORS,
                            useExisting: forwardRef(() => EqualValidatorDirective),
                            multi: true,
                        },
                    ],
                    standalone: true,
                }]
        }], ctorParameters: () => [{ type: undefined, decorators: [{
                    type: Attribute,
                    args: ['validateEqual']
                }] }, { type: undefined, decorators: [{
                    type: Attribute,
                    args: ['validateEqualReference']
                }] }] });

class GifService {
    static isGif(src) {
        return src && src.split('?')[0].endsWith('.gif');
    }
}
/**
 * If the image is a GIF then replace the img element by a canvas containing a frozen gif.
 * Note 1: if the image is displayed under a condition, the condition must be applied on the parent of the image, so the
 * new canvas element will have the same condition.
 * Note 2: the image must not have the properties "display" and "visibility" in its style. Since they are used to frozen
 * the GIF. You need to apply this properties on the parent element.
 * Note 3: If the GIF is frozen, all the event are propagated to the image. However, all events are dispatched
 * with an Event instance. Ex: click event is not dispatched with a MouseEvent instance.
 */
class FrozenGifDirective {
    elementRef;
    src = '';
    apFrozen = true;
    // Add all the events that need to be propagated.
    apGifEvents = ['click'];
    element;
    canvas = null;
    constructor(elementRef) {
        this.elementRef = elementRef;
        const element = this.elementRef.nativeElement;
        if (!(element instanceof HTMLImageElement)) {
            return;
        }
        this.element = element;
    }
    ngOnChanges(changes) {
        let freeze = false;
        if (changes.src) {
            freeze = true;
        }
        if (changes.frozen) {
            if (changes.frozen.currentValue) {
                freeze = true;
            }
            else {
                this.unfreeze();
            }
        }
        if (freeze) {
            this.freeze();
        }
    }
    freeze() {
        if (!GifService.isGif(this.src) || !this.apFrozen) {
            this.unfreeze();
            return;
        }
        // hack to avoid displaying the GIF before replacing it by the canvas
        this.element.style.visibility = 'hidden';
        this.element.addEventListener('load', () => this.addCanvas());
    }
    addCanvas() {
        if (this.canvas) {
            this.canvas.remove();
        }
        this.canvas = document.createElement('canvas');
        this.canvas.width = this.element.width;
        this.canvas.height = this.element.height;
        this.canvas.getContext('2d')?.drawImage(this.element, 0, 0, this.canvas.width, this.canvas.height);
        for (let i = 0; i < this.element.attributes.length; i++) {
            const attr = this.element.attributes[i];
            if (attr.name === 'id') {
                // avoid two elements with the same id
                this.canvas.setAttribute('id', attr.value + '_frozenGif');
            }
            else if ((attr.name === 'style' && attr.value.includes('visibility: hidden;')) || attr.value.includes('display: none;')) {
                // remove the added 'visibility: hidden' and 'display: none'
                const styleValue = attr.value;
                this.canvas.setAttribute('style', styleValue.replace('visibility: hidden;', '').replace('display: none;', ''));
            }
            else if (attr.name !== '"') {
                // test for invalid attributes
                this.canvas.setAttribute(attr.name, attr.value);
            }
        }
        this.addEvents();
        this.element.parentNode?.insertBefore(this.canvas, this.element);
        this.element.style.display = 'none';
    }
    addEvents() {
        this.apGifEvents.forEach((eventName) => {
            this.canvas?.addEventListener(eventName, (ev) => this.element.dispatchEvent(
            // wm: find a way to dispatch the right event type
            new Event(ev.type, ev)));
        });
    }
    unfreeze() {
        if (this.canvas) {
            this.canvas.remove();
            this.canvas = null;
        }
        this.element.style.visibility = 'inherit';
        this.element.style.display = 'inherit';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FrozenGifDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: FrozenGifDirective, isStandalone: true, selector: "img[apFrozenGif]", inputs: { src: "src", apFrozen: "apFrozen", apGifEvents: "apGifEvents" }, host: { properties: { "src": "src" } }, usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: FrozenGifDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'img[apFrozenGif]',
                    host: {
                        '[src]': 'src',
                    },
                    standalone: true,
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { src: [{
                type: Input,
                args: [{
                        required: true,
                    }]
            }], apFrozen: [{
                type: Input
            }], apGifEvents: [{
                type: Input
            }] } });

const DATA_MST = 'data-mst';
/**
 * This directive aims to parse simple string to extract some specific tags and to turn them into SPAN with styling classes attributes and optional event listening.
 * The specific tags must this schema: <ng-container data-mst="STYLING-CLASSES">TEXT</ng-container>.
 * Example: 'Lorem <ng-container data-mst="my-style">ipsum</ng-container> dolor sit amet'.
 */
class MultiStyleTextDirective {
    elRef;
    renderer;
    set multiStyleText(fullText) {
        // First remove previously added children (on update).
        this.renderer.setProperty(this.elRef.nativeElement, 'innerHTML', '');
        if (!fullText || fullText.length <= 0) {
            return;
        }
        this.renderer.setProperty(this.elRef.nativeElement, 'innerHTML', DOMPurify.sanitize(fullText.replace(/ng-container/g, 'span')));
        Array.from(this.elRef.nativeElement.children).forEach((childNode) => {
            if (childNode.nodeType == 1 && childNode.tagName.toLowerCase() === 'span') {
                // Node.ELEMENT_NODE
                const span = this.renderer.createElement('span');
                span.innerHTML = childNode.innerHTML;
                this.elRef.nativeElement.replaceChild(span, childNode);
                const mstValue = childNode.getAttribute(DATA_MST);
                if (mstValue) {
                    const mstContents = mstValue.split(';');
                    // Bind click events
                    if (mstContents[1]) {
                        this.renderer.listen(span, 'click', () => this.partEvent.emit(mstContents[1]));
                    }
                    // Add classes
                    if (mstContents[0] && mstContents[0].length > 0) {
                        this.renderer.setAttribute(span, 'class', mstContents[0].replace(',', ' '));
                    }
                }
            }
        });
    }
    partEvent = new EventEmitter();
    constructor(elRef, renderer) {
        this.elRef = elRef;
        this.renderer = renderer;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MultiStyleTextDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: MultiStyleTextDirective, isStandalone: true, selector: "[multiStyleText]", inputs: { multiStyleText: "multiStyleText" }, outputs: { partEvent: "partEvent" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: MultiStyleTextDirective, decorators: [{
            type: Directive,
            args: [{
                    // eslint-disable-next-line @angular-eslint/directive-selector
                    selector: '[multiStyleText]',
                    standalone: true,
                }]
        }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { multiStyleText: [{
                type: Input
            }], partEvent: [{
                type: Output
            }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { AutosizeTextareaDirective, BaseButtonDirective, CheckboxDirective, DefaultImageDirective, EllipsisDirective, EqualValidatorDirective, FrozenGifDirective, GifService, MultiStyleTextDirective };
//# sourceMappingURL=agorapulse-ui-components-directives.mjs.map
