/* GETCOURSE — USERS PAGE / v1.4 — segment logic separated */
(function () {
    'use strict';

    const MOBILE_BREAKPOINT = 767;
    const READY_CLASS = 'psych-users-ready';
    const FALLBACK_READY_DELAY = 2500;
    const SEGMENT_WIDGET = '.segment-construct-widget';

    let moveIndex = 0;
    let customSelectClosingBound = false;
    let actionsDropdownBound = false;

    function isMobile() {
        return window.innerWidth <= MOBILE_BREAKPOINT;
    }

    function normalizeText(value) {
        return String(value || '').replace(/\s+/g, ' ').trim();
    }

    function setReadyState(value) {
        document.documentElement.classList.toggle(READY_CLASS, Boolean(value));
    }

    function getPage() {
        const users = document.querySelector('.standard-page-content #users');
        if (!users) return null;

        const page = users.closest('.standard-page-content');
        const table = users.querySelector('table.kv-grid-table, table.table');
        const segmentWidget = page?.querySelector(SEGMENT_WIDGET);

        if (!page || !table || !segmentWidget) return null;
        return { users, page, table, segmentWidget };
    }

    /* =========================
       Custom selects
       ========================= */

    function isSelect2Native(select) {
        if (!select) return true;

        if (
            select.classList.contains('select2-offscreen') ||
            select.classList.contains('kv-hide') ||
            select.classList.contains('select2-focusser') ||
            select.classList.contains('select2-input')
        ) {
            return true;
        }

        if (select.id && document.getElementById(`s2id_${select.id}`)) {
            return true;
        }

        return Boolean(select.closest('.select2-container'));
    }

    function closeCustomSelect(wrapper) {
        if (!wrapper) return;

        wrapper.classList.remove('is-open');

        const control = wrapper.querySelector('.psych-users-select__control');
        const menuId = wrapper.dataset.psychMenuId;
        const menu = menuId ? document.getElementById(menuId) : null;

        control?.setAttribute('aria-expanded', 'false');
        menu?.classList.remove('is-open');
    }

    function closeAllCustomSelects(except = null) {
        document.querySelectorAll('.psych-users-select.is-open').forEach(wrapper => {
            if (wrapper !== except) closeCustomSelect(wrapper);
        });
    }

    function positionCustomSelectMenu(wrapper) {
        const control = wrapper?.querySelector('.psych-users-select__control');
        const menuId = wrapper?.dataset.psychMenuId;
        const menu = menuId ? document.getElementById(menuId) : null;

        if (!control || !menu || !wrapper.classList.contains('is-open')) return;

        const rect = control.getBoundingClientRect();
        const gap = 6;
        const viewportGap = 12;
        const availableBelow = window.innerHeight - rect.bottom - viewportGap;
        const availableAbove = rect.top - viewportGap;
        const preferredHeight = Math.min(menu.scrollHeight || 280, isMobile() ? 320 : 280);
        const openAbove =
            availableBelow < Math.min(preferredHeight, 180) &&
            availableAbove > availableBelow;

        const width = Math.max(rect.width, 150);
        let left = rect.left;

        if (left + width > window.innerWidth - viewportGap) {
            left = Math.max(viewportGap, window.innerWidth - viewportGap - width);
        }

        menu.style.width = `${width}px`;
        menu.style.left = `${Math.round(left)}px`;
        menu.style.right = 'auto';

        if (openAbove) {
            menu.style.top = 'auto';
            menu.style.bottom = `${Math.round(window.innerHeight - rect.top + gap)}px`;
            menu.style.maxHeight = `${Math.max(120, availableAbove - gap)}px`;
        } else {
            menu.style.top = `${Math.round(rect.bottom + gap)}px`;
            menu.style.bottom = 'auto';
            menu.style.maxHeight = `${Math.max(120, availableBelow - gap)}px`;
        }
    }

    function initCustomSelects(root = document) {
        root.querySelectorAll(
            '.standard-page-content #users select:not(.psych-users-select__native), ' +
            '#users-grid-modal select:not(.psych-users-select__native)'
        ).forEach(select => {
            /*
             * Внутри конструктора сегментов оставляем только штатный Select2 GetCourse.
             * Наш psych-users-select там не создаём.
             */
            if (select.closest(SEGMENT_WIDGET)) {
                select.dataset.psychUsersSelect = 'ready';
                return;
            }

            if (
                select.dataset.psychUsersSelect === 'ready' ||
                isSelect2Native(select)
            ) {
                return;
            }

            select.dataset.psychUsersSelect = 'ready';
            select.classList.add('psych-users-select__native');

            const wrapper = document.createElement('div');
            wrapper.className = 'psych-users-select';

            const control = document.createElement('button');
            control.type = 'button';
            control.className = 'psych-users-select__control';
            control.setAttribute('aria-haspopup', 'listbox');
            control.setAttribute('aria-expanded', 'false');

            const value = document.createElement('span');
            value.className = 'psych-users-select__value';

            const arrow = document.createElement('span');
            arrow.className = 'psych-users-select__arrow';

            const menu = document.createElement('div');
            const menuId = `psych-users-select-menu-${Math.random().toString(36).slice(2, 10)}`;
            menu.id = menuId;
            menu.className = 'psych-users-select-menu';
            menu.setAttribute('role', 'listbox');

            wrapper.dataset.psychMenuId = menuId;

            control.append(value, arrow);
            select.parentNode.insertBefore(wrapper, select);
            wrapper.append(select, control);
            document.body.appendChild(menu);

            function render() {
                const selected =
                    select.options[select.selectedIndex] ||
                    select.options[0] ||
                    null;

                value.textContent = selected ? selected.textContent : '';
                wrapper.classList.toggle('is-disabled', select.disabled);
                control.disabled = select.disabled;
                menu.innerHTML = '';

                Array.from(select.options).forEach(option => {
                    const item = document.createElement('button');
                    item.type = 'button';
                    item.className = 'psych-users-select__option';
                    item.textContent = option.textContent;
                    item.dataset.value = option.value;
                    item.disabled = option.disabled;
                    item.setAttribute('role', 'option');
                    item.setAttribute('aria-selected', option.selected ? 'true' : 'false');

                    if (option.selected) item.classList.add('is-selected');

                    item.addEventListener('click', () => {
                        if (option.disabled) return;

                        const changed = select.value !== option.value;
                        select.value = option.value;

                        if (changed) {
                            select.dispatchEvent(new Event('input', { bubbles: true }));
                            select.dispatchEvent(new Event('change', { bubbles: true }));
                        }

                        render();
                        closeCustomSelect(wrapper);
                        control.focus();
                    });

                    item.addEventListener('keydown', event => {
                        const items = [
                            ...menu.querySelectorAll(
                                '.psych-users-select__option:not(:disabled)'
                            )
                        ];
                        const index = items.indexOf(document.activeElement);

                        if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
                            event.preventDefault();
                            const step = event.key === 'ArrowDown' ? 1 : -1;
                            const next =
                                index < 0
                                    ? 0
                                    : (index + step + items.length) % items.length;

                            items[next]?.focus();
                        }

                        if (event.key === 'Escape') {
                            event.preventDefault();
                            closeCustomSelect(wrapper);
                            control.focus();
                        }
                    });

                    menu.appendChild(item);
                });

                if (wrapper.classList.contains('is-open')) {
                    requestAnimationFrame(() => positionCustomSelectMenu(wrapper));
                }
            }

            function open() {
                if (select.disabled) return;

                closeAllCustomSelects(wrapper);
                render();

                wrapper.classList.add('is-open');
                menu.classList.add('is-open');
                control.setAttribute('aria-expanded', 'true');

                requestAnimationFrame(() => {
                    positionCustomSelectMenu(wrapper);
                    menu.querySelector('.is-selected')?.scrollIntoView({
                        block: 'nearest'
                    });
                });
            }

            control.addEventListener('click', event => {
                event.preventDefault();

                if (wrapper.classList.contains('is-open')) {
                    closeCustomSelect(wrapper);
                } else {
                    open();
                }
            });

            control.addEventListener('keydown', event => {
                if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
                    event.preventDefault();
                    open();

                    requestAnimationFrame(() => {
                        const selectedItem = menu.querySelector('.is-selected');
                        const firstItem = menu.querySelector(
                            '.psych-users-select__option:not(:disabled)'
                        );
                        (selectedItem || firstItem)?.focus();
                    });
                }

                if (event.key === 'Escape') {
                    closeCustomSelect(wrapper);
                }
            });

            select.addEventListener('change', render);

            const observer = new MutationObserver(render);
            observer.observe(select, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ['disabled', 'selected']
            });

            render();
        });
    }

    function bindCustomSelectClosing() {
        if (customSelectClosingBound) return;
        customSelectClosingBound = true;

        document.addEventListener('click', event => {
            document.querySelectorAll('.psych-users-select.is-open').forEach(wrapper => {
                const menuId = wrapper.dataset.psychMenuId;
                const menu = menuId ? document.getElementById(menuId) : null;

                if (
                    !wrapper.contains(event.target) &&
                    !menu?.contains(event.target)
                ) {
                    closeCustomSelect(wrapper);
                }
            });
        });

        document.addEventListener('keydown', event => {
            if (event.key === 'Escape') closeAllCustomSelects();
        });

        window.addEventListener('resize', () => {
            document.querySelectorAll('.psych-users-select.is-open')
                .forEach(positionCustomSelectMenu);
        });

        window.addEventListener(
            'scroll',
            () => {
                document.querySelectorAll('.psych-users-select.is-open')
                    .forEach(positionCustomSelectMenu);
            },
            true
        );
    }

    /* =========================
       Top action dropdowns
       ========================= */

    function getOpenActionMenus() {
        return [
            ...document.querySelectorAll(
                '.standard-page-content:has(#users) ' +
                '.standard-page-actions .btn-group.open > .dropdown-menu'
            )
        ];
    }

    function resetActionMenu(menu) {
        if (!menu) return;

        menu.classList.remove('psych-users-actions-menu-fixed');

        [
            'top',
            'left',
            'right',
            'bottom',
            'width',
            'max-height',
            'max-width'
        ].forEach(property => menu.style.removeProperty(property));
    }

    function positionActionMenu(menu) {
        if (!menu) return;

        const group = menu.closest('.btn-group');
        const trigger =
            group?.querySelector('.dropdown-toggle') ||
            group?.querySelector('.btn');

        if (!group || !trigger || !group.classList.contains('open')) {
            resetActionMenu(menu);
            return;
        }

        const viewportGap = 12;
        const gap = 6;
        const triggerRect = trigger.getBoundingClientRect();

        menu.classList.add('psych-users-actions-menu-fixed');

        menu.style.setProperty('top', '0px', 'important');
        menu.style.setProperty('left', '0px', 'important');
        menu.style.setProperty('right', 'auto', 'important');
        menu.style.setProperty('bottom', 'auto', 'important');
        menu.style.setProperty('width', 'max-content', 'important');
        menu.style.setProperty(
            'max-width',
            `${Math.max(220, window.innerWidth - viewportGap * 2)}px`,
            'important'
        );

        const rect = menu.getBoundingClientRect();
        const menuWidth = Math.min(
            Math.max(rect.width, 240),
            window.innerWidth - viewportGap * 2
        );
        const naturalHeight = Math.min(
            rect.height || menu.scrollHeight || 220,
            window.innerHeight - viewportGap * 2
        );

        let left = triggerRect.right - menuWidth;

        if (left < viewportGap) left = viewportGap;

        if (left + menuWidth > window.innerWidth - viewportGap) {
            left = window.innerWidth - viewportGap - menuWidth;
        }

        const availableBelow =
            window.innerHeight -
            triggerRect.bottom -
            viewportGap;

        const availableAbove =
            triggerRect.top -
            viewportGap;

        const openAbove =
            availableBelow < Math.min(naturalHeight, 180) &&
            availableAbove > availableBelow;

        let top;
        let maxHeight;

        if (openAbove) {
            maxHeight = Math.max(120, availableAbove - gap);
            top = Math.max(
                viewportGap,
                triggerRect.top -
                Math.min(naturalHeight, maxHeight) -
                gap
            );
        } else {
            maxHeight = Math.max(120, availableBelow - gap);
            top = triggerRect.bottom + gap;

            if (
                top + Math.min(naturalHeight, maxHeight) >
                window.innerHeight - viewportGap
            ) {
                top = Math.max(
                    viewportGap,
                    window.innerHeight -
                    viewportGap -
                    Math.min(naturalHeight, maxHeight)
                );
            }
        }

        menu.style.setProperty(
            'width',
            `${Math.round(menuWidth)}px`,
            'important'
        );
        menu.style.setProperty(
            'left',
            `${Math.round(left)}px`,
            'important'
        );
        menu.style.setProperty(
            'top',
            `${Math.round(top)}px`,
            'important'
        );
        menu.style.setProperty('right', 'auto', 'important');
        menu.style.setProperty('bottom', 'auto', 'important');
        menu.style.setProperty(
            'max-height',
            `${Math.round(maxHeight)}px`,
            'important'
        );
    }

    function refreshActionMenus() {
        getOpenActionMenus().forEach(positionActionMenu);

        document.querySelectorAll(
            '.standard-page-content:has(#users) ' +
            '.standard-page-actions ' +
            '.dropdown-menu.psych-users-actions-menu-fixed'
        ).forEach(menu => {
            if (!menu.closest('.btn-group')?.classList.contains('open')) {
                resetActionMenu(menu);
            }
        });
    }

    function bindActionDropdowns() {
        if (actionsDropdownBound) return;
        actionsDropdownBound = true;

        document.addEventListener(
            'click',
            event => {
                if (
                    event.target.closest(
                        '.standard-page-content:has(#users) ' +
                        '.standard-page-actions .dropdown-toggle, ' +
                        '.standard-page-content:has(#users) ' +
                        '.standard-page-actions .btn-group > .btn'
                    )
                ) {
                    requestAnimationFrame(refreshActionMenus);
                    window.setTimeout(refreshActionMenus, 20);
                }
            },
            true
        );

        const observer = new MutationObserver(mutations => {
            const changed = mutations.some(mutation =>
                mutation.type === 'attributes' &&
                mutation.attributeName === 'class' &&
                mutation.target.matches?.(
                    '.standard-page-content:has(#users) ' +
                    '.standard-page-actions .btn-group'
                )
            );

            if (changed) {
                requestAnimationFrame(refreshActionMenus);
            }
        });

        observer.observe(document.body, {
            subtree: true,
            attributes: true,
            attributeFilter: ['class']
        });

        window.addEventListener('resize', refreshActionMenus);
        window.addEventListener('scroll', refreshActionMenus, true);
    }

    /* =========================
       Headers / cards / filters
       ========================= */

    function getHeaders(table) {
        const row = table.querySelector('thead tr:not(.filters)');
        if (!row) return [];

        return [
            ...row.querySelectorAll('th[data-col-seq], td[data-col-seq]')
        ].map((cell, index) => ({
            seq: cell.getAttribute('data-col-seq') || String(index),
            label: normalizeText(cell.textContent) || `Поле ${index + 1}`,
            index
        }));
    }

    function getHeaderMap(headers) {
        const map = new Map();
        headers.forEach(header => map.set(String(header.seq), header));
        return map;
    }

    function findHeaderByPattern(headers, pattern) {
        return headers.find(
            header => pattern.test(header.label.toLowerCase())
        ) || null;
    }

    function markUserRows(table, headers) {
        const headerMap = getHeaderMap(headers);
        const emailHeader = findHeaderByPattern(
            headers,
            /(эл\.?\s*адрес|эл\.?\s*поч|e-?mail|email)/
        );

        table.querySelectorAll('tbody > tr.gc-user-link').forEach(row => {
            row.classList.add('psych-user-card');

            const cells = [
                ...row.querySelectorAll(
                    ':scope > td[data-col-seq], :scope > th[data-col-seq]'
                )
            ];

            cells.forEach((cell, index) => {
                const seq =
                    cell.getAttribute('data-col-seq') ||
                    String(index);

                const header = headerMap.get(seq);

                cell.dataset.mobileLabel = header
                    ? header.label
                    : `Поле ${index + 1}`;

                cell.classList.remove(
                    'psych-user-card-avatar',
                    'psych-user-card-name',
                    'psych-user-card-email',
                    'psych-user-card-empty'
                );

                if (cell.querySelector('.user-profile-image')) {
                    cell.classList.add('psych-user-card-avatar');
                    return;
                }

                if (cell.classList.contains('user-name')) {
                    cell.classList.add('psych-user-card-name');
                    return;
                }

                if (
                    emailHeader &&
                    String(emailHeader.seq) === String(seq)
                ) {
                    cell.classList.add('psych-user-card-email');
                    return;
                }

                const value = normalizeText(cell.textContent);

                if (!value) {
                    cell.classList.add('psych-user-card-empty');

                    if (
                        !cell.querySelector(
                            'input, select, textarea, button'
                        )
                    ) {
                        cell.textContent = '—';
                    }
                }
            });
        });
    }

    function markFilterCells(table, headers) {
        const filterRow =
            table.querySelector('#w7-filters, thead tr.filters');

        if (!filterRow) return null;

        [
            ...filterRow.querySelectorAll(':scope > td, :scope > th')
        ].forEach((cell, index) => {
            const header = headers[index];

            cell.dataset.mobileLabel = header
                ? header.label
                : `Фильтр ${index + 1}`;
        });

        return filterRow;
    }

    function countActiveFilters(filterRow) {
        if (!filterRow) return 0;

        let count = 0;

        filterRow.querySelectorAll('input[name], select[name]').forEach(control => {
            if (
                control.classList.contains('select2-focusser') ||
                control.classList.contains('select2-input')
            ) {
                return;
            }

            const value = normalizeText(control.value);

            if (!value || value === 'null') return;

            if (
                value === '0' &&
                /email_validate/i.test(control.name || '')
            ) {
                return;
            }

            count++;
        });

        return count;
    }

    function updateFilterCounter(button, filterRow) {
        if (!button) return;

        let counter = button.querySelector('.psych-users-filter-count');
        const count = countActiveFilters(filterRow);

        if (!count) {
            counter?.remove();
            return;
        }

        if (!counter) {
            counter = document.createElement('span');
            counter.className = 'psych-users-filter-count';
            button.appendChild(counter);
        }

        counter.textContent = String(count);
    }

    function ensureFilterButton(users, filterRow) {
        let button = document.querySelector('.psych-users-filter-toggle');

        if (!button) {
            button = document.createElement('button');
            button.type = 'button';
            button.className = 'psych-users-filter-toggle';
            button.innerHTML = '<span>Фильтры</span>';
            button.setAttribute('aria-expanded', 'false');

            button.addEventListener('click', event => {
                event.preventDefault();
                event.stopPropagation();

                const open = users.classList.toggle(
                    'psych-users-filters-open'
                );

                button.setAttribute(
                    'aria-expanded',
                    open ? 'true' : 'false'
                );
            });
        }

        updateFilterCounter(button, filterRow);
        return button;
    }

    function bindFilterCounter(filterRow, button) {
        if (
            !filterRow ||
            !button ||
            filterRow.dataset.psychCounterBound === '1'
        ) {
            return;
        }

        filterRow.dataset.psychCounterBound = '1';

        const refresh = () => {
            window.setTimeout(() => {
                updateFilterCounter(button, filterRow);
            }, 0);
        };

        filterRow.addEventListener('input', refresh);
        filterRow.addEventListener('change', refresh);

        if (window.jQuery?.fn) {
            window.jQuery(filterRow).on(
                'select2-selecting select2-removed change',
                refresh
            );
        }
    }

    /* =========================
       Mobile workspace
       ========================= */

    function moveNode(node, destination) {
        if (!node || !destination) return;

        if (!node.dataset.psychMobileMoveId) {
            moveIndex++;

            const id = `psych-mobile-${moveIndex}`;
            const placeholder = document.createElement('span');

            node.dataset.psychMobileMoveId = id;
            placeholder.hidden = true;
            placeholder.dataset.psychMobilePlaceholder = id;

            node.parentNode?.insertBefore(placeholder, node);
        }

        destination.appendChild(node);
    }

    function buildMobileWorkspace(users, segmentWidget, filterButton) {
        if (users.querySelector('.psych-users-workspace')) return;

        const panelBefore = users.querySelector('.kv-panel-before');
        if (!panelBefore) return;

        const toolbar = panelBefore.querySelector('.kv-grid-toolbar');
        const summary = panelBefore.querySelector('.summary');

        const workspace = document.createElement('div');
        workspace.className = 'psych-users-workspace';

        const segmentRow = document.createElement('div');
        segmentRow.className = 'psych-users-workspace__segment';

        const toolsRow = document.createElement('div');
        toolsRow.className = 'psych-users-workspace__tools';

        const summaryRow = document.createElement('div');
        summaryRow.className = 'psych-users-workspace__summary';

        if (filterButton) toolsRow.appendChild(filterButton);
        if (summary) moveNode(summary, summaryRow);
        if (toolbar) moveNode(toolbar, toolsRow);

        moveNode(segmentWidget, segmentRow);
        segmentWidget.classList.add('psych-users-segment-mobile');

        const form = segmentWidget.querySelector(':scope > form');
        const root = form?.querySelector(':scope > .clearfix');
        const topControls = root?.querySelector(
            ':scope > .clearfix:not(.segment-rule):not(.action-buttons)'
        );

        if (topControls && toolsRow.children.length) {
            topControls.insertAdjacentElement('afterend', toolsRow);
        }

        segmentRow.appendChild(segmentWidget);
        workspace.appendChild(segmentRow);
        users.insertBefore(workspace, users.firstChild);

        if (summaryRow.children.length) {
            workspace.insertAdjacentElement('afterend', summaryRow);
        }

        panelBefore.classList.add('psych-users-original-hidden');
    }

    function restoreMovedNodes() {
        document.querySelectorAll('[data-psych-mobile-move-id]')
            .forEach(node => {
                const id = node.dataset.psychMobileMoveId;

                const placeholder = document.querySelector(
                    `[data-psych-mobile-placeholder="${id}"]`
                );

                if (placeholder?.parentNode) {
                    placeholder.parentNode.insertBefore(node, placeholder);
                    placeholder.remove();
                }

                delete node.dataset.psychMobileMoveId;
            });

        document.querySelectorAll(
            '.psych-users-workspace, ' +
            '.psych-users-workspace__summary, ' +
            '.psych-users-workspace__tools'
        ).forEach(element => element.remove());

        document.querySelectorAll('.psych-users-original-hidden')
            .forEach(element => {
                element.classList.remove('psych-users-original-hidden');
            });

        document.querySelectorAll('.psych-users-segment-mobile')
            .forEach(element => {
                element.classList.remove('psych-users-segment-mobile');
            });
    }

    /* =========================
       Refresh / init
       ========================= */

    function enhancePage() {
        const data = getPage();
        if (!data) return false;

        const { users, table, segmentWidget } = data;
        const headers = getHeaders(table);

        if (!headers.length) return false;

        users.classList.add('psych-users-mobile-ready');

        markUserRows(table, headers);

        const filterRow = markFilterCells(table, headers);
        const filterButton = ensureFilterButton(users, filterRow);

        bindFilterCounter(filterRow, filterButton);
        buildMobileWorkspace(users, segmentWidget, filterButton);

        return true;
    }

    function refresh() {
        initCustomSelects(document);

        if (isMobile()) {
            if (enhancePage()) {
                setReadyState(true);
            }
        } else {
            restoreMovedNodes();
            setReadyState(false);
        }
    }

    function init() {
        if (isMobile()) {
            setReadyState(false);
        }

        bindCustomSelectClosing();
        bindActionDropdowns();
        refresh();

        window.setTimeout(() => {
            if (isMobile()) {
                setReadyState(true);
            }
        }, FALLBACK_READY_DELAY);

        [250, 700, 1500, 3000].forEach(delay => {
            window.setTimeout(refresh, delay);
        });

        let mutationTimer = null;

        const observer = new MutationObserver(mutations => {
            if (
                !mutations.some(
                    mutation =>
                        mutation.addedNodes.length ||
                        mutation.type === 'attributes'
                )
            ) {
                return;
            }

            window.clearTimeout(mutationTimer);

            mutationTimer = window.setTimeout(() => {
                        initCustomSelects(document);
            }, 30);
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class', 'style']
        });

        let resizeTimer = null;

        window.addEventListener('resize', () => {
            window.clearTimeout(resizeTimer);
            resizeTimer = window.setTimeout(refresh, 160);
        });

        window.addEventListener('pageshow', refresh);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init, { once: true });
    } else {
        init();
    }
})();
