UNPKG

@highcharts/dashboards

Version:
4,809 lines 201 kB
/**
 * @license Highcharts Dashboards Layout 3.5.0 (2025-07-14)
 *
 * (c) 2009-2025 Highsoft AS
 *
 * License: www.highcharts.com/license
 */
(function (factory) {
    if (typeof module === 'object' && module.exports) {
        factory['default'] = factory;
        module.exports = factory;
    } else if (typeof define === 'function' && define.amd) {
        define('dashboards/modules/layout', ['dashboards'], function (Dashboards) {
            factory(Dashboards);
            factory.Dashboards = Dashboards;
            return factory;
        });
    } else {
        factory(typeof Dashboards !== 'undefined' ? Dashboards : undefined);
    }
}(function (Dashboards) {
    'use strict';
    var _modules = Dashboards ? Dashboards._modules : {};
    function _registerModule(obj, path, args, fn) {
        if (!obj.hasOwnProperty(path)) {
            obj[path] = fn.apply(null, args);

            if (typeof CustomEvent === 'function') {
                Dashboards.win.dispatchEvent(new CustomEvent(
                    'DashboardsModuleLoaded',
                    { detail: { path: path, module: obj[path] } }
                ));
            }
        }
    }
    _registerModule(_modules, 'Dashboards/EditMode/EditRenderer.js', [_modules['Dashboards/EditMode/EditGlobals.js'], _modules['Core/Utilities.js']], function (EditGlobals, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { merge, createElement, defined } = U;
        /* *
         *
         *  Functions
         *
         * */
        /**
         * Function to create a context button.
         * @internal
         *
         * @param parentElement
         * The element to which the new element should be appended.
         *
         * @param editMode
         * EditMode instance.
         *
         * @returns
         * Context button element.
         */
        function renderContextButton(parentNode, editMode) {
            const contextMenuOptions = editMode.options.contextMenu;
            let contextButton;
            if (contextMenuOptions) {
                contextButton = createElement('button', {
                    className: EditGlobals.classNames.contextMenuBtn,
                    onclick: function (event) {
                        event.stopPropagation();
                        editMode.onContextBtnClick();
                    }
                }, {}, parentNode);
                // Add the icon if defined.
                if (contextMenuOptions.icon) {
                    createElement('img', {
                        src: contextMenuOptions.icon,
                        className: EditGlobals.classNames.icon
                    }, {}, contextButton);
                }
                // Add text next to the icon if defined.
                if (contextMenuOptions.text) {
                    createElement('span', {
                        className: EditGlobals.classNames.contextMenuBtnText,
                        textContent: contextMenuOptions.text
                    }, {}, contextButton);
                }
                contextButton.setAttribute('aria-label', editMode.lang.accessibility.contextMenu.button);
                contextButton.setAttribute('aria-expanded', 'false');
            }
            return contextButton;
        }
        /**
         * Creates the collapsable header element.
         * @internal
         *
         * @param parentElement
         * The HTMLElement to which the element should be rendered to.
         *
         * @param options
         * Nested header options.
         *
         * @returns the outer element and content in the collapsable div.
         */
        function renderCollapseHeader(parentElement, options) {
            const { name, showToggle, onchange, isEnabled, isNested, isStandalone, lang } = options;
            const accordion = createElement('div', {
                className: EditGlobals.classNames[(isNested ? 'accordionNestedWrapper' : 'accordionContainer')] + ' ' +
                    (isStandalone ?
                        EditGlobals.classNames.accordionStandaloneWrapper : '') + ' ' + EditGlobals.classNames.collapsableContentHeader
            }, {}, parentElement);
            const header = createElement('div', {
                className: EditGlobals.classNames.accordionHeader
            }, {}, accordion);
            let headerBtn;
            if (!isStandalone || showToggle) {
                headerBtn = createElement(isStandalone && showToggle ? 'span' : 'button', {
                    className: EditGlobals.classNames[isStandalone ?
                        'accordionHeaderWrapper' : 'accordionHeaderBtn']
                }, {}, header);
            }
            createElement('span', {
                textContent: lang[name] || name
            }, {}, headerBtn);
            if (showToggle && header) {
                renderToggle(header, {
                    enabledOnOffLabels: true,
                    id: name,
                    name: '',
                    onchange: onchange,
                    value: isEnabled || false,
                    lang
                });
            }
            if (!isStandalone) {
                const headerIcon = createElement('span', {
                    className: EditGlobals.classNames.accordionHeaderIcon + ' ' +
                        EditGlobals.classNames.collapsedElement
                }, {}, headerBtn);
                headerBtn?.addEventListener('click', function () {
                    content.classList.toggle(EditGlobals.classNames.hiddenElement);
                    headerIcon?.classList.toggle(EditGlobals.classNames.collapsedElement);
                });
            }
            const content = createElement('div', {
                className: EditGlobals.classNames.accordionContent + ' ' +
                    (isStandalone ?
                        EditGlobals.classNames.standaloneElement :
                        EditGlobals.classNames.hiddenElement)
            }, {}, accordion);
            return { outerElement: accordion, content: content };
        }
        /**
         * Function to create select element.
         *
         * @param parentElement
         * The element to which the new element should be appended.
         *
         * @param options
         * Select form field options.
         *
         * @returns
         * Select element
         */
        function renderSelect(parentElement, options) {
            if (!parentElement) {
                return;
            }
            if (options.name) {
                renderText(parentElement, { title: options.name, isLabel: true });
            }
            const iconsURLPrefix = options.iconsURLPrefix || '';
            const customSelect = createElement('div', {
                className: EditGlobals.classNames.dropdown +
                    ' ' +
                    EditGlobals.classNames.collapsableContentHeader
            }, {}, parentElement);
            const btn = createElement('button', {
                className: EditGlobals.classNames.dropdownButton
            }, {}, customSelect);
            const btnContent = createElement('div', {
                className: EditGlobals.classNames.dropdownButtonContent
            }, {}, btn);
            const iconURL = (U.find(options.selectOptions, (item) => item.name === options.value) || {}).iconURL;
            let headerIcon;
            if (iconURL) {
                headerIcon = createElement('img', {
                    src: iconsURLPrefix + iconURL,
                    className: EditGlobals.classNames.icon
                }, {}, btnContent);
            }
            const placeholder = createElement('span', {
                textContent: options.value,
                id: options.id || ''
            }, {}, btnContent);
            const dropdownPointer = createElement('img', {
                className: EditGlobals.classNames.dropdownIcon +
                    ' ' +
                    EditGlobals.classNames.collapsedElement,
                src: iconsURLPrefix + 'dropdown-pointer.svg'
            }, {}, btn);
            const dropdown = createElement('ul', {
                className: EditGlobals.classNames.dropdownContent +
                    ' ' +
                    EditGlobals.classNames.hiddenElement
            }, {}, customSelect);
            btn.addEventListener('click', function () {
                dropdown.classList.toggle(EditGlobals.classNames.hiddenElement);
                dropdownPointer.classList.toggle(EditGlobals.classNames.collapsedElement);
            });
            for (let i = 0, iEnd = options.selectOptions.length; i < iEnd; ++i) {
                renderSelectElement(merge(options.selectOptions[i] || {}, { iconsURLPrefix }), dropdown, placeholder, options.id, dropdownPointer, headerIcon, options.onchange);
            }
            return customSelect;
        }
        /**
         * @internal
         */
        function renderSelectElement(option, dropdown, placeholder, id, dropdownPointer, headerIcon, callback) {
            const iconURL = option.iconsURLPrefix + option.iconURL;
            const selectOption = createElement('li', {}, {}, dropdown);
            const selectOptionBtn = createElement('button', { className: EditGlobals.classNames.customSelectButton }, {}, selectOption);
            if (option.iconURL) {
                createElement('img', {
                    src: iconURL
                }, {}, selectOptionBtn);
            }
            createElement('span', { textContent: option.name || '' }, {}, selectOptionBtn);
            selectOptionBtn.addEventListener('click', function () {
                dropdown.classList.add(EditGlobals.classNames.hiddenElement);
                dropdownPointer.classList.toggle(EditGlobals.classNames.collapsedElement);
                placeholder.textContent = option.name || '';
                if (headerIcon && option.iconURL) {
                    headerIcon.src = iconURL;
                }
                if (callback) {
                    return callback(option.name);
                }
            });
        }
        /**
         * Function to create toggle element.
         *
         * @param parentElement
         * The element to which the new element should be appended.
         *
         * @param options
         * Form field options.
         *
         * @returns
         * Toggle element.
         */
        function renderToggle(parentElement, options) {
            if (!parentElement) {
                return;
            }
            const lang = options.lang, value = options.value, title = options.title || options.name, langKey = options.langKey;
            if (options.isNested) {
                const labeledToggleWrapper = createElement('div', {
                    className: EditGlobals.classNames.labeledToggleWrapper
                }, {}, parentElement);
                parentElement = labeledToggleWrapper;
            }
            const toggleContainer = createElement('button', {
                className: EditGlobals.classNames.toggleContainer,
                type: 'button',
                role: 'switch',
                ariaChecked: false,
                ariaLabel: langKey ? lang.accessibility[langKey][options.name] : ''
            }, {}, parentElement);
            if (title) {
                renderText(options.isNested ? parentElement : toggleContainer, { title });
            }
            if (options.enabledOnOffLabels) {
                renderText(toggleContainer, {
                    title: lang.off,
                    className: EditGlobals.classNames.toggleLabels
                });
            }
            const toggle = createElement('label', {
                className: EditGlobals.classNames.toggleWrapper +
                    ' ' + (options.className || '')
            }, {}, toggleContainer);
            const input = renderCheckbox(toggle, value), callbackFn = options.onchange;
            callbackFn && toggleContainer.addEventListener('click', (e) => {
                callbackFn(!input.checked);
                input.checked = !input.checked;
                toggleContainer.setAttribute('aria-checked', input.checked);
                e.stopPropagation();
            });
            const slider = createElement('span', {
                className: EditGlobals.classNames.toggleSlider
            }, {}, toggle);
            callbackFn && slider.addEventListener('click', (e) => {
                e.preventDefault();
            });
            if (options.enabledOnOffLabels) {
                renderText(toggleContainer, {
                    title: lang.on,
                    className: EditGlobals.classNames.toggleLabels
                });
            }
            return toggleContainer;
        }
        /**
         * Function to create text element.
         *
         * @param parentElement
         * The element to which the new element should be appended
         *
         * @param text
         * Text to be displayed
         *
         * @param callback
         * Callback function to be fired on the click
         *
         * @returns text Element
         */
        function renderText(parentElement, options) {
            let textElem;
            const { title: text, className, isLabel } = options;
            if (parentElement) {
                const labelFor = isLabel ? { htmlFor: text } : {};
                textElem = createElement(isLabel ? 'label' : 'div', {
                    className: EditGlobals.classNames.labelText + ' ' + (className || ''),
                    textContent: text,
                    ...labelFor
                }, {}, parentElement);
            }
            return textElem;
        }
        /**
         * Function to create Icon element.
         *
         * @param parentElement
         * The element to which the new element should be appended.
         *
         * @param icon
         * Icon URL
         *
         * @param callback
         * Callback function
         *
         * @returns
         * Icon Element
         */
        function renderIcon(parentElement, options) {
            const { icon, callback } = options;
            if (!parentElement) {
                return;
            }
            const iconElem = createElement('div', {
                onclick: callback,
                className: options.className || ''
            }, {}, parentElement);
            iconElem.style['background-image'] = 'url(' + icon + ')';
            const mousedown = options.mousedown;
            const click = options.click;
            if (mousedown) {
                iconElem.onmousedown = function () {
                    mousedown.apply(this, arguments);
                };
            }
            if (click) {
                iconElem.addEventListener('click', function () {
                    click.apply(this, arguments);
                });
            }
            return iconElem;
        }
        /**
         * Function to create input element.
         *
         * @param parentElement
         * the element to which the new element should be appended
         *
         * @param options
         * Form field options
         *
         * @returns
         * Input Element
         */
        function renderInput(parentElement, options) {
            if (!parentElement) {
                return;
            }
            if (options.name) {
                renderText(parentElement, { title: options.name, isLabel: true });
            }
            const input = createElement('input', {
                type: 'text',
                onclick: options.callback,
                id: options.id || '',
                name: options.name || '',
                value: ((defined(options.value) &&
                    options.value.toString().replace(/\"/g, '')) || '')
            }, {}, parentElement);
            const onchange = options.onchange;
            if (onchange) {
                input.addEventListener('change', function (e) {
                    onchange(e.target.value);
                });
            }
            return input;
        }
        /**
         * Function to create textarea element.
         *
         * @param parentElement
         * The element to which the new element should be appended
         *
         * @param options
         * Form field options
         *
         * @returns
         * textarea Element
         */
        function renderTextarea(parentElement, options) {
            if (!parentElement) {
                return;
            }
            if (options.name) {
                renderText(parentElement, { title: options.name, isLabel: true });
            }
            const textarea = createElement('textarea', {
                id: options.id,
                name: options.name,
                value: options.value || ''
            }, {}, parentElement);
            const onchange = options.onchange;
            if (onchange) {
                textarea.addEventListener('change', function (e) {
                    onchange(e.target.value);
                });
            }
            return textarea;
        }
        /**
         * Function to render the input of type checkbox.
         *
         * @param parentElement
         * An element to which render the checkbox to
         *
         * @param checked
         * Whether the checkbox should be checked or not.
         *
         * @returns
         * The checkbox element
         */
        function renderCheckbox(parentElement, checked) {
            let input;
            if (parentElement) {
                input = createElement('input', {
                    type: 'checkbox',
                    checked: !!checked
                }, {}, parentElement);
            }
            return input;
        }
        /**
         * Function to create button element.
         *
         * @param parentElement
         * the element to which the new element should be appended
         *
         * @param options
         * Button field options
         *
         * @returns
         * Button Element
         */
        function renderButton(parentElement, options) {
            if (!parentElement) {
                return;
            }
            const button = createElement('button', {
                className: (EditGlobals.classNames.button + ' ' +
                    (options.className || '')),
                onclick: options.callback,
                textContent: options.text
            }, options.style || {}, parentElement);
            if (options.icon) {
                button.style['background-image'] =
                    'url(' + options.icon + ')';
            }
            return button;
        }
        /**
         * Get the renderer function based on the type of the element to render.
         *
         * @param type
         * Type of the element to render
         *
         * @returns
         * function to render a specific element
         */
        function getRendererFunction(type) {
            return {
                select: renderSelect,
                toggle: renderToggle,
                text: renderText,
                collapse: renderCollapseHeader,
                icon: renderIcon,
                contextButton: renderContextButton,
                input: renderInput,
                textarea: renderTextarea,
                checkbox: renderCheckbox,
                button: renderButton
            }[type];
        }
        const EditRenderer = {
            renderSelect,
            renderToggle,
            renderText,
            renderCollapseHeader,
            renderIcon,
            renderContextButton,
            renderInput,
            renderTextarea,
            renderCheckbox,
            renderButton,
            getRendererFunction
        };

        return EditRenderer;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Menu/MenuItem.js', [_modules['Dashboards/EditMode/EditGlobals.js'], _modules['Core/Utilities.js'], _modules['Dashboards/EditMode/EditRenderer.js']], function (EditGlobals, U, EditRenderer) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { createElement, merge } = U;
        class MenuItem {
            /* *
            *
            *  Constructor
            *
            * */
            constructor(menu, options) {
                this.menu = menu;
                this.isActive = false;
                this.options = merge(MenuItem.defaultOptions, options);
                this.container = this.setContainer();
                this.innerElement = this.setInnerElement();
            }
            /* *
            *
            *  Functions
            *
            * */
            setContainer() {
                const item = this, options = item.options;
                let className = EditGlobals.classNames.menuItem;
                if (item.menu.options.itemsClassName) {
                    className += ' ' + item.menu.options.itemsClassName;
                }
                if (options.className) {
                    className += ' ' + options.className;
                }
                return createElement('div', { className: className || '' }, merge(this.options.style || {}, 
                // To remove
                this.isActive ? { display: 'block' } : {}), this.menu.container);
            }
            setInnerElement() {
                const item = this, options = item.options, container = item.container, langKey = options.langKey;
                if (options.type === 'toggle') {
                    return EditRenderer.renderToggle(container, {
                        id: options.id,
                        name: options.id,
                        title: langKey ?
                            this.menu.editMode.lang[langKey] :
                            options.text,
                        value: !!(options.getValue && options.getValue(item)),
                        lang: this.menu.editMode.lang,
                        langKey: langKey,
                        onchange: options.events?.click?.bind(item)
                    });
                }
                if (options.type === 'text') {
                    return EditRenderer.renderText(container, {
                        title: langKey ?
                            this.menu.editMode.lang[langKey] :
                            options.text || '',
                        className: options.className || ''
                    });
                }
                if (options.type === 'icon') {
                    return EditRenderer.renderIcon(container, {
                        icon: options.icon || '',
                        mousedown: options.events?.onmousedown?.bind(item),
                        click: options.events?.click?.bind(item)
                    });
                }
                if (options.type === 'button') {
                    return EditRenderer.renderButton(container, {
                        callback: options.events?.click?.bind(item),
                        className: options.className || '',
                        style: options.style || {},
                        text: langKey ?
                            this.menu.editMode.lang[langKey] :
                            (options.text || '')
                    });
                }
            }
            update() {
                const item = this, options = item.options;
                if (options.events && options.events.update) {
                    options.events.update.apply(item, arguments);
                }
            }
            activate() {
                const item = this;
                item.update();
                // Temp.
                if (item.container) {
                    item.isActive = true;
                    item.container.style.display = 'block';
                }
            }
            deactivate() {
                const item = this;
                // Temp.
                if (item.container) {
                    item.isActive = false;
                    item.container.style.display = 'none';
                }
            }
        }
        /* *
        *
        *  Static Properties
        *
        * */
        MenuItem.defaultOptions = {
            type: 'text'
        };

        return MenuItem;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Menu/MenuItemBindings.js', [], function () {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const MenuItemBindings = {
            /* *
            *
            *  Context menu
            *
            * */
            viewFullscreen: {
                id: 'viewFullscreen',
                type: 'button',
                langKey: 'viewFullscreen',
                events: {
                    click: function () {
                        const fullScreen = this.menu.editMode.board.fullscreen;
                        if (fullScreen) {
                            fullScreen.toggle();
                        }
                    }
                }
            }
        };

        return MenuItemBindings;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Menu/Menu.js', [_modules['Dashboards/EditMode/EditGlobals.js'], _modules['Core/Utilities.js'], _modules['Dashboards/EditMode/Menu/MenuItem.js'], _modules['Dashboards/EditMode/Menu/MenuItemBindings.js']], function (EditGlobals, U, MenuItem, MenuItemBindings) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { createElement, merge } = U;
        class Menu {
            /* *
            *
            *  Constructor
            *
            * */
            constructor(parentElement, options, editMode, parent) {
                this.parentElement = parentElement;
                this.isVisible = false;
                this.activeItems = [];
                this.options = options;
                this.items = {};
                this.editMode = editMode;
                if (parent) {
                    this.parent = parent;
                }
                this.container = this.setContainer();
            }
            /* *
            *
            *  Functions
            *
            * */
            setContainer() {
                return createElement('div', {
                    className: EditGlobals.classNames.menu +
                        ' ' + (this.options.className || '')
                }, {}, this.parentElement);
            }
            // ItemsSchemas - default items definitions.
            initItems(itemsSchemas, activeItems) {
                const menu = this, optionsItems = menu.options.items || [];
                let itemSchema, itemConfig, item, options;
                for (let i = 0, iEnd = optionsItems.length; i < iEnd; ++i) {
                    itemConfig = optionsItems[i];
                    itemSchema =
                        typeof itemConfig === 'string' ? itemsSchemas[itemConfig] :
                            itemConfig.id ? itemsSchemas[itemConfig.id] :
                                {};
                    options = typeof itemConfig === 'string' ?
                        merge(itemSchema, { id: itemConfig }) :
                        merge(itemSchema, itemConfig);
                    if (options.id) {
                        item = new MenuItem(menu, options);
                        // Save initialized item.
                        menu.items[item.options.id] = item;
                        if (activeItems) {
                            item.activate();
                            menu.activeItems.push(item);
                        }
                    }
                    else {
                        // Error - defined item needs an id.
                    }
                }
            }
            setActiveItems(items) {
                const menu = this;
                let item;
                // Deactivate items.
                for (let i = 0, iEnd = menu.activeItems.length; i < iEnd; ++i) {
                    if (items.indexOf(menu.activeItems[i].options.id) === -1) {
                        menu.activeItems[i].deactivate();
                    }
                }
                menu.activeItems.length = 0;
                for (let j = 0, jEnd = items.length; j < jEnd; ++j) {
                    item = menu.items[items[j]];
                    if (item) {
                        // Activate item.
                        if (!item.isActive) {
                            item.activate();
                        }
                        else {
                            item.update();
                        }
                        menu.activeItems.push(item);
                    }
                }
            }
            deactivateActiveItems() {
                const menu = this;
                for (let i = 0, iEnd = menu.activeItems.length; i < iEnd; ++i) {
                    menu.activeItems[i].deactivate();
                }
            }
            updateActiveItems() {
                const activeItems = this.activeItems;
                for (let i = 0, iEnd = activeItems.length; i < iEnd; ++i) {
                    activeItems[i].update();
                }
            }
            destroy() {
                this.activeItems.length = 0;
                this.container.remove();
                this.items = {};
                this.options = {};
            }
        }
        /* *
        *
        *  Static Properties
        *
        * */
        Menu.items = MenuItemBindings;

        return Menu;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Toolbar/EditToolbar.js', [_modules['Core/Utilities.js'], _modules['Dashboards/EditMode/Menu/Menu.js']], function (U, Menu) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { defined, createElement, css } = U;
        /**
         * Abstract Class of Edit Toolbar.
         * @internal
         */
        class EditToolbar {
            /* *
             *
             *  Constructor
             *
             * */
            constructor(editMode, options) {
                this.container = createElement('div', {
                    className: options.className
                }, void 0, editMode.board.container);
                this.editMode = editMode;
                this.iconURLPrefix = editMode.iconsURLPrefix;
                this.menu = new Menu(this.container, options.menu, editMode, this);
                this.options = options;
                this.isVisible = false;
                if (this.options.outline) {
                    this.outline = createElement('div', {
                        className: options.outlineClassName
                    }, void 0, this.container);
                }
            }
            /* *
             *
             *  Functions
             *
             * */
            hide() {
                this.setPosition(void 0, void 0);
            }
            refreshOutline(x, y, guiElement, offset = 0) {
                const toolbar = this, guiElemCnt = (guiElement || {}).container;
                if (toolbar.outline && guiElemCnt) {
                    css(toolbar.outline, {
                        display: 'block',
                        left: x - offset + 'px',
                        top: y - offset + 'px',
                        width: guiElemCnt.offsetWidth + offset * 2 + 'px',
                        height: guiElemCnt.offsetHeight + offset * 2 + 'px'
                    });
                }
            }
            hideOutline() {
                if (this.outline) {
                    this.outline.style.display = 'none';
                }
            }
            setPosition(x, y) {
                const toolbar = this;
                if (toolbar.container) {
                    css(toolbar.container, {
                        left: (x || '-9999') + 'px',
                        top: (y || '-9999') + 'px'
                    });
                }
                toolbar.isVisible = defined(x) && defined(y);
            }
        }

        return EditToolbar;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Toolbar/CellEditToolbar.js', [_modules['Dashboards/Layout/Cell.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/Toolbar/EditToolbar.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Cell, EditGlobals, EditToolbar, GUIElement, H, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { isFirefox } = H;
        const { merge, fireEvent, objectEach } = U;
        /**
         * @internal
         */
        class CellEditToolbar extends EditToolbar {
            static getItemsConfig(options, iconURLPrefix) {
                const items = [];
                if (options.dragDrop?.enabled) {
                    items.push({
                        id: 'drag',
                        type: 'icon',
                        icon: iconURLPrefix + 'drag.svg',
                        events: {
                            onmousedown: function (e) {
                                // #22546, workaround for Firefox, where mouseenter
                                // event is not fired when triggering it while dragging
                                // another element.
                                if (isFirefox) {
                                    e.preventDefault();
                                }
                                const cellEditToolbar = this.menu
                                    .parent;
                                const dragDrop = cellEditToolbar.editMode.dragDrop;
                                if (dragDrop &&
                                    cellEditToolbar.cell &&
                                    Cell.isCell(cellEditToolbar.cell)) {
                                    dragDrop.onDragStart(e, cellEditToolbar.cell);
                                }
                            }
                        }
                    });
                }
                if (options.settings?.enabled) {
                    items.push({
                        id: 'settings',
                        type: 'icon',
                        icon: iconURLPrefix + 'settings.svg',
                        events: {
                            click: function () {
                                this.menu.parent.editMode.setEditOverlay();
                                this.menu.parent.onCellOptions();
                            }
                        }
                    });
                }
                items.push({
                    id: 'destroy',
                    type: 'icon',
                    className: EditGlobals.classNames.menuDestroy,
                    icon: iconURLPrefix + 'destroy.svg',
                    events: {
                        click: function () {
                            const parentNode = this.menu.parent, editMode = this.menu.parent.editMode, popup = editMode.confirmationPopup;
                            popup.show({
                                confirmButton: {
                                    value: editMode.lang.confirmButton,
                                    callback: parentNode.onCellDestroy,
                                    context: parentNode
                                },
                                cancelButton: {
                                    value: editMode.lang.cancelButton,
                                    callback: () => {
                                        popup.closePopup();
                                    }
                                },
                                text: editMode.lang.confirmDestroyCell
                            });
                        }
                    }
                });
                return items;
            }
            /* *
             *
             *  Constructor
             *
             * */
            constructor(editMode) {
                super(editMode, merge(CellEditToolbar.defaultOptions, (editMode.options.toolbars || {}).cell, {
                    menu: {
                        items: CellEditToolbar.getItemsConfig(editMode.options, editMode.iconsURLPrefix)
                    }
                }));
                if (editMode.customHTMLMode) {
                    this.filterOptionsAvailableInCustomHTMLMode();
                }
                this.menu.initItems({});
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Show toolbar for given cell.
             *
             * @param cell
             * Cell to show toolbar for.
             */
            showToolbar(cell) {
                const toolbar = this;
                const cellCnt = cell.container;
                const toolbarWidth = 30;
                const toolbarMargin = 10;
                const cellToolbar = toolbar.editMode.cellToolbar;
                if (!cellToolbar) {
                    return;
                }
                if (cellCnt && toolbar.editMode.isActive() &&
                    !(toolbar.editMode.dragDrop || {}).isActive) {
                    const cellOffsets = GUIElement.getOffsets(cell, toolbar.editMode.board.container);
                    const x = cellOffsets.right - toolbarWidth - toolbarMargin;
                    const y = cellOffsets.top + toolbarMargin;
                    objectEach(toolbar.menu.items, (item) => {
                        if (!cell.options?.editMode?.toolbarItems) {
                            item.activate();
                            return;
                        }
                        const toolbarItems = cell.options.editMode.toolbarItems;
                        if (toolbarItems[item.options.id]
                            ?.enabled === false) {
                            item.deactivate();
                            return;
                        }
                        item.activate();
                    });
                    toolbar.setPosition(x, y);
                    toolbar.cell = cell;
                    toolbar.refreshOutline();
                    cellToolbar.isVisible = true;
                }
                else if (toolbar.isVisible) {
                    toolbar.hide();
                    cellToolbar.isVisible = false;
                }
            }
            refreshOutline() {
                const toolbar = this, offsetWidth = -1;
                if (toolbar.cell && toolbar.cell.container && toolbar.outline) {
                    super.refreshOutline(-toolbar.cell.container.offsetWidth, 0, this.cell, offsetWidth);
                }
            }
            /**
             * When options icon is clicked, show sidebar with options.
             */
            onCellOptions() {
                const toolbar = this;
                const editMode = toolbar.editMode;
                if (!editMode.sidebar) {
                    return;
                }
                editMode.sidebar.show(toolbar.cell);
                toolbar.highlightCell();
            }
            onCellDestroy() {
                const toolbar = this;
                if (toolbar.cell && Cell.isCell(toolbar.cell)) {
                    const row = toolbar.cell.row;
                    const cellId = toolbar.cell.id;
                    // Disable row highlight.
                    toolbar.cell.row.setHighlight();
                    toolbar.resetEditedCell();
                    toolbar.cell.destroy();
                    toolbar.cell = void 0;
                    // Hide row and cell toolbars.
                    toolbar.editMode.hideToolbars(['cell', 'row']);
                    // Disable resizer.
                    toolbar.editMode.resizer?.disableResizer();
                    // Call cellResize dashboard event.
                    if (row && row.cells && row.cells.length) {
                        fireEvent(toolbar.editMode.board, 'cellResize', {
                            cell: row.cells[0]
                        });
                        fireEvent(row, 'cellChange', { cell: row.cells[0], row });
                        fireEvent(toolbar.editMode, 'layoutChanged', {
                            type: 'cellDestroyed',
                            target: cellId,
                            board: toolbar.editMode.board
                        });
                    }
                }
            }
            resetEditedCell() {
                this.editedCell = void 0;
            }
            /**
             * Filter options available in custom HTML mode, only settings available.
             */
            filterOptionsAvailableInCustomHTMLMode() {
                this.options.menu.items = this.options.menu.items?.filter((item) => {
                    if (typeof item === 'string') {
                        return false;
                    }
                    return item.id === 'settings';
                });
            }
            /**
             * Highlight cell and gray out the rest of the dashboard.
             */
            highlightCell() {
                const toolbar = this;
                if (!toolbar.cell) {
                    return;
                }
                if (toolbar.cell.setHighlight) {
                    toolbar.cell.setHighlight();
                }
                else {
                    toolbar.cell.container.classList.add(EditGlobals.classNames.cellEditHighlight);
                    toolbar.editMode.board.container.classList.add(EditGlobals.classNames.dashboardCellEditHighlightActive);
                }
            }
        }
        /* *
         *
         *  Static Properties
         *
         * */
        CellEditToolbar.defaultOptions = {
            enabled: true,
            className: EditGlobals.classNames.editToolbar,
            outline: false,
            outlineClassName: EditGlobals.classNames.editToolbarCellOutline,
            menu: {
                className: EditGlobals.classNames.editToolbarCell,
                itemsClassName: EditGlobals.classNames.editToolbarItem,
                items: []
            }
        };

        return CellEditToolbar;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Toolbar/RowEditToolbar.js', [_modules['Core/Utilities.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/Toolbar/EditToolbar.js'], _modules['Dashboards/Layout/GUIElement.js']], function (U, EditGlobals, EditToolbar, GUIElement) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { fireEvent, merge, objectEach } = U;
        /**
         * @internal
         */
        class RowEditToolbar extends EditToolbar {
            static getMenuItemsConfig(options, iconURLPrefix) {
                const items = [];
                if (options.dragDrop?.enabled) {
                    items.push({
                        id: 'drag',
                        type: 'icon',
                        icon: iconURLPrefix + 'drag.svg',
                        events: {
                            onmousedown: function (e) {
                                const rowEditToolbar = this.menu
                                    .parent, dragDrop = rowEditToolbar.editMode.dragDrop;
                                e.preventDefault();
                                if (dragDrop && rowEditToolbar.row) {
                                    dragDrop.onDragStart(e, rowEditToolbar.row);
                                }
                            }
                        }
                    });
                }
                items.push({
                    id: 'destroy',
                    type: 'icon',
                    className: EditGlobals.classNames.menuDestroy,
                    icon: iconURLPrefix + 'destroy.svg',
                    events: {
                        click: function () {
                            const parentNode = this.menu.parent, editMode = this.menu.parent.editMode, popup = editMode.confirmationPopup;
                            popup.show({
                                confirmButton: {
                                    value: editMode.lang.confirmButton,
                                    callback: parentNode.onRowDestroy,
                                    context: parentNode
                                },
                                cancelButton: {
                                    value: editMode.lang.cancelButton,
                                    callback: () => {
                                        popup.closePopup();
                                    }
                                },
                                text: editMode.lang.confirmDestroyRow
                            });
                        }
                    }
                });
                return items;
            }
            /* *
             *
             *  Constructor
             *
             * */
            constructor(editMode) {
                super(editMode, merge(RowEditToolbar.defaultOptions, (editMode.options.toolbars || {}).row, {
                    menu: {
                        items: RowEditToolbar.getMenuItemsConfig(editMode.options, editMode.iconsURLPrefix)
                    }
                }));
                this.menu.initItems({});
            }
            /* *
             *
             *  Functions
             *
             * */
            refreshOutline(x, y) {
                const toolbar = this, offsetWidth = 2;
                if (toolbar.row && toolbar.row.container) {
                    super.refreshOutline(x, y, this.row, offsetWidth);
                }
            }
            showToolbar(row) {
                const toolbar = this;
                const rowCnt = row.container;
                const rowToolbar = toolbar.editMode.rowToolbar;
                let x;
                let y;
                let offsetX;
                if (!rowToolbar) {
                    return;
                }
                if (rowCnt &&
                    toolbar.editMode.isActive() &&
                    !(toolbar.editMode.dragDrop || {}).isActive) {
                    const rowOffsets = GUIElement.getOffsets(row, toolbar.editMode.board.container);
                    const rowWidth = rowOffsets.right - rowOffsets.left;
                    objectEach(toolbar.menu.items, (item) => {
                        if (!row.options?.editMode?.toolbarItems) {
                            item.activate();
                            return;
                        }
                        const toolbarItems = row.options.editMode.toolbarItems;
                        if (toolbarItems[item.options.id]
                            ?.enabled === false) {
                            item.deactivate();
                            return;
                        }
                        item.activate();
                    });
                    offsetX = rowWidth / 2 - toolbar.container.clientWidth / 2;
                    x = rowOffsets.left + offsetX;
                    y = rowOffsets.top - toolbar.container.clientHeight;
                    toolbar.setPosition(x, y);
                    toolbar.row = row;
                    toolbar.refreshOutline(-offsetX, toolbar.container.clientHeight);
                    rowToolbar.isVisible = true;
                }
                else if (toolbar.isVisible) {
                    toolbar.hide();
                    rowToolbar.isVisible = false;
                }
            }
            onRowOptions() {
                const toolbar = this;
                if (toolbar.editMode.sidebar) {
                    toolbar.editMode.sidebar.show(toolbar.row);
                }
            }
            onRowDestroy() {
                const toolbar = this;
                if (toolbar.row) {
                    const rowId = toolbar.row.options.id || -1;
                    this.resetEditedRow();
                    toolbar.row.destroy();
                    toolbar.row = void 0;
                    // Hide row and cell toolbars.
                    toolbar.editMode.hideToolbars(['cell', 'row']);
                    toolbar.editMode.resizer?.disableResizer();
                    fireEvent(toolbar.editMode, 'layoutChanged', {
                        type: 'rowDestroyed',
                        target: rowId,
                        board: toolbar.editMode.board
                    });
                }
            }
            resetEditedRow() {
                /// super.resetCurrentElements(this.row as Row, true);
                this.editedRow = void 0;
            }
        }
        /* *
         *
         *  Static Properties
         *
         * */
        RowEditToolbar.defaultOptions = {
            enabled: true,
            className: EditGlobals.classNames.editToolbar,
            outline: true,
            outlineClassName: EditGlobals.classNames.editToolbarRowOutline,
            menu: {
                className: EditGlobals.classNames.editToolbarRow,
                itemsClassName: EditGlobals.classNames.editToolbarItem,
                items: []
            }
        };

        return RowEditToolbar;
    });
    _registerModule(_modules, 'Shared/BaseForm.js', [_modules['Core/Renderer/HTML/AST.js'], _modules['Core/Utilities.js']], function (AST, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         * */
        /* *
         *
         *  Imports
         *
         * */
        const { addEvent, createElement } = U;
        /* *
         *
         *  Class
         *
         * */
        class BaseForm {
            /* *
             *
             *  Constructor
             *
             * */
            constructor(parentDiv, iconsURL) {
                this.iconsURL = iconsURL;
                this.container = this.createPopupContainer(parentDiv);
                this.closeButton = this.addCloseButton();
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Create popup div container.
             *
             * @param {HTMLElement} parentDiv
             * Parent div to attach popup.
             *
             * @param  {string} className
             * Class name of the popup.
             *
             * @return {HTMLElement}
             * Popup div.
             */
            createPopupContainer(parentDiv, className = 'highcharts-popup highcharts-no-tooltip') {
                return createElement('div', { className }, void 0, parentDiv);
            }
            /**
             * Create HTML element and attach click event to close popup.
             *
             * @param {string} className
             * Class name of the close button.
             *
             * @return {HTMLElement}
             * Close button.
             */
            addCloseButton(className = 'highcharts-popup-close') {
                const popup = this, iconsURL = this.iconsURL;
                // Create close popup button.
                const closeButton = createElement('button', { className }, void 0, this.container);
                createElement('span', {
                    className: 'highcharts-icon'
                }, {
                    backgroundImage: 'url(' + (iconsURL.match(/png|svg|jpeg|jpg|gif/ig) ?
                        iconsURL : iconsURL + 'close.svg') + ')'
                }, closeButton);
                ['click', 'touchstart'].forEach((eventName) => {
                    addEvent(closeButton, eventName, popup.closeButtonEvents.bind(popup));
                });
                // Close popup when press ESC
                addEvent(document, 'keydown', function (event) {
                    if (event.code === 'Escape') {
                        popup.closeButtonEvents();
                    }
                });
                return closeButton;
            }
            /**
             * Close button events.
             * @return {void}
             */
            closeButtonEvents() {
                this.closePopup();
            }
            /**
             * Reset content of the current popup and show.
             *
             * @param {string} toolbarClass
             * Class name of the toolbar which styles should be reset.
             */
            showPopup(toolbarClass = 'highcharts-annotation-toolbar') {
                const popupDiv = this.container, popupCloseButton = this.closeButton;
                this.type = void 0;
                // Reset content.
                popupDiv.innerHTML = AST.emptyHTML;
                // Reset toolbar styles if exists.
                if (popupDiv.className.indexOf(toolbarClass) >= 0) {
                    popupDiv.classList.remove(toolbarClass);
                    // Reset toolbar inline styles
                    popupDiv.removeAttribute('style');
                }
                // Add close button.
                popupDiv.appendChild(popupCloseButton);
                popupDiv.style.display = 'block';
                popupDiv.style.height = '';
            }
            /**
             * Hide popup.
             */
            closePopup() {
                this.container.style.display = 'none';
            }
        }
        /* *
         *
         *  Default Export
         *
         * */

        return BaseForm;
    });
    _registerModule(_modules, 'Dashboards/EditMode/ConfirmationPopup.js', [_modules['Core/Utilities.js'], _modules['Shared/BaseForm.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/EditRenderer.js']], function (U, BaseForm, EditGlobals, EditRenderer) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { createElement } = U;
        /**
         * Class to create confirmation popup.
         */
        class ConfirmationPopup extends BaseForm {
            /* *
            *
            *  Static Properties
            *
            * */
            /* *
            *
            *  Constructor
            *
            * */
            /**
             * Constructs an instance of the ConfirmationPopup.
             *
             * @param parentDiv
             * Parent div where the popup will be added.
             *
             * @param iconsURL
             * URL to the icons.
             *
             * @param editMode
             * The EditMode instance.
             *
             * @param options
             * Options for confirmation popup.
             */
            constructor(parentDiv, iconsURL, editMode, options) {
                iconsURL =
                    options && options.close && options.close.icon ?
                        options.close.icon :
                        iconsURL;
                super(parentDiv, iconsURL);
                this.editMode = editMode;
                this.options = options;
            }
            /* *
            *
            *  Functions
            *
            * */
            /**
             * Returns popup container.
             *
             * @param parentDiv
             * Parent div where the popup will be added.
             *
             * @param className
             * Class name added to the popup container.
             */
            createPopupContainer(parentDiv, className = EditGlobals.classNames.confirmationPopup) {
                return super.createPopupContainer(parentDiv, className);
            }
            /**
             * Adds close button to the popup.
             *
             * @param className
             * Class name added to the close button.
             */
            addCloseButton(className = EditGlobals.classNames.popupCloseButton) {
                return super.addCloseButton(className);
            }
            /**
             * Adds events to the close button.
             *
             * @override BaseForm.closeButtonEvents
             */
            closeButtonEvents() {
                const cancelCallback = this.contentOptions?.cancelButton.callback;
                if (!cancelCallback) {
                    return;
                }
                cancelCallback();
            }
            /**
             * Adds content inside the popup.
             */
            renderContent() {
                const options = this.contentOptions;
                if (!options) {
                    return;
                }
                // Render content wrapper
                this.contentContainer = createElement('div', {
                    className: EditGlobals.classNames.popupContentContainer
                }, {}, this.container);
                const popupContainer = this.contentContainer.parentNode;
                popupContainer.style.marginTop = '0px';
                const offsetTop = popupContainer.getBoundingClientRect().top;
                popupContainer.style.marginTop = (offsetTop < 0 ? Math.abs(offsetTop - 200) : 200) + 'px';
                // Render text
                EditRenderer.renderText(this.contentContainer, {
                    title: options.text || ''
                });
                // Render button wrapper
                this.buttonContainer = createElement('div', {
                    className: EditGlobals.classNames.popupButtonContainer
                }, {}, this.container);
                // Render cancel buttons
                EditRenderer.renderButton(this.buttonContainer, {
                    text: options.cancelButton.value,
                    className: EditGlobals.classNames.popupCancelBtn,
                    callback: options.cancelButton.callback
                });
                // Confirm
                EditRenderer.renderButton(this.buttonContainer, {
                    text: options.confirmButton.value,
                    className: EditGlobals.classNames.popupConfirmBtn,
                    callback: () => {
                        options.confirmButton.callback.call(options.confirmButton.context);
                        this.closePopup();
                    }
                });
            }
            /**
             * Shows confirmation popup.
             *
             * @param options
             * Options for confirmation popup.
             */
            show(options) {
                this.contentOptions = options;
                this.showPopup();
                this.renderContent();
                this.editMode.setEditOverlay();
            }
            /**
             * Hides confirmation popup.
             */
            closePopup() {
                super.closePopup();
                this.editMode.setEditOverlay(true);
            }
        }

        return ConfirmationPopup;
    });
    _registerModule(_modules, 'Dashboards/EditMode/AccordionMenu.js', [_modules['Dashboards/EditMode/EditRenderer.js'], _modules['Core/Utilities.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/ConfirmationPopup.js']], function (EditRenderer, U, EditGlobals, ConfirmationPopup) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Pawel Lysy
         *  - Sebastian Bochan
         *
         * */
        const { createElement, merge, error, fireEvent } = U;
        /* *
         *
         *  Class
         *
         * */
        /**
         * Accordion menu class.
         */
        class AccordionMenu {
            /* *
             *
             *  Constructor
             *
             * */
            constructor(iconsURLPrefix, closeSidebar) {
                this.changedOptions = {};
                this.chartOptionsJSON = {};
                this.oldOptionsBuffer = {};
                this.waitingForConfirmation = false;
                this.iconsURLPrefix = iconsURLPrefix;
                this.closeSidebar = closeSidebar;
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Renders the menu for given component.
             *
             * @param container
             * The HTML Element to render the menu in.
             *
             * @param component
             * The component to render the menu for.

             * @param sidebarMainContainer
             * The main container of the sidebar.
             */
            renderContent(container, component, sidebarMainContainer) {
                const { editMode } = component.board;
                const menu = this;
                const editableOptions = component.editableOptions.getOptions();
                let options;
                let content;
                this.component = component;
                this.oldOptionsBuffer = component.getEditableOptions();
                if (editMode) {
                    this.confirmationPopup = new ConfirmationPopup(component.board.container, editMode.iconsURLPrefix, editMode, { close: { icon: '' } });
                }
                const accordionContainer = createElement('div', {
                    className: EditGlobals.classNames.accordionMenu
                }, {}, container);
                for (let i = 0, end = editableOptions.length; i < end; i++) {
                    options = editableOptions[i];
                    content = EditRenderer.renderCollapseHeader(accordionContainer, merge({
                        iconsURLPrefix: menu.iconsURLPrefix,
                        lang: (component.board?.editMode || EditGlobals).lang
                    }, options)).content;
                    this.renderAccordion(options, content, component);
                }
                const buttonContainer = createElement('div', {
                    className: EditGlobals.classNames.accordionMenuButtonsContainer
                }, {}, sidebarMainContainer);
                EditRenderer.renderButton(buttonContainer, {
                    text: (component.board?.editMode || EditGlobals)
                        .lang.confirmButton,
                    className: EditGlobals.classNames.popupConfirmBtn,
                    callback: async () => {
                        await this.confirmChanges();
                        fireEvent(editMode, 'confirmEditing');
                    }
                });
                EditRenderer.renderButton(buttonContainer, {
                    text: (component.board?.editMode || EditGlobals)
                        .lang.cancelButton,
                    className: EditGlobals.classNames.popupCancelBtn,
                    callback: () => {
                        this.cancelChanges();
                        fireEvent(editMode, 'cancelEditing');
                    }
                });
                sidebarMainContainer.appendChild(buttonContainer);
            }
            /**
             * Update the options object with new nested value, based on the property
             * path. If the objects in the path are not defined, the function will
             * create them.
             *
             * @param propertyPath
             * Path of the property for which the value should be updated.
             * Example: ```['chartOptions', 'chart', 'type']```
             *
             * @param value
             * New value of the property.
             */
            updateOptions(propertyPath, value) {
                const pathLength = propertyPath.length - 1;
                let currentLevel = this.changedOptions;
                let currentChartOptionsLevel;
                let currentOldChartOptionsBufferLevel;
                let currentDataGridOptionsLevel;
                let currentOldDataGridOptionsBufferLevel;
                if (pathLength === 0 && propertyPath[0] === 'chartOptions') {
                    try {
                        const parsedValue = JSON.parse(value);
                        this.chartOptionsJSON = parsedValue;
                    }
                    catch (e) {
                        // TODO: Handle the wrong config passed from the user.
                        error(`Dashboards Error: Wrong JSON config structure passed as a chart options. \n____________\n${e}`);
                    }
                }
                for (let i = 0; i < pathLength; i++) {
                    const key = propertyPath[i];
                    if (!currentLevel[key]) {
                        currentLevel[key] = {};
                    }
                    currentLevel = currentLevel[key];
                    if (key === 'gridOptions') {
                        const realGridOptions = this.component.dataGrid?.options;
                        if (realGridOptions) {
                            const oldOptionsBuffer = this.oldOptionsBuffer;
                            if (!oldOptionsBuffer.gridOptions) {
                                oldOptionsBuffer.gridOptions = {};
                            }
                            currentOldDataGridOptionsBufferLevel =
                                oldOptionsBuffer.gridOptions;
                            currentDataGridOptionsLevel = realGridOptions;
                        }
                    }
                    else if (currentDataGridOptionsLevel &&
                        currentOldDataGridOptionsBufferLevel) {
                        currentDataGridOptionsLevel = currentDataGridOptionsLevel[key];
                        if (currentOldDataGridOptionsBufferLevel[key] === void 0) {
                            currentOldDataGridOptionsBufferLevel[key] = {};
                        }
                        currentOldDataGridOptionsBufferLevel =
                            currentOldDataGridOptionsBufferLevel[key];
                    }
                    if (key === 'chartOptions') {
                        const realChartOptions = this.component.chart?.options;
                        if (realChartOptions) {
                            const oldOptionsBuffer = this.oldOptionsBuffer;
                            if (!oldOptionsBuffer.chartOptions) {
                                oldOptionsBuffer.chartOptions = {};
                            }
                            currentOldChartOptionsBufferLevel =
                                oldOptionsBuffer.chartOptions;
                            currentChartOptionsLevel = realChartOptions;
                        }
                    }
                    else if (currentChartOptionsLevel &&
                        currentOldChartOptionsBufferLevel) {
                        currentChartOptionsLevel = currentChartOptionsLevel[key];
                        if (currentOldChartOptionsBufferLevel[key] === void 0) {
                            currentOldChartOptionsBufferLevel[key] = {};
                        }
                        currentOldChartOptionsBufferLevel =
                            currentOldChartOptionsBufferLevel[key];
                    }
                }
                const lastKey = propertyPath[pathLength];
                currentLevel[lastKey] = value;
                if (currentOldChartOptionsBufferLevel && currentChartOptionsLevel) {
                    currentOldChartOptionsBufferLevel[lastKey] = (currentOldChartOptionsBufferLevel[lastKey] ??
                        currentChartOptionsLevel[lastKey]);
                }
                // eslint-disable-next-line @typescript-eslint/no-floating-promises
                this.component?.update(this.changedOptions);
            }
            /**
             * Renders either a basic or nested element. This function can be
             * recursively called, if there are multiple nested options.
             *
             * @param options
             * Configuration object of the Component options.
             *
             * @param parentNode
             * A container where the accordion is rendered.
             *
             * @param component
             * the component for which the menu should be rendered.
             */
            renderAccordion(options, parentNode, component) {
                if (options.type === 'nested') {
                    return this.renderNested(parentNode, options, component);
                }
                const renderFunction = EditRenderer.getRendererFunction(options.type);
                if (!renderFunction) {
                    return;
                }
                renderFunction(parentNode, {
                    ...options,
                    iconsURLPrefix: this.iconsURLPrefix,
                    value: component.getEditableOptionValue(options.propertyPath),
                    enabledOnOffLabels: options.type === 'toggle',
                    onchange: (value) => this.updateOptions(options.propertyPath || [], value)
                });
            }
            /**
             * Render nested menu for the component.
             *
             * @param parentElement
             * HTML element to which the nested structure should be rendered to
             *
             * @param options
             * configuration object for the options
             *
             * @param component
             * The component instance for the options should be rendered
             */
            renderNested(parentElement, options, component) {
                if (!parentElement || !options.nestedOptions) {
                    return;
                }
                const nestedOptions = options.nestedOptions;
                for (let i = 0, iEnd = nestedOptions.length; i < iEnd; ++i) {
                    const name = nestedOptions[i].name;
                    const accordionOptions = nestedOptions[i].options;
                    const showToggle = !!nestedOptions[i].showToggle;
                    const propertyPath = nestedOptions[i].propertyPath || [];
                    const lang = (component.board?.editMode || EditGlobals).lang;
                    const collapsedHeader = EditRenderer.renderCollapseHeader(parentElement, {
                        name,
                        isEnabled: !!component.getEditableOptionValue(propertyPath),
                        iconsURLPrefix: this.iconsURLPrefix,
                        showToggle: showToggle,
                        onchange: (value) => this.updateOptions(propertyPath, value),
                        isNested: !!accordionOptions,
                        isStandalone: !accordionOptions,
                        lang
                    });
                    for (let j = 0, jEnd = accordionOptions?.length; j < jEnd; ++j) {
                        this.renderAccordion(merge(accordionOptions[j], { lang, isNested: true }), collapsedHeader.content, component);
                    }
                }
                return;
            }
            /**
             * Closes the sidebar discarding changes. If there are any changes, it will
             * show a confirmation popup. If no changes, it will close the sidebar.
             */
            cancelChanges() {
                if (Object.keys(this.changedOptions).length < 1) {
                    this.closeSidebar();
                }
                else {
                    this.showCancelConfirmationPopup();
                }
            }
            /**
             * Confirms changes made in the component.
             *
             * @fires EditMode#componentChanged
             */
            async confirmChanges() {
                const component = this.component;
                if (!component) {
                    return;
                }
                if (component.type === 'Highcharts' &&
                    Object.keys(this.chartOptionsJSON).length) {
                    await component.update({
                        chartOptions: this.chartOptionsJSON
                    });
                }
                else if (component.type === 'HTML') {
                    const options = this.changedOptions;
                    await component.update(options, true);
                }
                fireEvent(component.board.editMode, 'componentChanged', {
                    target: component,
                    changedOptions: merge({}, this.changedOptions),
                    oldOptions: merge({}, this.oldOptionsBuffer)
                });
                this.changedOptions = {};
                this.chartOptionsJSON = {};
                this.closeSidebar();
            }
            /**
             * Discards changes made in the component.
             *
             * @fires EditMode#componentChangesDiscarded
             */
            async discardChanges() {
                const component = this.component;
                if (!component) {
                    return;
                }
                await component.update(this.oldOptionsBuffer);
                fireEvent(component.board.editMode, 'componentChangesDiscarded', {
                    target: component,
                    changedOptions: merge({}, this.changedOptions),
                    oldOptions: merge({}, this.oldOptionsBuffer)
                });
                this.changedOptions = {};
                this.chartOptionsJSON = {};
            }
            /**
             * Shows a confirmation popup when the user tries to discard changes.
             */
            showCancelConfirmationPopup() {
                const popup = this.confirmationPopup;
                const editMode = this.component?.board?.editMode;
                if (!popup || !editMode || this.waitingForConfirmation) {
                    return;
                }
                this.waitingForConfirmation = true;
                popup.show({
                    text: editMode.lang.confirmDiscardChanges,
                    confirmButton: {
                        value: editMode.lang.confirmButton,
                        callback: async () => {
                            await this.discardChanges();
                            this.waitingForConfirmation = false;
                            this.closeSidebar();
                        },
                        context: this
                    },
                    cancelButton: {
                        value: editMode.lang.cancelButton,
                        callback: () => {
                            popup.closePopup();
                            editMode.setEditOverlay();
                            setTimeout(() => {
                                this.waitingForConfirmation = false;
                            }, 100);
                        }
                    }
                });
            }
        }
        /* *
         *
         *  Default Export
         *
         * */

        return AccordionMenu;
    });
    _registerModule(_modules, 'Dashboards/Layout/Row.js', [_modules['Dashboards/Globals.js'], _modules['Dashboards/Layout/Cell.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Core/Utilities.js'], _modules['Dashboards/EditMode/EditGlobals.js']], function (Globals, Cell, GUIElement, U, EditGlobals) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { pick, defined, merge, objectEach, fireEvent } = U;
        /**
         * @internal
         **/
        class Row extends GUIElement {
            /* *
            *
            *  Static Properties
            *
            * */
            static setContainerHeight(rowContainer, height) {
                if (height) {
                    rowContainer.style.height = height + 'px';
                }
            }
            /* *
            *
            *  Constructor
            *
            * */
            /**
             * Constructs an instance of the Row class.
             *
             * @param {Layout} layout
             * Reference to the layout instance.
             *
             * @param {Row.Options} options
             * Options for the row.
             *
             * @param {HTMLElement} rowElement
             * The container of the row HTML element.
             */
            constructor(layout, options, rowElement) {
                super();
                /**
                 * The type of GUI element.
                 */
                this.type = Globals.guiElementType.row;
                this.layout = layout;
                this.cells = [];
                this.options = options;
                this.isVisible = true;
                // Get parent container
                const parentContainer = document.getElementById(options.parentContainerId || '') ||
                    layout.container;
                const layoutOptions = (layout.options || {}), rowClassName = layoutOptions.rowClassName || '';
                this.container = this.getElementContainer({
                    render: layout.board.guiEnabled,
                    parentContainer: parentContainer,
                    attribs: {
                        id: options.id,
                        className: Globals.classNames.row + ' ' +
                            rowClassName
                    },
                    element: rowElement,
                    elementId: options.id,
                    style: merge(layoutOptions.style, options.style)
                });
                // Init rows from options.
                if (this.options.cells) {
                    this.setCells();
                }
            }
            /* *
            *
            *  Functions
            *
            * */
            /**
             * Set the row cells using cell options or cellClassName.
             */
            setCells() {
                const row = this, cellClassName = (row.layout.options || {}).cellClassName || '', cellsElements = pick(row.options.cells, row.container && row.container.getElementsByClassName(cellClassName)) || [];
                let cellElement, i, iEnd;
                for (i = 0, iEnd = cellsElements.length; i < iEnd; ++i) {
                    cellElement = cellsElements[i];
                    row.addCell(row.layout.board.guiEnabled ? cellElement : { id: '' }, cellElement instanceof HTMLElement ? cellElement : void 0);
                }
            }
            /**
             * Add a new Cell instance to the row cells array.
             *
             * @param {Cell.Options} [options]
             * Options for the row cell.
             *
             * @param {HTMLElement} [cellElement]
             * The container for a new cell HTML element.
             *
             * @return {Cell}
             * Returns the Cell object.
             */
            addCell(options, cellElement, index) {
                const row = this, cell = new Cell(row, options, cellElement);
                if (!defined(index)) {
                    row.cells.push(cell);
                }
                else {
                    row.mountCell(cell, index);
                }
                // Set editMode events.
                if (row.layout.board.editMode) {
                    row.layout.board.editMode.setCellEvents(cell);
                }
                return cell;
            }
            /**
             * Destroy the element, its container, event hooks
             * and inner cells.
             */
            destroy() {
                const row = this;
                const { layout } = row;
                // Copy to avoid problem with index when shifting array of cells during
                // the destroy.
                const rowCells = [...row.cells];
                // Destroy cells.
                for (let i = 0, iEnd = rowCells?.length; i < iEnd; ++i) {
                    if (rowCells[i]) {
                        rowCells[i].destroy();
                    }
                }
                if (row.layout) {
                    row.layout.unmountRow(row);
                    super.destroy();
                    if (layout.rows?.length === 0) {
                        layout.destroy();
                    }
                }
            }
            /**
             * Get the row's options.
             * @returns
             * The JSON of row's options.
             *
             * @internal
             *
             */
            getOptions() {
                const row = this, cells = [];
                for (let i = 0, iEnd = row.cells.length; i < iEnd; ++i) {
                    cells.push(row.cells[i].getOptions());
                }
                return {
                    id: this.options.id,
                    style: this.options.style,
                    cells
                };
            }
            setSize(height) {
                Row.setContainerHeight(this.container, height);
            }
            // Get cell index from the row.cells array.
            getCellIndex(cell) {
                for (let i = 0, iEnd = this.cells?.length; i < iEnd; ++i) {
                    if (this.cells[i].id === cell.id) {
                        return i;
                    }
                }
            }
            // Add cell to the row.cells array and move cell container.
            mountCell(cell, index = 0) {
                const row = this, nextCell = row.cells[index], prevCell = row.cells[index - 1];
                if (cell.container) {
                    if (nextCell && nextCell.container) {
                        nextCell.container.parentNode.insertBefore(cell.container, nextCell.container);
                    }
                    else if (prevCell && prevCell.container) {
                        prevCell.container.parentNode.insertBefore(cell.container, prevCell.container.nextSibling);
                    }
                    else if (!prevCell && !nextCell && row.container) {
                        row.container.appendChild(cell.container);
                    }
                    row.cells.splice(index, 0, cell);
                    cell.row = row;
                    setTimeout(() => {
                        fireEvent(row, 'cellChange', { row, cell });
                    }, 0);
                }
            }
            // Remove cell from the row.cells array.
            unmountCell(cell) {
                const cellIndex = this.getCellIndex(cell);
                if (defined(cellIndex)) {
                    this.cells.splice(cellIndex, 1);
                }
                setTimeout(() => {
                    fireEvent(this, 'cellChange', { row: this, cell });
                }, 0);
            }
            getVisibleCells() {
                const cells = [];
                for (let i = 0, iEnd = this.cells.length; i < iEnd; ++i) {
                    if (this.cells[i].isVisible) {
                        cells.push(this.cells[i]);
                    }
                }
                return cells;
            }
            changeVisibility(setVisible = true, displayStyle) {
                const row = this;
                super.changeVisibility(setVisible, displayStyle);
                // Change layout visibility if needed.
                if (!row.layout.getVisibleRows().length) {
                    row.layout.hide();
                }
                else if (row.isVisible && !row.layout.isVisible) {
                    row.layout.show();
                }
            }
            show() {
                this.changeVisibility(true, 'flex');
            }
            setHighlight(remove) {
                const classList = this.container.classList;
                const highlightClass = EditGlobals.classNames.rowContextHighlight;
                if (remove === true) {
                    classList.remove(highlightClass);
                }
                else {
                    classList.toggle(highlightClass, !remove);
                }
            }
            // Row can have cells below each others.
            // This method returns cells split into levels.
            getRowLevels() {
                const row = this, rowLevels = {}, rowLevelsArray = [];
                let cell, cellOffsets;
                for (let k = 0, kEnd = row.cells.length; k < kEnd; ++k) {
                    cell = row.cells[k];
                    if (cell.isVisible) {
                        cellOffsets = GUIElement.getOffsets(cell);
                        if (!rowLevels[cellOffsets.top]) {
                            rowLevels[cellOffsets.top] = {
                                top: cellOffsets.top,
                                bottom: cellOffsets.bottom,
                                cells: []
                            };
                        }
                        if (rowLevels[cellOffsets.top].bottom < cellOffsets.bottom) {
                            rowLevels[cellOffsets.top].bottom = cellOffsets.bottom;
                        }
                        rowLevels[cellOffsets.top].cells.push(cell);
                    }
                }
                objectEach(rowLevels, (value) => {
                    rowLevelsArray.push(value);
                });
                return rowLevelsArray;
            }
            // Get row level with additional info
            // on a specific Y position.
            getRowLevelInfo(posY) {
                const rowLevels = this.getRowLevels();
                let rowLevelInfo;
                for (let i = 0, iEnd = rowLevels.length; i < iEnd; ++i) {
                    if (rowLevels[i].top <= posY && rowLevels[i].bottom > posY) {
                        rowLevelInfo = {
                            index: i,
                            rowLevels: rowLevels,
                            rowLevel: rowLevels[i]
                        };
                    }
                }
                return rowLevelInfo;
            }
        }

        return Row;
    });
    _registerModule(_modules, 'Dashboards/Layout/Layout.js', [_modules['Core/Utilities.js'], _modules['Dashboards/Layout/Row.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Dashboards/Globals.js']], function (U, Row, GUIElement, Globals) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { pick, defined } = U;
        /**
         * @internal
         **/
        class Layout extends GUIElement {
            /* *
            *
            *  Constructor
            *
            * */
            /**
             * Constructs an instance of the Layout class.
             *
             * @param {Dashboard} board
             * Reference to the dashboard instance.
             *
             * @param {Layout.Options} options
             * Options for the layout.
             */
            constructor(board, options, parentCell) {
                super();
                /**
                 * The type of GUI element.
                 */
                this.type = Globals.guiElementType.layout;
                this.board = board;
                this.rows = [];
                this.options = options;
                this.isVisible = true;
                // Get parent container
                const parentContainer = parentCell ? parentCell.container :
                    document.getElementById(options.parentContainerId || '') || board.layoutsWrapper;
                // Set layout level.
                if (parentCell) {
                    this.parentCell = parentCell;
                    this.level = parentCell.row.layout.level + 1;
                }
                else {
                    this.level = 0;
                }
                // GUI structure
                if (options.copyId) {
                    this.copyId = options.copyId;
                }
                const layoutOptions = (this.options || {}), layoutClassName = layoutOptions.rowClassName || '';
                this.container = this.getElementContainer({
                    render: board.guiEnabled,
                    parentContainer: parentContainer,
                    attribs: {
                        id: (options.id || '') + (this.copyId ? '_' + this.copyId : ''),
                        className: Globals.classNames.layout + ' ' +
                            layoutClassName
                    },
                    elementId: options.id,
                    style: this.options.style
                });
                // Init rows from options.
                if (this.options.rows) {
                    this.setRows();
                }
            }
            /* *
            *
            *  Functions
            *
            * */
            /**
             * Set the layout rows using rows options or rowClassName.
             */
            setRows() {
                const layout = this, rowsElements = pick(layout.options.rows, layout.container && layout.container.getElementsByClassName(layout.options.rowClassName || '')) || [];
                let rowElement, i, iEnd;
                for (i = 0, iEnd = rowsElements.length; i < iEnd; ++i) {
                    rowElement = rowsElements[i];
                    layout.addRow(layout.board.guiEnabled ? rowElement : {}, rowElement instanceof HTMLElement ? rowElement : void 0);
                }
            }
            /**
             * Add a new Row instance to the layout rows array.
             *
             * @param {Row.Options} options
             * Options of a row.
             *
             * @param {HTMLElement} rowElement
             * The container for a new row HTML element.
             *
             * @return {Row}
             * Returns the Row object.
             */
            addRow(options, rowElement, index) {
                const layout = this, row = new Row(layout, options, rowElement);
                if (!defined(index)) {
                    layout.rows.push(row);
                }
                else {
                    layout.mountRow(row, index);
                }
                // Set editMode events.
                if (layout.board.editMode) {
                    layout.board.editMode.setRowEvents(row);
                }
                return row;
            }
            /**
             * Destroy the element, its container, event hooks
             * and inner rows.
             */
            destroy() {
                const layout = this;
                for (let i = layout.board.layouts.length - 1; i >= 0; i--) {
                    if (layout.board.layouts[i] === layout) {
                        layout.board.layouts.splice(i, 1);
                    }
                }
                if (layout.parentCell) {
                    delete layout.parentCell.nestedLayout;
                }
                // Destroy rows.
                for (let i = layout.rows.length - 1; i >= 0; i--) {
                    layout.rows[i].destroy();
                }
                if (layout.parentCell) {
                    layout.parentCell.destroy();
                }
                super.destroy();
            }
            // Get row index from the layout.rows array.
            getRowIndex(row) {
                for (let i = 0, iEnd = this.rows.length; i < iEnd; ++i) {
                    if (this.rows[i] === row) {
                        return i;
                    }
                }
            }
            // Add cell to the layout.rows array and move row container.
            mountRow(row, index) {
                const nextRow = this.rows[index], prevRow = this.rows[index - 1];
                if (row.container) {
                    if (nextRow && nextRow.container) {
                        nextRow.container.parentNode.insertBefore(row.container, nextRow.container);
                    }
                    else if (prevRow && prevRow.container) {
                        prevRow.container.parentNode.insertBefore(row.container, prevRow.container.nextSibling);
                    }
                    this.rows.splice(index, 0, row);
                    row.layout = this;
                }
            }
            // Remove row from the layout.rows array.
            unmountRow(row) {
                const rowIndex = this.getRowIndex(row);
                if (defined(rowIndex)) {
                    this.rows.splice(rowIndex, 1);
                }
            }
            getVisibleRows() {
                const rows = [];
                for (let i = 0, iEnd = this.rows.length; i < iEnd; ++i) {
                    if (this.rows[i].isVisible) {
                        rows.push(this.rows[i]);
                    }
                }
                return rows;
            }
            changeVisibility(setVisible = true) {
                const layout = this;
                super.changeVisibility(setVisible);
                // Change parentCell visibility.
                if (layout.parentCell) {
                    if (layout.isVisible && !layout.parentCell.isVisible) {
                        layout.parentCell.show();
                    }
                    else if (!layout.isVisible && layout.parentCell.isVisible) {
                        layout.parentCell.hide();
                    }
                }
            }
            /**
             * Get the layout's options.
             * @returns
             * Layout's options.
             *
             * @internal
             *
             */
            getOptions() {
                const layout = this, rows = [];
                // Get rows JSON.
                for (let i = 0, iEnd = layout.rows.length; i < iEnd; ++i) {
                    rows.push(layout.rows[i].getOptions());
                }
                return {
                    id: this.options.id,
                    layoutClassName: this.options.layoutClassName,
                    rowClassName: this.options.rowClassName,
                    cellClassName: this.options.cellClassName,
                    style: this.options.style,
                    rows
                };
            }
        }

        return Layout;
    });
    _registerModule(_modules, 'Dashboards/EditMode/SidebarPopup.js', [_modules['Core/Renderer/HTML/AST.js'], _modules['Dashboards/Layout/CellHTML.js'], _modules['Dashboards/EditMode/AccordionMenu.js'], _modules['Shared/BaseForm.js'], _modules['Dashboards/Actions/Bindings.js'], _modules['Dashboards/Layout/Cell.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/EditRenderer.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Dashboards/Layout/Layout.js'], _modules['Core/Utilities.js']], function (AST, CellHTML, AccordionMenu, BaseForm, Bindings, Cell, EditGlobals, EditRenderer, GUIElement, Layout, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  Pawel Lysy
         *
         * */
        const { addEvent, createElement, fireEvent, merge } = U;
        /* *
         *
         *  Class
         *
         * */
        /**
         * Class which creates the sidebar and handles its behavior.
         *
         * @internal
         */
        class SidebarPopup extends BaseForm {
            /* *
             *
             *  Constructor
             *
             * */
            /**
             * Constructor of the SidebarPopup class.
             *
             * @param parentDiv
             * Element to which the sidebar will be appended.
             *
             * @param iconsURL
             * URL to the icons.
             *
             * @param editMode
             * Instance of EditMode.
             */
            constructor(parentDiv, iconsURL, editMode) {
                super(parentDiv, iconsURL);
                /**
                 * Options used in the sidebar.
                 */
                this.options = {
                    components: ['HTML', 'row', 'Highcharts', 'DataGrid', 'KPI']
                };
                /**
                 * Whether the sidebar is visible.
                 */
                this.isVisible = false;
                /**
                 * List of components that can be added to the board.
                 */
                this.componentsList = [];
                this.editMode = editMode;
                this.options = merge(this.options, editMode.options.toolbars?.sidebar || {});
                this.componentsList = this.getComponentsList(this.options.components || []);
                this.accordionMenu = new AccordionMenu(this.iconsURL, this.hide.bind(this));
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Function to detect on which side of the screen should the sidebar be.
             *
             * @param context
             * The cell or row which is the context of the sidebar.
             *
             * @returns
             * Whether the sidebar should be on the right side of the screen.
             */
            detectRightSidebar(context) {
                const editMode = this.editMode;
                const layoutWrapper = editMode.customHTMLMode ?
                    editMode.board.container : editMode.board.layoutsWrapper;
                if (!layoutWrapper) {
                    return false;
                }
                return GUIElement.getOffsets(context, layoutWrapper).left < ((layoutWrapper.offsetWidth / 2) - 10); // 10 = snap
            }
            /**
             * Function to remove the class names from the sidebar.
             */
            removeClassNames() {
                const classNames = EditGlobals.classNames, classList = this.container.classList;
                classList.remove(classNames.editSidebarShow);
                classList.remove(classNames.editSidebarRightShow);
            }
            /**
             * Function to add the class names to the sidebar depending on the position
             * of the sidebar.
             *
             * @param isRightSidebar
             * Whether the sidebar should be on the right side of the screen.
             */
            addClassNames(isRightSidebar) {
                const classList = this.container.classList;
                if (isRightSidebar) {
                    classList.add(EditGlobals.classNames.editSidebarRight);
                }
                else {
                    classList.remove(EditGlobals.classNames.editSidebarRight);
                }
                setTimeout(() => {
                    classList.add(EditGlobals.classNames[isRightSidebar ? 'editSidebarRightShow' : 'editSidebarShow']);
                });
            }
            /**
             * Function to show the sidebar.
             *
             * @param context
             * The cell or row which is the context of the sidebar.
             */
            show(context) {
                const editMode = this.editMode, isRightSidebar = !!(context && this.detectRightSidebar(context));
                this.showPopup(EditGlobals.classNames.editSidebarShow);
                this.addClassNames(isRightSidebar);
                if (editMode.resizer) {
                    editMode.resizer.disableResizer();
                }
                // Remove highlight from the row.
                if (Cell.isCell(editMode.editCellContext) &&
                    editMode.editCellContext.row) {
                    editMode.editCellContext.row.setHighlight();
                }
                editMode.hideToolbars(['cell', 'row']);
                editMode.stopContextDetection();
                this.isVisible = true;
                this.generateContent(context);
            }
            generateContent(context) {
                // Reset
                this.container.innerHTML = AST.emptyHTML;
                // Title
                this.renderHeader(context ?
                    this.editMode.lang.settings :
                    this.editMode.lang.addComponent, '');
                // Render content wrapper
                this.sidebarWrapper = createElement('div', {
                    className: EditGlobals.classNames.editSidebarWrapper
                }, void 0, this.container);
                if (!context) {
                    this.renderAddComponentsList();
                    return;
                }
                this.type = context.getType();
                if (this.type === 'cell-html' || this.type === 'cell') {
                    const component = context.mountedComponent;
                    if (!component) {
                        return;
                    }
                    this.accordionMenu.renderContent(this.sidebarWrapper, component, this.container);
                }
            }
            renderAddComponentsList() {
                const sidebar = this;
                const components = this.componentsList;
                let gridElement;
                const gridWrapper = createElement('div', {
                    className: EditGlobals.classNames.editGridItems
                }, {}, sidebar.sidebarWrapper);
                for (let i = 0, iEnd = components.length; i < iEnd; ++i) {
                    gridElement = createElement('div', {}, {}, gridWrapper);
                    // Drag drop new component.
                    gridElement.addEventListener('mousedown', (e) => {
                        e.preventDefault();
                        const dragDrop = sidebar.editMode.dragDrop;
                        if (dragDrop) {
                            // Workaround for Firefox, where mouseleave is not triggered
                            // correctly when dragging.
                            const onMouseMove = (event) => {
                                const rect = sidebar.container.getBoundingClientRect();
                                if (event.clientX < rect.left ||
                                    event.clientX > rect.right ||
                                    event.clientY < rect.top ||
                                    event.clientY > rect.bottom) {
                                    sidebar.hide();
                                    document.removeEventListener('mousemove', onMouseMove);
                                }
                            };
                            // Clean up event listeners
                            const onMouseUp = () => {
                                document.removeEventListener('mousemove', onMouseMove);
                                document.removeEventListener('mouseup', onMouseUp);
                            };
                            // Add event listeners
                            document.addEventListener('mousemove', onMouseMove);
                            document.addEventListener('mouseup', onMouseUp);
                            dragDrop.onDragStart(e, void 0, (dropContext) => {
                                // Add component if there is no layout yet.
                                if (this.editMode.board.layouts.length === 0) {
                                    const board = this.editMode.board, newLayoutId = GUIElement.getElementId('layout'), layout = new Layout(board, {
                                        id: newLayoutId,
                                        copyId: '',
                                        parentContainerId: board.container.id,
                                        rows: [{}],
                                        style: {}
                                    });
                                    if (layout) {
                                        board.layouts.push(layout);
                                    }
                                    dropContext = layout.rows[0];
                                }
                                if (!dropContext?.type) {
                                    const layouts = sidebar.editMode.board.layouts;
                                    dragDrop.dropContext = dropContext =
                                        layouts[layouts.length - 1].addRow({}, void 0);
                                }
                                const newCell = components[i].onDrop(sidebar, dropContext);
                                /* eslint-disable max-len */
                                const unbindLayoutChanged = addEvent(this.editMode, 'layoutChanged', (e) => {
                                    if (newCell && e.type === 'newComponent') {
                                        const chart = newCell.mountedComponent?.chart;
                                        const settingsEnabled = this.editMode.options.settings?.enabled;
                                        if (chart?.isDirtyBox) {
                                            const unbind = addEvent(chart, 'render', () => {
                                                sidebar.editMode.setEditCellContext(newCell);
                                                if (settingsEnabled) {
                                                    sidebar.show(newCell);
                                                    newCell.setHighlight();
                                                }
                                                unbind();
                                                unbindLayoutChanged();
                                            });
                                        }
                                        else {
                                            sidebar.editMode.setEditCellContext(newCell);
                                            if (settingsEnabled) {
                                                sidebar.show(newCell);
                                                newCell.setHighlight();
                                            }
                                            unbindLayoutChanged();
                                        }
                                    }
                                });
                                /* eslint-enable max-len */
                                // Clean up event listener after drop is complete
                                document.removeEventListener('mousemove', onMouseMove);
                            });
                        }
                    });
                    gridElement.innerHTML = components[i].text;
                }
                return;
            }
            onDropNewComponent(dropContext, componentOptions) {
                const sidebar = this, dragDrop = sidebar.editMode.dragDrop;
                if (!dragDrop) {
                    return;
                }
                const row = (dropContext.getType() === 'cell' ?
                    dropContext.row :
                    dropContext), newCell = row.addCell({
                    id: GUIElement.getElementId('col')
                });
                dragDrop.onCellDragEnd(newCell);
                const options = merge(componentOptions, {
                    cell: newCell.id
                });
                const componentPromise = Bindings.addComponent(options, sidebar.editMode.board, newCell);
                sidebar.editMode.setEditOverlay(!this.editMode.options.settings?.enabled);
                void (async () => {
                    const component = await componentPromise;
                    if (!component) {
                        return;
                    }
                    fireEvent(this.editMode, 'layoutChanged', {
                        type: 'newComponent',
                        target: component
                    });
                })();
                return newCell;
            }
            /**
             * Function to hide the sidebar.
             */
            hide() {
                const editMode = this.editMode;
                const editCellContext = editMode.editCellContext;
                this.removeClassNames();
                this.container.style.display = 'none';
                // Remove edit overlay if active.
                if (editMode.isEditOverlayActive) {
                    editMode.setEditOverlay(true);
                }
                if (Cell.isCell(editCellContext) && editCellContext.row) {
                    editMode.showToolbars(['cell', 'row'], editCellContext);
                    editCellContext.row.setHighlight(true);
                    editCellContext.setHighlight(true);
                    if (editMode.resizer) {
                        editMode.resizer.setSnapPositions(editMode.editCellContext);
                    }
                }
                else if (CellHTML.isCellHTML(editCellContext) && editMode.cellToolbar) {
                    editMode.cellToolbar.showToolbar(editCellContext);
                    editCellContext.setHighlight();
                }
                editMode.isContextDetectionActive = true;
                this.isVisible = false;
            }
            /**
             * Function called when the close button is pressed.
             *
             * @override BaseForm.closeButtonEvents
             */
            closeButtonEvents() {
                if (this.type === 'cell' || this.type === 'cell-html') {
                    this.accordionMenu.cancelChanges();
                }
                else {
                    this.hide();
                }
            }
            renderHeader(title, iconURL) {
                if (!this.container) {
                    return;
                }
                const headerWrapper = createElement('div', {
                    className: EditGlobals.classNames.editSidebarHeader
                }, {}, this.container);
                this.container.appendChild(headerWrapper);
                this.headerWrapper = headerWrapper;
                const icon = EditRenderer.renderIcon(this.headerWrapper, {
                    icon: iconURL,
                    className: EditGlobals.classNames.editSidebarTitle
                });
                if (icon) {
                    icon.textContent = title;
                }
                this.headerWrapper?.appendChild(this.closeButton);
            }
            /**
             * Based on the provided components list, it returns the list of components
             * with its names and functions that are called when the component is
             * dropped.
             *
             * @param components
             * List of components that can be added to the board.
             */
            getComponentsList(components) {
                const sidebar = this, editMode = sidebar.editMode, componentTypes = editMode.board.componentTypes, componentList = [];
                components.forEach((componentName) => {
                    const component = componentTypes[componentName];
                    if (component) {
                        componentList.push({
                            text: editMode.lang?.sidebar[componentName] ||
                                component.name,
                            onDrop: function (sidebar, dropContext) {
                                const options = component.prototype.getOptionsOnDrop(sidebar);
                                if (options) {
                                    return sidebar.onDropNewComponent(dropContext, options);
                                }
                            }
                        });
                    }
                    else if (componentName === 'row') {
                        componentList.push({
                            ...SidebarPopup.addRow,
                            text: editMode.lang?.sidebar[componentName] ||
                                SidebarPopup.addRow.text
                        });
                    }
                });
                return componentList;
            }
            /**
             * Function to create and add the close button to the sidebar.
             *
             * @param className
             * Class name of the close button.
             * @returns Close button element
             */
            addCloseButton(className = EditGlobals.classNames.popupCloseButton) {
                // Close popup when click outside the popup
                addEvent(document, 'click', (event) => {
                    event.stopPropagation();
                    if (this.container.style.display === 'block' &&
                        !this.container.contains(event.target) &&
                        this.container.classList.value.includes('show')) {
                        if (this.type === 'cell' || this.type === 'cell-html') {
                            this.accordionMenu.cancelChanges();
                        }
                        else {
                            this.hide();
                        }
                    }
                });
                return super.addCloseButton.call(this, className);
            }
            /**
             * Function that creates the container of the sidebar.
             *
             * @param parentDiv
             * The parent div to which the sidebar will be appended.
             * @param className
             * Class name of the sidebar.
             * @returns The container of the sidebar.
             */
            createPopupContainer(parentDiv, className = EditGlobals.classNames.editSidebar) {
                return super.createPopupContainer.call(this, parentDiv, className);
            }
        }
        SidebarPopup.addRow = {
            text: EditGlobals.lang.sidebar.row,
            onDrop: function (sidebar, dropContext) {
                if (!dropContext) {
                    return;
                }
                const isCellType = dropContext.getType() === 'cell', row = isCellType ? dropContext.row :
                    dropContext, board = row.layout.board, cellId = GUIElement.getElementId('cell');
                if (isCellType) {
                    const newLayoutId = GUIElement.getElementId('layout');
                    const layout = new Layout(board, {
                        id: newLayoutId,
                        copyId: '',
                        parentContainerId: board.container.id,
                        rows: [{
                                cells: [{
                                        id: cellId
                                    }]
                            }],
                        style: {}
                    });
                    board.layouts.push(layout);
                    fireEvent(board.editMode, 'layoutChanged', {
                        type: 'newLayout',
                        target: layout,
                        board
                    });
                }
                else {
                    dropContext.layout.rows[0].addCell({
                        id: cellId
                    });
                }
                void Bindings.addComponent({
                    type: 'HTML',
                    cell: cellId,
                    className: 'highcharts-dashboards-component-placeholder',
                    html: `
                            <h2> Placeholder </h2>
                            <span> This placeholder can be deleted when you add extra
                                components to this row.
                            </span>
                            `
                }, board);
            }
        };
        /* *
         *
         *  Default Export
         *
         * */

        return SidebarPopup;
    });
    _registerModule(_modules, 'Dashboards/EditMode/EditContextMenu.js', [_modules['Dashboards/EditMode/EditGlobals.js'], _modules['Core/Utilities.js'], _modules['Dashboards/EditMode/Menu/Menu.js']], function (EditGlobals, U, Menu) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { addEvent, merge } = U;
        /**
         * Class to create context menu.
         * @internal
         */
        class EditContextMenu extends Menu {
            /* *
             *
             *  Constructor
             *
             * */
            constructor(parentElement, options, editMode) {
                super(editMode.board.container, merge(EditContextMenu.defaultOptions, options || {}), editMode);
                this.editMode = editMode;
                this.options = merge(EditContextMenu.defaultOptions, options || {});
                // Move it in the DOM after the edit tools so it is better accessible.
                this.editMode.board.layoutsWrapper?.parentNode.insertBefore(this.container, this.editMode.board.layoutsWrapper);
                // Set the context menu container width.
                this.container.style.width = this.options.width + 'px';
                super.initItems(EditContextMenu.items);
                if (this.options.items) {
                    const items = [];
                    for (let i = 0, iEnd = this.options.items.length; i < iEnd; ++i) {
                        if (typeof this.options.items[i] === 'string') {
                            items.push(this.options.items[i]);
                        }
                        else if (this.options.items[i].id) {
                            items.push(this.options.items[i].id);
                        }
                    }
                    this.setActiveItems(items);
                }
                this.initEvents();
            }
            /* *
            *
            *  Functions
            *
            * */
            initEvents() {
                const contextMenu = this;
                // Click on document close the context menu
                // TODO refactor
                addEvent(document, 'click', (event) => {
                    if (event.target !== this.container &&
                        event.target !==
                            contextMenu.editMode.tools.contextButtonElement &&
                        !event.target.classList
                            .contains(EditGlobals.classNames.toggleSlider) &&
                        event.target.tagName !== 'INPUT' &&
                        this.isVisible) {
                        this.setVisible(false);
                    }
                });
            }
            setVisible(visible) {
                const contextMenu = this, contextButtonElement = contextMenu.editMode.tools.contextButtonElement;
                if (contextMenu.container && contextButtonElement) {
                    if (visible) {
                        contextMenu.container.style.display = 'block';
                        contextMenu.isVisible = true;
                        contextButtonElement.setAttribute('aria-expanded', 'true');
                    }
                    else {
                        contextMenu.container.style.display = 'none';
                        contextMenu.isVisible = false;
                        contextButtonElement.setAttribute('aria-expanded', 'false');
                    }
                }
                // Set editMode toggle state
                const toggleEditMode = this.activeItems.find((item) => item.options.langKey === 'editMode');
                if (toggleEditMode) {
                    toggleEditMode.options.setValue(toggleEditMode, this.editMode.isActive());
                }
            }
            updatePosition(ctxButton, x, y) {
                const contextMenu = this, width = contextMenu.options.width || 0, left = (ctxButton ?
                    ctxButton.offsetLeft - width + ctxButton.offsetWidth :
                    x), top = ctxButton ? ctxButton.offsetTop + ctxButton.offsetHeight : y;
                if (left && top) {
                    contextMenu.container.style.left = left + 'px';
                    contextMenu.container.style.top = top + 'px';
                }
            }
        }
        /* *
        *
        *  Static Properties
        *
        * */
        EditContextMenu.defaultOptions = {
            enabled: true,
            width: 150,
            className: EditGlobals.classNames.contextMenu,
            itemsClassName: EditGlobals.classNames.contextMenuItem,
            items: ['editMode']
        };
        /**
         * Default Context menu items.
         */
        EditContextMenu.items = merge(Menu.items, {
            editMode: {
                id: 'editMode',
                type: 'toggle',
                getValue: function (item) {
                    return item.menu.editMode.isActive();
                },
                setValue: function (item, value) {
                    const inputElem = item.innerElement?.querySelector('input');
                    if (inputElem) {
                        inputElem.checked = value;
                    }
                },
                langKey: 'editMode',
                events: {
                    click: function () {
                        this.menu.editMode.toggleEditMode();
                    }
                }
            }
        });

        return EditContextMenu;
    });
    _registerModule(_modules, 'Dashboards/Actions/ContextDetection.js', [_modules['Dashboards/Layout/GUIElement.js'], _modules['Core/Utilities.js']], function (GUIElement, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { defined } = U;
        class ContextDetection {
            static isGUIElementOnParentEdge(mouseContext, side) {
                const visibleElements = (side === 'top' || side === 'bottom') ?
                    mouseContext.row.layout.getVisibleRows() :
                    (side === 'left' || side === 'right') ?
                        mouseContext.row.getVisibleCells() :
                        [];
                const lastElementIndex = (visibleElements.length - 1);
                return ((visibleElements[lastElementIndex] === mouseContext &&
                    side === 'right') ||
                    (visibleElements[lastElementIndex] === mouseContext.row &&
                        side === 'bottom') ||
                    (visibleElements[0] === mouseContext && side === 'left') ||
                    (visibleElements[0] === mouseContext.row && side === 'top'));
            }
            static getContextLevel(mouseContext, offset, sideOffset, side) {
                // Array of overlapped levels.
                const overlappedLevels = mouseContext.getOverlappingLevels(side, offset / 2);
                // Divide offset to level sections (eg 3 nested layouts -
                // cell edge will have 3 sections each 1/3 offset width).
                const divOffset = offset / overlappedLevels.length;
                // Overlapped nested layout level.
                const lastOverlappedLevel = overlappedLevels[overlappedLevels.length - 1];
                let level = mouseContext.row.layout.level - Math.floor(sideOffset / divOffset);
                level = level < lastOverlappedLevel ? lastOverlappedLevel : (level > mouseContext.row.layout.level ?
                    mouseContext.row.layout.level : level);
                return level;
            }
            static getContext(mouseCellContext, e, offset) {
                let sideOffset;
                // Get cell offsets, width, height
                const mouseCellContextOffsets = GUIElement.getOffsets(mouseCellContext);
                const { width, height } = GUIElement.getDimFromOffsets(mouseCellContextOffsets);
                // Correct offset when element to small.
                if (width < 2 * offset) {
                    offset = width / 2;
                }
                // Get mouse position relative to the mouseContext sides.
                const leftSideX = e.clientX - mouseCellContextOffsets.left;
                const topSideY = e.clientY - mouseCellContextOffsets.top;
                // Get cell side - right, left, top, bottom
                let side = 'bottom';
                if (leftSideX >= -offset && leftSideX <= offset) {
                    side = 'left';
                }
                else if (leftSideX - width >= -offset && leftSideX - width <= offset) {
                    side = 'right';
                }
                else if (topSideY >= -offset && topSideY <= offset) {
                    side = 'top';
                }
                else if (topSideY - height >= -offset && topSideY - height <= offset) {
                    side = 'bottom';
                }
                switch (side) {
                    case 'right':
                        sideOffset = leftSideX - width + offset;
                        break;
                    case 'left':
                        sideOffset = offset - leftSideX;
                        break;
                    case 'top':
                        sideOffset = offset - topSideY;
                        break;
                    case 'bottom':
                        sideOffset = topSideY - height + offset;
                        break;
                }
                const context = {
                    cell: mouseCellContext,
                    side: side
                };
                // Nested layouts.
                if (mouseCellContext.row?.layout.level &&
                    side &&
                    ContextDetection.isGUIElementOnParentEdge(mouseCellContext, side) &&
                    defined(sideOffset)) {
                    const level = ContextDetection.getContextLevel(mouseCellContext, offset, sideOffset, side);
                    const cell = mouseCellContext.getParentCell(level);
                    if (cell) {
                        context.cell = cell;
                    }
                }
                return context;
            }
        }

        return ContextDetection;
    });
    _registerModule(_modules, 'Dashboards/Actions/DragDrop.js', [_modules['Core/Utilities.js'], _modules['Dashboards/Globals.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Dashboards/Actions/ContextDetection.js']], function (U, Globals, EditGlobals, GUIElement, ContextDetection) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { addEvent, merge, css, fireEvent, createElement } = U;
        /**
         * Class providing a drag and drop functionality.
         * @internal
         */
        class DragDrop {
            /* *
             *
             *  Constructors
             *
             * */
            /**
             * Constructor for the DragDrop class.
             * @internal
             *
             * @param {EditMode} editMode
             * The parent editMode reference.
             *
             * @param {DragDrop.Options} options
             * Options for the DragDrop.
             */
            constructor(editMode, options) {
                this.editMode = editMode;
                this.options = merge(DragDrop.defaultOptions, options);
                this.mockElement = createElement('div', { className: EditGlobals.classNames.dragMock }, {}, editMode.board.container);
                this.dropPointer = {
                    isVisible: false,
                    align: '',
                    element: createElement('div', { className: EditGlobals.classNames.dropPointer }, {}, editMode.board.container)
                };
                this.isActive = false;
                this.initEvents();
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Method for showing and positioning drop pointer.
             *
             * @param {number} left
             * Drop pointer left position.
             *
             * @param {number} top
             * Drop pointer top position.
             *
             * @param {number} width
             * Drop pointer width.
             *
             * @param {number} height
             * Drop pointer height.
             */
            showDropPointer(left, top, width, height) {
                this.dropPointer.isVisible = true;
                css(this.dropPointer.element, {
                    display: 'block',
                    left: left + 'px',
                    top: top + 'px',
                    height: height + 'px',
                    width: width + 'px'
                });
            }
            /**
             * Method for hiding drop pointer.
             */
            hideDropPointer() {
                if (this.dropPointer.isVisible) {
                    this.dropPointer.isVisible = false;
                    this.dropPointer.align = '';
                    this.dropPointer.element.style.display = 'none';
                }
            }
            /**
             * Method for positioning drag mock element.
             *
             * @param {PointerEvent} mouseEvent
             * Mouse event.
             */
            setMockElementPosition(mouseEvent) {
                const dragDrop = this, dashBoundingRect = dragDrop.editMode.board.container.getBoundingClientRect(), offset = dragDrop.mockElement.clientWidth / 2, x = mouseEvent.clientX - dashBoundingRect.left - offset, y = mouseEvent.clientY - dashBoundingRect.top - offset;
                css(this.mockElement, { left: x + 'px', top: y + 'px' });
            }
            /**
             * Method for initializing drag drop events.
             */
            initEvents() {
                const dragDrop = this;
                // DragDrop events.
                addEvent(document, 'mousemove', dragDrop.onDrag.bind(dragDrop));
                addEvent(document, 'mouseup', dragDrop.onDragEnd.bind(dragDrop));
            }
            /**
             * General method used on drag start.
             *
             * @param {PointerEvent} e
             * Mouse event.
             *
             * @param {Cell|Row} context
             * Reference to the dragged context.
             *
             * @param {Function} dragEndCallback
             * Callback invoked on drag end.
             */
            onDragStart(e, context, dragEndCallback) {
                this.isActive = true;
                this.editMode.hideToolbars(['cell', 'row']);
                if (this.editMode.resizer) {
                    this.editMode.resizer.disableResizer();
                }
                this.setMockElementPosition(e);
                if (context) {
                    this.context = context;
                    context.hide();
                    if (context.getType() === Globals.guiElementType.cell) {
                        const draggedCell = context;
                        // Call cellResize board event.
                        fireEvent(this.editMode.board, 'cellResize', { cell: context });
                        fireEvent(draggedCell.row, 'cellChange', { cell: context, row: draggedCell.row });
                    }
                }
                else if (dragEndCallback) {
                    this.dragEndCallback = dragEndCallback;
                }
                css(this.mockElement, {
                    cursor: 'grabbing',
                    display: 'block'
                });
            }
            /**
             * General method used while dragging.
             *
             * @param {PointerEvent} e
             * Mouse event.
             */
            onDrag(e) {
                const dragDrop = this;
                if (dragDrop.isActive) {
                    e.preventDefault();
                    dragDrop.setMockElementPosition(e);
                    if (dragDrop.context) {
                        if (dragDrop.context.getType() ===
                            Globals.guiElementType.cell) {
                            dragDrop.onCellDrag(e);
                        }
                        else if (dragDrop.context.getType() ===
                            Globals.guiElementType.row) {
                            dragDrop.onRowDrag(e);
                        }
                    }
                    else if (dragDrop.dragEndCallback) {
                        dragDrop.onCellDrag(e);
                    }
                }
            }
            /**
             * General method used when drag finish.
             */
            onDragEnd() {
                const dragDrop = this;
                if (dragDrop.isActive) {
                    dragDrop.isActive = false;
                    css(dragDrop.mockElement, {
                        cursor: 'grab',
                        display: 'none'
                    });
                    if (dragDrop.context) {
                        if (dragDrop.context.getType() ===
                            Globals.guiElementType.cell) {
                            dragDrop.onCellDragEnd();
                        }
                        else if (dragDrop.context.getType() ===
                            Globals.guiElementType.row) {
                            dragDrop.onRowDragEnd();
                        }
                        dragDrop.context = void 0;
                        // Show toolbars and snaps.
                        if (dragDrop.editMode.editCellContext) {
                            dragDrop.editMode.showToolbars(['row', 'cell'], dragDrop.editMode.editCellContext);
                            if (dragDrop.editMode.resizer) {
                                dragDrop.editMode.resizer.setSnapPositions(dragDrop.editMode.editCellContext);
                            }
                        }
                    }
                    else if (dragDrop.dragEndCallback) {
                        dragDrop.dragEndCallback(dragDrop.dropContext);
                        dragDrop.dragEndCallback = void 0;
                        dragDrop.hideDropPointer();
                    }
                }
            }
            /**
             * Sets appropriate drop context and refresh drop pointer position when
             * row is dragged or cell is dragged as a row.
             *
             * @param {PointerEvent} e
             * Mouse event.
             *
             * @param {ContextDetection.ContextDetails} contextDetails
             * Context details (cell, side)
             */
            onRowDrag(e, contextDetails) {
                const dragDrop = this, mouseCellContext = dragDrop.mouseCellContext, dropPointerSize = dragDrop.options.dropPointerSize || 0, offset = dragDrop.options.rowDropOffset || 0;
                let updateDropPointer = false;
                if (mouseCellContext) {
                    const context = (contextDetails ||
                        ContextDetection.getContext(mouseCellContext, e, offset));
                    const align = context.side;
                    if (dragDrop.dropPointer.align !== align ||
                        dragDrop.dropContext !== context.cell.row) {
                        updateDropPointer = true;
                        dragDrop.dropPointer.align = align;
                        dragDrop.dropContext = context.cell.row;
                    }
                    if (align) {
                        const dropContextRowOffsets = GUIElement.getOffsets(dragDrop.dropContext, dragDrop.editMode.board.container);
                        const { width, height } = GUIElement
                            .getDimFromOffsets(dropContextRowOffsets);
                        // Update or show drop pointer.
                        if (!dragDrop.dropPointer.isVisible || updateDropPointer) {
                            dragDrop.showDropPointer(dropContextRowOffsets.left, dropContextRowOffsets.top + (dragDrop.dropPointer.align === 'bottom' ?
                                height :
                                0) - dropPointerSize / 2, width, dropPointerSize);
                        }
                    }
                    else {
                        dragDrop.dropContext = void 0;
                        dragDrop.hideDropPointer();
                    }
                }
            }
            /**
             * Unmounts dropped row and mounts it in a new position.
             *
             * @fires DragDrop#layoutChanged
             */
            onRowDragEnd() {
                const dragDrop = this, draggedRow = dragDrop.context, dropContext = dragDrop.dropContext;
                if (dragDrop.dropPointer.align) {
                    draggedRow.layout.unmountRow(draggedRow);
                    // Destroy layout when empty.
                    if (draggedRow.layout.rows.length === 0) {
                        draggedRow.layout.destroy();
                    }
                    dropContext.layout.mountRow(draggedRow, (dropContext.layout.getRowIndex(dropContext) || 0) +
                        (dragDrop.dropPointer.align === 'bottom' ? 1 : 0));
                    // Call cellResize board event.
                    if (draggedRow.cells[0]) {
                        fireEvent(dragDrop.editMode.board, 'cellResize', { cell: draggedRow.cells[0] });
                        fireEvent(draggedRow, 'cellChange', { cell: draggedRow.cells[0], row: draggedRow });
                    }
                }
                dragDrop.hideDropPointer();
                draggedRow.show();
                fireEvent(dragDrop.editMode, 'layoutChanged', {
                    type: 'rowDragEnd',
                    target: draggedRow,
                    board: dragDrop.editMode.board
                });
            }
            /**
             * Method used as middleware when cell is dragged.
             * Decides where to pass an event depending on the mouse context.
             *
             * @param {PointerEvent} e
             * Mouse event.
             *
             * @param {ContextDetection.ContextDetails} contextDetails
             * Context details (cell, side)
             */
            onCellDrag(e, contextDetails) {
                const dragDrop = this, mouseCellContext = dragDrop.mouseCellContext, offset = dragDrop.options.cellDropOffset || 0;
                if (mouseCellContext || contextDetails) {
                    dragDrop.onCellDragCellCtx(e, contextDetails ||
                        ContextDetection.getContext(mouseCellContext, e, offset));
                }
                else if (dragDrop.mouseRowContext) {
                    dragDrop.onCellDragRowCtx(e, dragDrop.mouseRowContext);
                }
            }
            /**
             * Sets appropriate drop context and refreshes the drop pointer
             * position when a cell is dragged and a cell context is detected.
             *
             * @param {PointerEvent} e
             * Mouse event.
             *
             * @param {ContextDetection.ContextDetails} context
             * Context details (cell, side)
             */
            onCellDragCellCtx(e, context) {
                const dragDrop = this, dropPointerSize = dragDrop.options.dropPointerSize || 0, align = context.side;
                let updateDropPointer = false;
                if (dragDrop.dropPointer.align !== align ||
                    dragDrop.dropContext !== context.cell) {
                    updateDropPointer = true;
                    dragDrop.dropPointer.align = align;
                    dragDrop.dropContext = context.cell;
                }
                if (align === 'right' || align === 'left') {
                    const dropContextOffsets = GUIElement.getOffsets(dragDrop.dropContext, dragDrop.editMode.board.container);
                    const { width, height } = GUIElement.getDimFromOffsets(dropContextOffsets);
                    // Update or show drop pointer.
                    if (!dragDrop.dropPointer.isVisible || updateDropPointer) {
                        const rowLevelInfo = dragDrop.dropContext.row.getRowLevelInfo(e.clientY), pointerHeight = (rowLevelInfo ?
                            (rowLevelInfo.rowLevel.bottom -
                                rowLevelInfo.rowLevel.top) :
                            height);
                        dragDrop.showDropPointer(dropContextOffsets.left + (align === 'right' ? width : 0) -
                            dropPointerSize / 2, dropContextOffsets.top, dropPointerSize, pointerHeight);
                    }
                }
                else if (align === 'top' || align === 'bottom') {
                    const dropContextOffsets = GUIElement.getOffsets(dragDrop.dropContext), rowLevelInfo = dragDrop.dropContext.row
                        .getRowLevelInfo(dropContextOffsets.top);
                    if (rowLevelInfo &&
                        ((rowLevelInfo.index === 0 && align === 'top') ||
                            (rowLevelInfo.index ===
                                rowLevelInfo.rowLevels.length - 1 &&
                                align === 'bottom'))) {
                        // Checks if a cell is dragged as a row
                        // (only when a cell edge is on a row edge)
                        dragDrop.onRowDrag(e, context);
                    }
                }
                else {
                    dragDrop.dropContext = void 0;
                    dragDrop.hideDropPointer();
                }
            }
            /**
             * Sets appropriate drop context and refreshes the drop pointer
             * position when a cell is dragged and a row context is detected.
             *
             * @param {PointerEvent} e
             * Mouse event.
             *
             * @param {Row} mouseRowContext
             * Row context.
             */
            onCellDragRowCtx(e, mouseRowContext) {
                const dragDrop = this, dropPointerSize = dragDrop.options.dropPointerSize || 0, rowOffsets = GUIElement.getOffsets(mouseRowContext), rowLevelInfo = mouseRowContext.getRowLevelInfo(e.clientY);
                let cell, cellOffsets;
                if (rowLevelInfo) {
                    for (let i = 0, iEnd = rowLevelInfo.rowLevel.cells.length; i < iEnd; ++i) {
                        cell = rowLevelInfo.rowLevel.cells[i];
                        cellOffsets = GUIElement.getOffsets(cell);
                        const { width, height } = GUIElement
                            .getDimFromOffsets(cellOffsets), dashOffsets = dragDrop.editMode.board.container
                            .getBoundingClientRect(), levelHeight = (rowLevelInfo.rowLevel.bottom -
                            rowLevelInfo.rowLevel.top);
                        if (cell.isVisible) {
                            if (height < 0.8 * levelHeight &&
                                cellOffsets.left <= e.clientX &&
                                cellOffsets.right >= e.clientX) {
                                if (cellOffsets.top > e.clientY) {
                                    // @ToDo - Mouse above the cell.
                                }
                                else if (cellOffsets.bottom < e.clientY) {
                                    // Mouse below the cell.
                                    dragDrop.showDropPointer(cellOffsets.left - dashOffsets.left, cellOffsets.top - dashOffsets.top + height, width, levelHeight - height);
                                    dragDrop.dropPointer.align = 'nestedBottom';
                                    dragDrop.dropContext = cell;
                                }
                                i = iEnd; // Stop the loop
                            }
                            else if ((i === 0 && cellOffsets.left > e.clientX) ||
                                (i === iEnd - 1 && cellOffsets.right < e.clientX)) {
                                if (cellOffsets.left > e.clientX) {
                                    // @ToDo - Mouse on the cell left side.
                                }
                                else if (cellOffsets.right < e.clientX) {
                                    // Mouse on the cell right side.
                                    const pointerWidth = rowOffsets.right - cellOffsets.right;
                                    dragDrop.showDropPointer(cellOffsets.left + ((i === 0 && cellOffsets.left > e.clientX) ?
                                        0 :
                                        width) - dropPointerSize / 2 - dashOffsets.left, cellOffsets.top - dashOffsets.top, pointerWidth > dropPointerSize ?
                                        pointerWidth :
                                        dropPointerSize, levelHeight || height);
                                    dragDrop.dropPointer.align = 'right';
                                    dragDrop.dropContext = cell;
                                }
                                i = iEnd; // Stop the loop
                            }
                        }
                        else if (!cell.isVisible && cell === dragDrop.context) {
                            // Element is not visible.
                            dragDrop.dropContext = void 0;
                            dragDrop.hideDropPointer();
                        }
                    }
                }
            }
            /**
             * Unmounts dropped cell and mounts it in a new position.
             * When cell is dragged as a row also creates a new row
             * and mounts cell there.
             *
             * @param {Cell} contextCell
             * Cell used as a dragDrop context.
             *
             * @fires DragDrop#layoutChanged
             */
            onCellDragEnd(contextCell) {
                const dragDrop = this, draggedCell = contextCell || dragDrop.context;
                let dropContext = dragDrop.dropContext;
                if (dragDrop.dropPointer.align && dropContext && draggedCell) {
                    draggedCell.row.unmountCell(draggedCell);
                    // Destroy row when empty.
                    if (draggedCell.row.cells.length === 0) {
                        draggedCell.row.destroy();
                    }
                    if ((dragDrop.dropPointer.align === 'top' ||
                        dragDrop.dropPointer.align === 'bottom') &&
                        dropContext.getType() === Globals.guiElementType.row) {
                        dropContext = dropContext;
                        const newRow = dropContext.layout.addRow({}, void 0, (dropContext.layout.getRowIndex(dropContext) || 0) +
                            (dragDrop.dropPointer.align === 'bottom' ? 1 : 0));
                        newRow.mountCell(draggedCell, 0);
                    }
                    else if (dragDrop.dropPointer.align === 'nestedBottom' &&
                        dropContext.getType() === Globals.guiElementType.cell) {
                        // Create nesting.
                        const dropContextCell = dropContext;
                        const row = dropContextCell.row;
                        const dropContextCellIndex = row.getCellIndex(dropContextCell);
                        row.unmountCell(dropContextCell);
                        const newCell = row.addCell({
                            id: GUIElement.getElementId('col-nested'),
                            layout: {
                                rows: [{}, {}]
                            }
                        }, void 0, dropContextCellIndex);
                        if (newCell.nestedLayout) {
                            newCell.nestedLayout.rows[0].mountCell(dropContextCell);
                            newCell.nestedLayout.rows[1].mountCell(draggedCell);
                        }
                    }
                    else if (dropContext.getType() === Globals.guiElementType.cell) {
                        dropContext = dropContext;
                        dropContext.row.mountCell(draggedCell, (dropContext.row.getCellIndex(dropContext) || 0) +
                            (dragDrop.dropPointer.align === 'right' ? 1 : 0));
                    }
                }
                // Call cellResize board event.
                fireEvent(dragDrop.editMode.board, 'cellResize', { cell: draggedCell });
                fireEvent(draggedCell.row, 'cellChange', { cell: draggedCell, row: draggedCell.row });
                dragDrop.hideDropPointer();
                draggedCell.show();
                fireEvent(dragDrop.editMode, 'layoutChanged', {
                    type: 'cellDragEnd',
                    target: draggedCell,
                    board: dragDrop.editMode.board
                });
            }
        }
        /* *
         *
         *  Static Properties
         *
         * */
        DragDrop.defaultOptions = {
            enabled: true,
            rowDropOffset: 30,
            cellDropOffset: 30,
            dropPointerSize: 16
        };
        /* *
         *
         *  Default Export
         *
         * */

        return DragDrop;
    });
    _registerModule(_modules, 'Dashboards/Actions/Resizer.js', [_modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Core/Utilities.js']], function (EditGlobals, GUIElement, U) {
        const { merge, addEvent, createElement, fireEvent, removeEvent } = U;
        /**
         * Class providing a resizing functionality.
         */
        class Resizer {
            /* *
            *
            *  Static Properties
            *
            * */
            /**
             * Creates a new instance of the Resizer class based on JSON.
             * @internal
             */
            static fromJSON(editMode, json) {
                return new Resizer(editMode, json.options);
            }
            /* *
            *
            *  Constructors
            *
            * */
            /**
             * Constructor for the Resizer class.
             *
             * @param {EditMode} editMode
             * The parent editMode reference.
             *
             * @param {Resizer.Options} options
             * Options for the Resizer.
             */
            constructor(editMode, options) {
                this.editMode = editMode;
                this.options = merge({}, Resizer.defaultOptions, editMode.options.resize, options);
                this.currentCell = void 0;
                this.isX = this.options.type.indexOf('x') > -1;
                this.isY = this.options.type.indexOf('y') > -1;
                this.isActive = false;
                this.startX = 0;
                this.tempSiblingsWidth = [];
                this.addSnaps();
            }
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Add Snap - create snaps and add events.
             *
             */
            addSnaps() {
                const iconsURLPrefix = this.editMode.iconsURLPrefix;
                const snapWidth = this.options.snap.width || 0;
                const snapHeight = this.options.snap.height || 0;
                const dashboardContainer = this.editMode.board.container;
                // Right snap
                this.snapRight = createElement('img', {
                    className: EditGlobals.classNames.resizeSnap + ' ' +
                        EditGlobals.classNames.resizeSnapX,
                    src: iconsURLPrefix + 'resize-handle.svg'
                }, {
                    width: snapWidth + 'px',
                    height: snapHeight + 'px',
                    left: -9999 + 'px'
                }, dashboardContainer);
                // Bottom snap
                this.snapBottom = createElement('img', {
                    className: EditGlobals.classNames.resizeSnap + ' ' +
                        EditGlobals.classNames.resizeSnapY,
                    src: iconsURLPrefix + 'resize-handle.svg'
                }, {
                    width: snapWidth + 'px',
                    height: snapHeight + 'px',
                    top: -9999 + 'px',
                    left: '0px'
                }, dashboardContainer);
                this.addResizeEvents();
            }
            /**
             * Hide snaps
             *
             */
            disableResizer() {
                this.isActive = false;
                this.currentDimension = void 0;
                this.currentCell = void 0;
                if (this.snapRight) {
                    this.snapRight.style.left = '-9999px';
                }
                if (this.snapBottom) {
                    this.snapBottom.style.left = '-9999px';
                }
            }
            /**
             * Update snap position.
             *
             * @param cell
             * Cell reference
             */
            setSnapPositions(cell) {
                // Set current cell
                this.currentCell = cell;
                // Set position of snaps
                const cellOffsets = GUIElement.getOffsets(cell, this.editMode.board.container);
                const left = cellOffsets.left || 0;
                const top = cellOffsets.top || 0;
                const { width, height } = GUIElement.getDimFromOffsets(cellOffsets);
                const snapWidth = (this.options.snap.width || 0);
                const snapHeight = (this.options.snap.height || 0);
                if (this.snapRight) {
                    this.snapRight.style.left = (left + width - snapWidth) + 'px';
                    this.snapRight.style.top = top + (height / 2) - (snapHeight / 2) + 'px';
                }
                if (this.snapBottom) {
                    this.snapBottom.style.top = (top + height - snapHeight) + 'px';
                    this.snapBottom.style.left = (left + (width / 2) - (snapWidth / 2)) + 'px';
                }
            }
            /**
             * Method detects siblings and auto-width applied by flex. The resizer
             * requires static widths for correct calculations, so we need to apply
             * temporary width on siblings.
             */
            setTempWidthSiblings() {
                const currentCell = this.currentCell;
                if (currentCell) {
                    const cellOffsets = GUIElement.getOffsets(currentCell), rowLevelInfo = currentCell.row.getRowLevelInfo(cellOffsets.top), rowLevelCells = (rowLevelInfo && rowLevelInfo.rowLevel.cells) || [];
                    let cellContainer, cell;
                    for (let i = 0, iEnd = rowLevelCells.length; i < iEnd; ++i) {
                        cell = rowLevelCells[i];
                        cellContainer = cell.container;
                        // Do not convert width on the current cell and next siblings.
                        if (cell === currentCell) {
                            break;
                        }
                        if (cellContainer) {
                            cellContainer.style.flex =
                                '0 0 ' + cellContainer.offsetWidth + 'px';
                            this.tempSiblingsWidth.push(cell);
                        }
                    }
                }
            }
            /**
             * Revert widths to auto.
             */
            revertSiblingsAutoWidth() {
                const tempSiblingsWidth = this.tempSiblingsWidth;
                let cellContainer, cellResize;
                for (let i = 0, iEnd = tempSiblingsWidth.length; i < iEnd; ++i) {
                    cellContainer = tempSiblingsWidth[i].container;
                    if (cellContainer) {
                        cellContainer.style.flex = '1 1 0%';
                        cellResize = tempSiblingsWidth[i];
                    }
                }
                this.tempSiblingsWidth = [];
                // Call cellResize dashboard event.
                if (cellResize) {
                    fireEvent(this.editMode.board, 'cellResize', {
                        cell: cellResize
                    });
                    fireEvent(cellResize.row, 'cellChange', {
                        cell: cellResize,
                        row: cellResize.row
                    });
                }
            }
            /**
             * Add mouse events to snaps
             *
             */
            addResizeEvents() {
                const resizer = this;
                let mouseDownSnapX, mouseDownSnapY, mouseMoveSnap, mouseUpSnap;
                resizer.mouseDownSnapX = mouseDownSnapX = function (e) {
                    resizer.isActive = true;
                    resizer.currentDimension = 'x';
                    resizer.editMode.hideToolbars(['row', 'cell']);
                    resizer.setTempWidthSiblings();
                    resizer.startX = e.clientX;
                };
                resizer.mouseDownSnapY = mouseDownSnapY = function () {
                    resizer.isActive = true;
                    resizer.currentDimension = 'y';
                    resizer.editMode.hideToolbars(['row', 'cell']);
                };
                resizer.mouseMoveSnap = mouseMoveSnap = function (e) {
                    if (resizer.isActive) {
                        resizer.onMouseMove(e);
                    }
                };
                resizer.mouseUpSnap = mouseUpSnap = function () {
                    if (resizer.isActive) {
                        resizer.isActive = false;
                        resizer.currentDimension = void 0;
                        resizer.revertSiblingsAutoWidth();
                        resizer.editMode.showToolbars(['row', 'cell'], resizer.currentCell);
                        if (resizer.currentCell) {
                            resizer.setSnapPositions(resizer.currentCell);
                        }
                    }
                };
                // Add mouse events
                addEvent(this.snapRight, 'mousedown', mouseDownSnapX);
                addEvent(this.snapBottom, 'mousedown', mouseDownSnapY);
                addEvent(document, 'mousemove', mouseMoveSnap);
                addEvent(document, 'mouseup', mouseUpSnap);
                // Touch events
                // addEvent(snapX, 'touchstart', mouseDownSnapX);
                // addEvent(snapY, 'touchstart', mouseDownSnapY);
                // if (!rowContainer.hcEvents.mousemove) {
                //     addEvent(rowContainer, 'touchmove', mouseMoveSnap);
                //     addEvent(rowContainer, 'touchend', mouseUpSnap);
                // }
                const runReflow = () => {
                    if (resizer.currentCell) {
                        resizer.setSnapPositions(resizer.currentCell);
                    }
                };
                if (typeof ResizeObserver === 'function') {
                    this.resizeObserver = new ResizeObserver(runReflow);
                    this.resizeObserver.observe(resizer.editMode.board.container);
                }
                else {
                    const unbind = addEvent(window, 'resize', runReflow);
                    addEvent(this, 'destroy', unbind);
                }
            }
            /**
             * General method used on resizing.
             *
             * @param {global.Event} e
             * A mouse event.
             *
             */
            onMouseMove(e) {
                const currentCell = this.currentCell;
                const cellContainer = currentCell && currentCell.container;
                const currentDimension = this.currentDimension;
                if (currentCell &&
                    cellContainer &&
                    !((currentCell.row.layout.board.editMode || {}).dragDrop || {})
                        .isActive) {
                    const cellOffsets = GUIElement.getOffsets(currentCell);
                    const { width: parentRowWidth } = GUIElement.getDimFromOffsets(GUIElement.getOffsets(currentCell.row));
                    // Resize width
                    if (currentDimension === 'x') {
                        const newWidth = (Math.min(e.clientX - cellOffsets.left, parentRowWidth) /
                            parentRowWidth) *
                            100 +
                            '%';
                        currentCell.setSize(newWidth);
                        this.startX = e.clientX;
                    }
                    // Resize height
                    if (currentDimension === 'y') {
                        currentCell.setSize(void 0, e.clientY - cellOffsets.top);
                    }
                    // Call cellResize dashboard event.
                    fireEvent(this.editMode.board, 'cellResize', {
                        cell: currentCell
                    });
                    fireEvent(currentCell.row, 'cellChange', {
                        cell: currentCell,
                        row: currentCell.row
                    });
                    this.setSnapPositions(currentCell);
                }
            }
            /**
             * Destroy resizer
             */
            destroy() {
                const snaps = ['snapRight', 'snapBottom'];
                let snap;
                // Unbind events
                removeEvent(document, 'mousemove');
                removeEvent(document, 'mouseup');
                this.resizeObserver?.unobserve(this.editMode.board.container);
                for (let i = 0, iEnd = snaps.length; i < iEnd; ++i) {
                    snap = this[snaps[i]];
                    // Unbind event
                    removeEvent(snap, 'mousedown');
                    // Destroy snap
                    snap.remove();
                }
            }
            /**
             * Converts the class instance to a class JSON.
             * @internal
             *
             * @return {Resizer.JSON}
             * Class JSON of this Resizer instance.
             */
            toJSON() {
                const options = this.options;
                return {
                    $class: 'Dashboards.Action.Resizer',
                    options: {
                        enabled: options.enabled,
                        styles: {
                            minWidth: options.styles.minWidth,
                            minHeight: options.styles.minHeight
                        },
                        type: options.type,
                        snap: {
                            width: options.snap.width,
                            height: options.snap.height
                        }
                    }
                };
            }
        }
        Resizer.defaultOptions = {
            enabled: true,
            styles: {
                minWidth: 20,
                minHeight: 50
            },
            type: 'xy',
            snap: {
                width: 9,
                height: 17
            }
        };

        return Resizer;
    });
    _registerModule(_modules, 'Dashboards/EditMode/EditMode.js', [_modules['Dashboards/Layout/Cell.js'], _modules['Dashboards/Layout/CellHTML.js'], _modules['Dashboards/EditMode/EditGlobals.js'], _modules['Dashboards/EditMode/EditRenderer.js'], _modules['Dashboards/EditMode/Toolbar/CellEditToolbar.js'], _modules['Dashboards/EditMode/Toolbar/RowEditToolbar.js'], _modules['Dashboards/EditMode/SidebarPopup.js'], _modules['Dashboards/EditMode/EditContextMenu.js'], _modules['Dashboards/Actions/DragDrop.js'], _modules['Dashboards/Actions/Resizer.js'], _modules['Dashboards/EditMode/ConfirmationPopup.js'], _modules['Dashboards/Layout/GUIElement.js'], _modules['Dashboards/Globals.js'], _modules['Dashboards/Layout/Layout.js'], _modules['Core/Utilities.js']], function (Cell, CellHTML, EditGlobals, EditRenderer, CellEditToolbar, RowEditToolbar, SidebarPopup, EditContextMenu, DragDrop, Resizer, ConfirmationPopup, GUIElement, Globals, Layout, U) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { addEvent, createElement, css, merge } = U;
        /* *
         *
         *  Class
         *
         * */
        class EditMode {
            /* *
            *
            *  Constructor
            *
            * */
            /**
             * Edit mode constructor.
             * @internal
              *
             * @param board
             * Board instance
             *
             * @param options
             * Edit mode options
             */
            constructor(board, options) {
                /* *
                *
                *  Properties
                *
                * */
                /**
                 * @internal
                 */
                this.active = false;
                /**
                 * Whether the board is generated with custom HTML.
                 */
                this.customHTMLMode = false;
                /**
                 * URL from which the icons will be fetched.
                 */
                this.iconsURLPrefix = 'https://code.highcharts.com/dashboards/3.5.0/gfx/dashboards-icons/';
                this.iconsURLPrefix =
                    (options && options.iconsURLPrefix) || this.iconsURLPrefix;
                this.options = merge(
                // Default options.
                {
                    confirmationPopup: {
                        close: {
                            icon: this.iconsURLPrefix + 'close.svg'
                        }
                    },
                    contextMenu: {
                        icon: this.iconsURLPrefix + 'menu.svg'
                    },
                    dragDrop: {
                        enabled: true
                    },
                    enabled: true,
                    resize: {
                        enabled: true
                    },
                    settings: {
                        enabled: true
                    },
                    toolbars: {
                        cell: {
                            enabled: true
                        },
                        row: {
                            enabled: true
                        }
                    },
                    tools: {
                        addComponentBtn: {
                            enabled: true,
                            icon: this.iconsURLPrefix + 'add.svg'
                        }
                    }
                }, options || {});
                this.board = board;
                this.lang = merge({}, EditGlobals.lang, this.options.lang);
                board.boardWrapper = board.container;
                if (board.guiEnabled) {
                    this.initLayout();
                }
                this.isInitialized = false;
                this.isContextDetectionActive = false;
                this.tools = {};
                if (board.editModeEnabled) {
                    this.customHTMLMode = !this.board.layoutsWrapper;
                    this.contextPointer = {
                        isVisible: false,
                        element: createElement('div', {
                            className: EditGlobals.classNames.contextDetectionPointer
                        }, {}, board.container)
                    };
                    this.createTools();
                    this.confirmationPopup = new ConfirmationPopup(board.container, this.iconsURLPrefix, this, this.options.confirmationPopup);
                    // Create edit overlay.
                    this.editOverlay = createElement('div', {
                        className: EditGlobals.classNames.editOverlay
                    }, {}, board.container);
                    this.isEditOverlayActive = false;
                    board.fullscreen = new Dashboards.Fullscreen(board);
                    if (this.customHTMLMode) {
                        board.container.classList.add(Globals.classNames.boardContainer);
                    }
                }
            }
            /* *
            *
            *  Functions
            *
            * */
            /**
             * Event to fire on click of the context button.
             * @internal
             */
            onContextBtnClick() {
                const editMode = this;
                // Toggle context menu visibility.
                if (editMode.tools.contextMenu) {
                    if (!editMode.tools.contextMenu.isVisible) {
                        editMode.tools.contextMenu
                            .updatePosition(editMode.tools.contextButtonElement);
                    }
                    editMode.tools.contextMenu.setVisible(!editMode.tools.contextMenu.isVisible);
                }
            }
            /**
             * Activate or deactivate edit mode.
             */
            toggleEditMode() {
                const editMode = this;
                if (editMode.active) {
                    editMode.deactivate();
                }
                else {
                    editMode.activate();
                }
            }
            /**
             * Init the instance of edit mode.
             * @internal
             */
            init() {
                const editMode = this;
                if (this.options.resize?.enabled && !editMode.customHTMLMode) {
                    editMode.resizer = new Resizer(editMode, editMode.options.resize);
                }
                editMode.dragDrop = new DragDrop(editMode, editMode.options.dragDrop);
                // Init rowToolbar.
                if (editMode.options.toolbars?.row?.enabled &&
                    !editMode.rowToolbar &&
                    !editMode.customHTMLMode) {
                    editMode.rowToolbar = new RowEditToolbar(editMode);
                }
                // Init cellToolbar.
                if (editMode.options.toolbars?.cell?.enabled && !editMode.cellToolbar) {
                    editMode.cellToolbar = new CellEditToolbar(editMode);
                }
                // Init Sidebar.
                if (!editMode.sidebar) {
                    editMode.sidebar = new SidebarPopup(this.board.container, this.iconsURLPrefix, editMode);
                }
                editMode.isInitialized = true;
            }
            /**
             * Init events for edit mode.
             * @internal
             */
            initEvents() {
                const editMode = this, board = editMode.board;
                if (this.customHTMLMode) {
                    const length = board.mountedComponents.length;
                    for (let i = 0, iEnd = length; i < iEnd; ++i) {
                        editMode.setCellEvents(board.mountedComponents[i].cell);
                    }
                }
                else {
                    for (let i = 0, iEnd = board.layouts.length; i < iEnd; ++i) {
                        editMode.setLayoutEvents(board.layouts[i]);
                    }
                }
                addEvent(document, 'keydown', (e) => {
                    if (e.key === 'Escape' && editMode.isActive()) {
                        editMode.hideToolbars(['cell', 'row']);
                        editMode.editCellContext = void 0;
                        editMode.resizer?.disableResizer();
                    }
                });
                if (editMode.cellToolbar) {
                    // Stop context detection when mouse on cell toolbar.
                    addEvent(editMode.cellToolbar.container, 'mouseenter', function () {
                        editMode.stopContextDetection();
                    });
                    addEvent(editMode.cellToolbar.container, 'mouseleave', function () {
                        editMode.isContextDetectionActive = true;
                    });
                }
                if (editMode.rowToolbar) {
                    // Stop context detection when mouse on row toolbar.
                    addEvent(editMode.rowToolbar.container, 'mouseenter', function () {
                        editMode.stopContextDetection();
                    });
                    addEvent(editMode.rowToolbar.container, 'mouseleave', function () {
                        editMode.isContextDetectionActive = true;
                    });
                }
                const elementForEvents = this.customHTMLMode ?
                    board.container : board.layoutsWrapper;
                addEvent(elementForEvents, 'mousemove', editMode.onDetectContext.bind(editMode));
                addEvent(elementForEvents, 'click', editMode.onContextConfirm.bind(editMode));
                addEvent(elementForEvents, 'mouseleave', () => {
                    editMode.hideContextPointer();
                });
            }
            /**
             * Initialize the container for the layouts.
             * @internal
             *
             */
            initLayout() {
                const board = this.board;
                // Clear the container from any content.
                board.container.innerHTML = '';
                // Add container for the board.
                board.container = createElement('div', {
                    className: Globals.classNames.boardContainer
                }, {}, board.boardWrapper);
                // Create layouts wrapper.
                board.layoutsWrapper = createElement('div', {
                    className: Globals.classNames.layoutsWrapper
                }, {}, board.container);
                if (board.options.gui) {
                    this.setLayouts(board.options.gui);
                }
            }
            /**
             * Creates a new layouts and adds it to the dashboard based on the options.
             * @internal
             *
             * @param guiOptions
             * The GUI options for the layout.
             *
             */
            setLayouts(guiOptions) {
                const board = this.board, layoutsOptions = guiOptions.layouts;
                for (let i = 0, iEnd = layoutsOptions.length; i < iEnd; ++i) {
                    board.layouts.push(new Layout(board, merge({}, guiOptions.layoutOptions, layoutsOptions[i])));
                }
            }
            /**
             * Set events for the layout.
             * @internal
             */
            setLayoutEvents(layout) {
                const editMode = this;
                for (let j = 0, jEnd = layout.rows.length; j < jEnd; ++j) {
                    const row = layout.rows[j];
                    editMode.setRowEvents(row);
                    for (let k = 0, kEnd = row.cells.length; k < kEnd; ++k) {
                        editMode.setCellEvents(row.cells[k]);
                    }
                }
            }
            /**
             * Set events for the row.
             * @internal
             */
            setRowEvents(row) {
                const editMode = this;
                // Init dragDrop row events.
                if (editMode.dragDrop) {
                    const dragDrop = editMode.dragDrop;
                    addEvent(row.container, 'mouseenter', function () {
                        if (editMode.isContextDetectionActive) {
                            editMode.mouseRowContext = row;
                        }
                    });
                    addEvent(row.container, 'mousemove', function (e) {
                        if (dragDrop.isActive && e.target === row.container) {
                            dragDrop.mouseRowContext = row;
                        }
                    });
                    addEvent(row.container, 'mouseleave', function () {
                        if (dragDrop.isActive && dragDrop.mouseRowContext === row) {
                            dragDrop.mouseRowContext = void 0;
                        }
                        if (editMode.isContextDetectionActive) {
                            editMode.mouseRowContext = void 0;
                        }
                    });
                }
            }
            /**
             * Set events for the cell.
             * @internal
             */
            setCellEvents(cell) {
                const editMode = this;
                if (CellHTML.isCellHTML(cell)) {
                    addEvent(cell.container, 'mouseenter', function () {
                        if (editMode.isContextDetectionActive) {
                            editMode.mouseCellContext = cell;
                        }
                    });
                }
                else {
                    if (cell.nestedLayout) {
                        editMode.setLayoutEvents(cell.nestedLayout);
                    }
                    else if (editMode.cellToolbar && cell.container) {
                        addEvent(cell.container, 'mouseenter', function () {
                            if (editMode.isContextDetectionActive) {
                                editMode.mouseCellContext = cell;
                            }
                        });
                        // Init dragDrop cell events only when using layouts.
                        if ((editMode.dragDrop || editMode.resizer)) {
                            const dragDrop = editMode.dragDrop;
                            addEvent(cell.container, 'mousemove', function (e) {
                                if (dragDrop &&
                                    dragDrop.isActive &&
                                    e.target === cell.container) {
                                    dragDrop.mouseCellContext = cell;
                                    dragDrop.mouseRowContext = void 0;
                                }
                            });
                            addEvent(cell.container, 'mouseleave', function () {
                                if (dragDrop &&
                                    dragDrop.isActive &&
                                    dragDrop.mouseCellContext === cell) {
                                    dragDrop.mouseCellContext = void 0;
                                }
                                if (editMode.isContextDetectionActive) {
                                    editMode.mouseCellContext = void 0;
                                }
                            });
                        }
                    }
                }
            }
            /**
             * Activate the edit mode.
             * @internal
             */
            activate() {
                const editMode = this;
                // Init edit mode.
                if (!editMode.isInitialized) {
                    editMode.init();
                    editMode.initEvents();
                }
                // Set edit mode active class to dashboard.
                editMode.board.container.classList.add(EditGlobals.classNames.editModeEnabled);
                if (this.addComponentBtn) {
                    this.addComponentBtn.style.display = 'block';
                }
                editMode.active = true;
                editMode.isContextDetectionActive = true;
            }
            /**
             * Deactivate the edit mode.
             * @internal
             */
            deactivate() {
                const editMode = this, dashboardCnt = editMode.board.container;
                dashboardCnt.classList.remove(EditGlobals.classNames.editModeEnabled);
                // Hide toolbars.
                editMode.hideToolbars();
                // Remove highlight from the context row if exists.
                if (this.editCellContext && Cell.isCell(this.editCellContext)) {
                    this.editCellContext.row?.setHighlight();
                }
                // TODO all buttons should be deactivated.
                if (this.addComponentBtn) {
                    this.addComponentBtn.style.display = 'none';
                }
                if (editMode.resizer) {
                    editMode.resizer.disableResizer();
                }
                // Disable responsive width and restore elements to their original
                // positions and sizes.
                if (this.board.layoutsWrapper) {
                    this.board.layoutsWrapper.style.width = '100%';
                }
                this.board.reflow();
                editMode.active = false;
                editMode.stopContextDetection();
                this.editCellContext = void 0;
                this.potentialCellContext = void 0;
            }
            /**
             * Function to check whether the edit mode is activated.
             * @internal
             *
             * @returns
             * Whether the edit mode is activated.
             */
            isActive() {
                return this.active;
            }
            /**
             * Method for hiding edit toolbars.
             * @internal
             *
             * @param toolbarTypes
             * The array of toolbar names to hide ('cell', 'row', 'sidebar').
             */
            hideToolbars(toolbarTypes) {
                const editMode = this, toolbarsToHide = toolbarTypes || ['cell', 'row', 'sidebar'];
                for (let i = 0, iEnd = toolbarsToHide.length; i < iEnd; ++i) {
                    switch (toolbarsToHide[i]) {
                        case 'cell': {
                            if (editMode.cellToolbar &&
                                editMode.cellToolbar.isVisible) {
                                editMode.cellToolbar.hide();
                            }
                            break;
                        }
                        case 'row': {
                            if (editMode.rowToolbar && editMode.rowToolbar.isVisible) {
                                editMode.rowToolbar.hide();
                            }
                            break;
                        }
                        case 'sidebar': {
                            if (editMode.sidebar && editMode.sidebar.isVisible) {
                                editMode.sidebar.hide();
                            }
                            break;
                        }
                        default: {
                            break;
                        }
                    }
                }
            }
            /**
             * Method for hiding edit toolbars.
             * @internal
             *
             * @param toolbarTypes
             * The array of toolbar names to hide ('cell', 'row', 'sidebar').
             *
             * @param currentCell
             * The cell reference for toolbar.
             *
             */
            showToolbars(toolbarTypes, currentCell) {
                const editMode = this, toolbarsToShow = toolbarTypes || ['cell', 'row', 'sidebar'];
                for (let i = 0, iEnd = toolbarsToShow.length; i < iEnd; ++i) {
                    switch (toolbarsToShow[i]) {
                        case 'cell': {
                            if (currentCell && editMode.cellToolbar) {
                                editMode.cellToolbar.showToolbar(currentCell);
                            }
                            break;
                        }
                        case 'row': {
                            if (currentCell && currentCell.row && editMode.rowToolbar) {
                                editMode.rowToolbar.showToolbar(currentCell.row);
                            }
                            break;
                        }
                        case 'sidebar': {
                            if (editMode.sidebar && !editMode.sidebar.isVisible) {
                                editMode.sidebar.show();
                            }
                            break;
                        }
                        default: {
                            break;
                        }
                    }
                }
            }
            /**
             * Creates the buttons such as `addComponent` button, context menu button
             * and its container.
             * @internal
             */
            createTools() {
                const editMode = this;
                const { board, options, tools } = editMode;
                // Create tools container
                tools.container = document.createElement('div');
                tools.container.classList.add(EditGlobals.classNames.editTools);
                if (board.layoutsWrapper) {
                    // For the generated layout
                    board.layoutsWrapper.parentNode.insertBefore(tools.container, board.layoutsWrapper);
                }
                else {
                    // For the custom layout
                    board.container.insertBefore(tools.container, board.container.firstChild);
                }
                // Create context menu button
                if (options.contextMenu && options.contextMenu.enabled) {
                    tools.contextButtonElement = EditRenderer.renderContextButton(tools.container, editMode);
                    // Init contextMenu if doesn't exist.
                    if (!editMode.tools.contextMenu) {
                        editMode.tools.contextMenu = new EditContextMenu(editMode.board.container, editMode.options.contextMenu || {}, editMode);
                    }
                }
                // Create add component button
                if (options.tools?.addComponentBtn?.enabled &&
                    options.toolbars?.cell?.enabled &&
                    !this.customHTMLMode) {
                    const addIconURL = options.tools.addComponentBtn.icon;
                    this.addComponentBtn = EditRenderer.renderButton(tools.container, {
                        className: EditGlobals.classNames.editToolsBtn,
                        icon: addIconURL,
                        text: this.lang.addComponent,
                        callback: () => {
                            // Sidebar trigger
                            if (editMode.sidebar) {
                                editMode.sidebar.show();
                                editMode.setEditOverlay();
                            }
                        },
                        style: {
                            display: 'none'
                        }
                    });
                }
            }
            /**
             * Event fired when detecting context on drag&drop.
             */
            onDetectContext() {
                const editMode = this;
                if (!editMode.isActive() ||
                    !editMode.isContextDetectionActive ||
                    (!editMode.mouseCellContext && !editMode.mouseRowContext) ||
                    (editMode.dragDrop || {}).isActive) {
                    return;
                }
                let cellContext;
                let rowContext;
                if (editMode.mouseCellContext) {
                    cellContext = editMode.mouseCellContext;
                }
                else if (editMode.mouseRowContext) {
                    rowContext = editMode.mouseRowContext;
                    cellContext = rowContext.layout.parentCell;
                }
                this.potentialCellContext = cellContext;
                if (cellContext) {
                    const cellContextOffsets = GUIElement
                        .getOffsets(cellContext, editMode.board.container);
                    const { width, height } = GUIElement
                        .getDimFromOffsets(cellContextOffsets);
                    editMode.showContextPointer(cellContextOffsets.left, cellContextOffsets.top, width, height);
                }
            }
            /**
             * Stops the context detection.
             */
            stopContextDetection() {
                this.isContextDetectionActive = false;
                if (this.dragDrop) {
                    this.dragDrop.mouseCellContext = void 0;
                }
                this.mouseCellContext = void 0;
                this.hideContextPointer();
            }
            /**
             * Confirms the selected context.
             */
            onContextConfirm() {
                if (this.isContextDetectionActive &&
                    this.potentialCellContext &&
                    this.editCellContext !== this.potentialCellContext) {
                    this.setEditCellContext(this.potentialCellContext, this.editCellContext);
                }
            }
            /**
             * Sets the edit cell context.
             * @internal
             */
            setEditCellContext(editCellContext, oldEditCellContext) {
                const editMode = this;
                const oldContext = oldEditCellContext;
                if (CellHTML.isCellHTML(editCellContext) ||
                    CellHTML.isCellHTML(oldContext)) {
                    editMode.editCellContext = editCellContext;
                    editMode.cellToolbar?.showToolbar(editCellContext);
                }
                else {
                    const oldContextRow = oldContext?.row;
                    editMode.editCellContext = editCellContext;
                    editMode.showToolbars(['row', 'cell'], editCellContext);
                    if (!oldContextRow || oldContextRow !== editCellContext.row) {
                        if (oldContextRow) {
                            // Remove highlight from the previous row.
                            oldContextRow.setHighlight(true);
                        }
                        // Add highlight to the context row.
                        if (editCellContext.row) {
                            editCellContext.row.setHighlight();
                        }
                    }
                    if (editMode.resizer) {
                        editMode.resizer.setSnapPositions(editCellContext);
                    }
                }
            }
            /**
             * Method for showing and positioning context pointer.
             * @internal
             */
            showContextPointer(left, top, width, height) {
                if (!this.contextPointer) {
                    return;
                }
                this.contextPointer.isVisible = true;
                css(this.contextPointer.element, {
                    display: 'block',
                    left: left + 'px',
                    top: top + 'px',
                    height: height + 'px',
                    width: width + 'px'
                });
            }
            /**
             * Method for hiding context pointer.
             * @internal
             */
            hideContextPointer() {
                if (this.contextPointer?.isVisible) {
                    this.contextPointer.isVisible = false;
                    this.contextPointer.element.style.display = 'none';
                }
            }
            /**
             * Adds/Removes the edit mode overlay.
             * @internal
             *
             * @param remove
             * Whether the edit overlay should be removed.
             */
            setEditOverlay(remove) {
                const editMode = this, cnt = editMode.editOverlay, isSet = cnt?.classList.contains(EditGlobals.classNames.editOverlayActive);
                if (!remove && !isSet) {
                    cnt?.classList.add(EditGlobals.classNames.editOverlayActive);
                    editMode.isEditOverlayActive = true;
                }
                else if (remove && isSet) {
                    cnt?.classList.remove(EditGlobals.classNames.editOverlayActive);
                    editMode.isEditOverlayActive = false;
                }
            }
        }
        /* *
         *
         *  Default Export
         *
         * */

        return EditMode;
    });
    _registerModule(_modules, 'Dashboards/EditMode/Fullscreen.js', [_modules['Core/Utilities.js'], _modules['Dashboards/Globals.js']], function (U, Globals) {
        /* *
         *
         *  (c) 2009-2025 Highsoft AS
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         *  Authors:
         *  - Sebastian Bochan
         *  - Wojciech Chmiel
         *  - Gøran Slettemark
         *  - Sophie Bremer
         *
         * */
        const { addEvent } = U;
        class Fullscreen {
            /* *
            *
            *  Constructor
            *
            * */
            constructor(DashboardClass) {
                this.isOpen = false;
                this.board = DashboardClass;
                // Add class to allow scroll element
                this.board.boardWrapper.classList.add(Globals.classNamePrefix + '-fullscreen');
            }
            /* *
            *
            *  Functions
            *
            * */
            /**
             * Toggles displaying the board in fullscreen mode.
             */
            toggle() {
                const fullscreen = this, isOpen = this.isOpen;
                fullscreen[isOpen ? 'close' : 'open']();
            }
            /**
             * Display board in fullscreen.
             */
            open() {
                if (this.isOpen) {
                    return;
                }
                const fullscreen = this, board = fullscreen.board;
                // Handle exitFullscreen() method when user clicks 'Escape' button.
                const unbindChange = addEvent(board.boardWrapper.ownerDocument, // Dashboard's document
                'fullscreenchange', function () {
                    if (fullscreen.isOpen) {
                        fullscreen.isOpen = false;
                        fullscreen.close();
                    }
                    else {
                        fullscreen.isOpen = true;
                        fullscreen.setButtonText();
                    }
                });
                fullscreen.unbindFullscreenEvent = () => {
                    unbindChange();
                };
                const promise = board.boardWrapper.requestFullscreen();
                promise['catch'](() => {
                    throw new Error('Full screen is not supported.');
                });
            }
            /**
             * Stops displaying the dashboard in fullscreen mode.
             */
            close() {
                const fullscreen = this, board = fullscreen.board;
                // Don't fire exitFullscreen() when user exited using 'Escape' button.
                if (fullscreen.isOpen &&
                    board.boardWrapper.ownerDocument instanceof Document) {
                    void board.boardWrapper.ownerDocument.exitFullscreen();
                }
                // Unbind event as it's necessary only before exiting from fullscreen.
                if (fullscreen.unbindFullscreenEvent) {
                    fullscreen.unbindFullscreenEvent =
                        fullscreen.unbindFullscreenEvent();
                }
                fullscreen.isOpen = false;
                this.setButtonText();
            }
            /**
             * Set the correct text depending of the fullscreen is on or of.
             */
            setButtonText() {
                const editMode = this.board.editMode, contextMenu = editMode && editMode.tools.contextMenu, button = contextMenu && contextMenu.items.viewFullscreen;
                if (button && button.innerElement) {
                    const lang = editMode.lang;
                    button.innerElement.innerHTML =
                        (this.isOpen ? lang.exitFullscreen : lang.viewFullscreen) || '';
                }
            }
        }

        return Fullscreen;
    });
    _registerModule(_modules, 'masters/modules/layout.src.js', [_modules['Dashboards/Globals.js'], _modules['Dashboards/EditMode/EditMode.js'], _modules['Dashboards/EditMode/Fullscreen.js']], function (Globals, EditMode, Fullscreen) {

        /* *
         *
         *  Imports
         *
         * */
        // Fill registries
        /* *
         *
         *  Namespace
         *
         * */
        const G = Globals;
        G.EditMode = EditMode;
        G.Fullscreen = Fullscreen;
        /* *
         *
         *  Default Export
         *
         * */

        return G;
    });
}));