import { AXPAuthGuard, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex/platform/auth';
import { AXPSettingsService, AXPMenuProviderService, AXPTokenDefinitionService, AXP_TOKEN_DEFINITION_PROVIDER, createAllQueryView, AXPEntityCommandScope, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER } from '@acorex/platform/common';
import { AXPPlatformScope, AXPExpressionEvaluatorService, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER } from '@acorex/platform/core';
import { AXMEntityCrudServiceImpl, AXPEntityService, entityMasterCrudActions, entityMasterRecordActions, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
import { AXPRootLayoutComponent } from '@acorex/platform/themes/default';
import * as i0 from '@angular/core';
import { inject, Injector, Injectable, viewChild, signal, computed, ViewEncapsulation, Component, NgModule } from '@angular/core';
import { ROUTES } from '@angular/router';
import { AXPMenuCustomizerService, AXPMenuCustomizerComponent, AXPThemeLayoutBlockComponent, AXP_MENU_CUSTOMIZER_SERVICE } from '@acorex/platform/layout/components';
import * as i1 from '@acorex/platform/workflow';
import { AXPWorkflowAction, AXPWorkflowModule } from '@acorex/platform/workflow';
import { cloneDeep } from 'lodash-es';
import { AXPopupService } from '@acorex/components/popup';
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
import { AXPPopupLayoutBaseComponent, AXPPopupLayoutComponent, AXPPopupLayoutBase } from '@acorex/platform/layout/views';
import { CommonModule } from '@angular/common';
import { provideCommandSetups } from '@acorex/platform/runtime';
import { AXDialogService } from '@acorex/components/dialog';
import { SwUpdate } from '@angular/service-worker';
import { AXPDataManagementMenuKeys } from '@acorex/modules/data-management';
import { AXPWidgetsCatalog } from '@acorex/platform/layout/widget-core';
import { AXPWidgetsList } from '@acorex/modules/common';

const config = {
    i18n: 'platform-management',
};
const RootConfig = {
    config,
    module: {
        route: 'platform-management',
        name: 'PlatformManagement',
        title: `@${config.i18n}:module.title`,
        icon: 'fa-light fa-cogs',
    },
    entities: {
        localizationManagement: {
            name: 'Localization Management',
            title: `@${config.i18n}:localization-management.entities.localization-management.title`,
            icon: 'fa-light fa-globe',
        },
        token: {
            name: 'Tokens',
            title: `@${config.i18n}:tokens.entities.token.title`,
            icon: 'fa-light fa-object-exclude',
        },
    },
};

class AXMEntityLoader {
    constructor() {
        this.injector = inject(Injector);
    }
    preload() {
        const module = RootConfig.module.name;
        return Array.from(Object.values(RootConfig.entities)).map((entity) => ({
            module: module,
            entity: entity.name,
        }));
    }
    async get(moduleName, entityName) {
        if (moduleName == RootConfig.module.name) {
            return new Promise(async (resolve) => {
                switch (entityName) {
                    case RootConfig.entities.token.name: {
                        const entity = (await Promise.resolve().then(function () { return index; })).tokenEntityFactory;
                        resolve(entity(this.injector));
                        break;
                    }
                    default:
                        resolve(null);
                }
            });
        }
        return null;
    }
    async list() {
        const m = RootConfig.module.name;
        return Promise.resolve(Object.values(RootConfig.entities).map((e) => ({ name: e.name, module: m })));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMEntityLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMEntityLoader }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMEntityLoader, decorators: [{
            type: Injectable
        }] });

const AXPPlatformManagementFeatureKeys = {
    MenuCustomization: 'PlatformManagement:Feature:menu-customization',
    AutoCheckUpdates: 'PlatformManagement:Feature:auto-check-updates',
    MaxTokens: 'PlatformManagement:Feature:max-tokens',
};

//#region ----   Imports   ----
//#endregion
//#region ----   Feature Definition Provider   ----
/**
 * Platform Management Feature Definition Provider.
 * Provides feature definitions for the Platform Management module.
 */
class AXPPlatformManagementFeatureDefinitionProvider {
    async provide(context) {
        context.addFeature(AXPPlatformManagementFeatureKeys.MenuCustomization, {
            title: '@platform-management:features.menu-customization.title',
            description: '@platform-management:features.menu-customization.description',
            defaultValue: true,
            type: 'boolean',
        });
        context.addFeature(AXPPlatformManagementFeatureKeys.AutoCheckUpdates, {
            title: '@platform-management:features.auto-check-updates.title',
            description: '@platform-management:features.auto-check-updates.description',
            defaultValue: true,
            type: 'boolean',
        });
        context.addFeature(AXPPlatformManagementFeatureKeys.MaxTokens, {
            title: '@platform-management:features.max-tokens.title',
            description: '@platform-management:features.max-tokens.description',
            defaultValue: 100,
            type: 'number',
            interface: {
                type: 'number-editor',
                options: {
                    min: 1,
                    max: 1000,
                    step: 1,
                },
            },
        });
    }
}
//#endregion

//#region ----   Menu Customization Constants   ----
/**
 * Setting key for menu customizations
 */
const AXP_MENU_CUSTOMIZATION_KEY = 'axp.platform-management.menu-customization';
/**
 * Current version of menu customization schema
 */
const AXP_MENU_CUSTOMIZATION_VERSION = '1.0.0';
/**
 * Default menu customization
 */
const AXP_MENU_CUSTOMIZATION_DEFAULT = {
    version: AXP_MENU_CUSTOMIZATION_VERSION,
    overrides: {},
    customItems: [],
};
/**
 * Menu management feature configuration
 */
const MenuManagementConfig = {
    route: 'menus',
    title: `@${RootConfig.config.i18n}:menu-management.components.menu-list.title`,
    icon: 'fa-light fa-bars',
};
//#endregion

//#region ----   Custom Menu Middleware   ----
/**
 * Middleware that applies menu customizations using the enhanced context API
 * Applies user/tenant customizations from settings with priority support
 */
class AXPCustomMenuMiddleware {
    constructor() {
        //#region ----   Middleware Properties   ----
        this.name = 'menu-customization';
        this.priority = 100; // High priority to apply customizations early
        //#endregion
        //#region ----   Dependencies   ----
        this.settingsService = inject(AXPSettingsService);
        //#endregion
    }
    //#endregion
    //#region ----   Middleware Implementation   ----
    async process(context) {
        try {
            // Load menu customization from settings
            const customization = await this.loadCustomization();
            // Apply overrides to existing menu items using context API
            this.applyOverrides(context, customization);
            // Add custom menu items
            this.addCustomItems(context, customization);
            // Re-sort after applying priority overrides
            context.sort();
        }
        catch (error) {
            console.error('Error applying menu customizations:', error);
        }
    }
    //#endregion
    //#region ----   Private Methods   ----
    /**
     * Load menu customization from settings
     * Merges Tenant and User scope customizations (User overrides Tenant)
     */
    async loadCustomization() {
        try {
            // Load both scopes
            const tenantSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
            const userSettings = this.settingsService.scope(AXPPlatformScope.User);
            const tenantCustomization = await tenantSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
            const userCustomization = await userSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
            // Merge customizations: Tenant as base, User overrides
            const merged = {
                version: userCustomization?.version || tenantCustomization?.version || AXP_MENU_CUSTOMIZATION_DEFAULT.version,
                overrides: {
                    ...(tenantCustomization?.overrides || {}),
                    ...(userCustomization?.overrides || {}), // User overrides win
                },
                customItems: [...(tenantCustomization?.customItems || []), ...(userCustomization?.customItems || [])],
            };
            // Return merged result or default if both are empty
            const hasCustomizations = Object.keys(merged.overrides).length > 0 || merged.customItems.length > 0;
            return hasCustomizations ? merged : AXP_MENU_CUSTOMIZATION_DEFAULT;
        }
        catch (error) {
            console.error('Failed to load menu customization:', error);
            return AXP_MENU_CUSTOMIZATION_DEFAULT;
        }
    }
    /**
     * Apply overrides to existing menu items using enhanced context API
     */
    applyOverrides(context, customization) {
        Object.entries(customization.overrides).forEach(([menuName, override]) => {
            const finder = context.findByName(menuName);
            if (!finder.exists()) {
                return;
            }
            // Hide menu item
            if (override.hidden) {
                finder.remove();
                return;
            }
            // Apply priority override
            if (override.priority !== undefined) {
                finder.setPriority(override.priority);
            }
            // Apply property overrides
            if (override.properties) {
                finder.update(override.properties);
            }
            // Move to different parent
            if (override.parentName !== undefined) {
                finder.moveTo(override.parentName);
            }
        });
    }
    /**
     * Add custom menu items using context API
     */
    addCustomItems(context, customization) {
        if (customization.customItems && customization.customItems.length > 0) {
            context.add(...customization.customItems);
        }
    }
}
//#endregion

/**
 * Builds a customization key from a scope key
 * @param scopeKey The scope key (e.g., 'edition:123', 'tenant:456')
 * @returns The full customization storage key
 */
function buildCustomizationKey(scopeKey) {
    return `${AXP_MENU_CUSTOMIZATION_KEY}.${scopeKey}`;
}
//#region ----   Menu Management Service   ----
/**
 * Constants for priority calculation
 */
const PRIORITY_BASE_ROOT = 0;
const PRIORITY_BASE_NESTED = 1000;
const PRIORITY_STEP = 10;
class AXPMenuManagementService extends AXPMenuCustomizerService {
    constructor() {
        super(...arguments);
        //#region ----   Dependencies   ----
        this.settingsService = inject(AXPSettingsService);
        this.menuProviderService = inject(AXPMenuProviderService);
    }
    //#endregion
    //#region ----   AXPMenuCustomizerService Interface Implementation   ----
    /**
     * Interface implementation: Get menu tree for the given scope key
     */
    async getMenuTree(scopeKey) {
        return this.getMenuTreeByKey(scopeKey);
    }
    /**
     * Interface implementation: Sync tree changes
     */
    async syncTreeChanges(scopeKey, treeNodes) {
        return this.syncTreeChangesByKey(scopeKey, treeNodes);
    }
    /**
     * Interface implementation: Show menu item
     */
    async showMenuItem(scopeKey, menuName) {
        return this.showMenuItemByKey(scopeKey, menuName);
    }
    /**
     * Interface implementation: Hide menu item
     */
    async hideMenuItem(scopeKey, menuName) {
        return this.hideMenuItemByKey(scopeKey, menuName);
    }
    /**
     * Interface implementation: Add custom menu item
     */
    async addCustomMenuItem(scopeKey, menuItem, parentName) {
        return this.addCustomMenuItemByKey(scopeKey, menuItem, parentName);
    }
    /**
     * Interface implementation: Update custom menu item
     */
    async updateCustomMenuItem(scopeKey, menuName, menuItem) {
        return this.updateCustomMenuItemByKey(scopeKey, menuName, menuItem);
    }
    /**
     * Interface implementation: Update menu properties
     */
    async updateMenuProperties(scopeKey, menuName, properties) {
        return this.updateMenuPropertiesByKey(scopeKey, menuName, properties);
    }
    /**
     * Interface implementation: Delete custom menu item
     */
    async deleteCustomMenuItem(scopeKey, menuName) {
        return this.deleteCustomMenuItemByKey(scopeKey, menuName);
    }
    /**
     * Interface implementation: Reset customizations
     */
    async resetCustomizations(scopeKey) {
        return this.resetCustomizationsByKey(scopeKey);
    }
    //#endregion
    //#region ----   Scope-Based Public Methods   ----
    /**
     * Get menu tree as AXTreeViewNode[] for ax-tree-view component (scope-based)
     */
    async getMenuTreeByScope(scope) {
        // Get RAW menu items WITHOUT middleware (for management purposes)
        const baseItems = await this.menuProviderService.rawItems();
        // Load customizations for the given scope
        const customization = await this.loadCustomization(scope);
        // Merge custom items with base items
        const allItems = [...baseItems, ...customization.customItems];
        // Apply parent overrides to restructure items BEFORE building tree
        const restructuredItems = this.applyParentOverrides(allItems, customization);
        // Convert to tree nodes with metadata
        return this.convertToTreeNodes(restructuredItems, customization);
    }
    /**
     * Sync tree changes back to customization (scope-based)
     * Called automatically when tree structure changes via drag-drop
     */
    async syncTreeChangesByScope(scope, treeNodes) {
        const customization = await this.loadCustomization(scope);
        // Extract and update priorities and parent relationships from tree structure
        this.updateCustomizationFromTree(treeNodes, customization);
        await this.saveCustomization(scope, customization);
    }
    /**
     * Load menu customization for a specific scope
     */
    async loadCustomization(scope) {
        try {
            const scopedSettings = this.settingsService.scope(scope);
            const saved = await scopedSettings.get(AXP_MENU_CUSTOMIZATION_KEY);
            if (saved && saved.version) {
                return saved;
            }
            return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
        }
        catch {
            return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
        }
    }
    /**
     * Save menu customization for a specific scope
     */
    async saveCustomization(scope, customization) {
        const scopedSettings = this.settingsService.scope(scope);
        await scopedSettings.set(AXP_MENU_CUSTOMIZATION_KEY, customization);
        // Clear menu cache to force reload
        this.menuProviderService.clearCache();
    }
    /**
     * Hide a menu item (scope-based)
     */
    async hideMenuItemByScope(scope, menuName) {
        this.validateMenuName(menuName, 'hide');
        const customization = await this.loadCustomization(scope);
        this.ensureOverrideExists(customization, menuName);
        customization.overrides[menuName].hidden = true;
        await this.saveCustomization(scope, customization);
    }
    /**
     * Show a menu item (scope-based)
     */
    async showMenuItemByScope(scope, menuName) {
        this.validateMenuName(menuName, 'show');
        const customization = await this.loadCustomization(scope);
        if (customization.overrides[menuName]) {
            delete customization.overrides[menuName].hidden;
            this.cleanupEmptyOverride(customization, menuName);
        }
        await this.saveCustomization(scope, customization);
    }
    /**
     * Update menu item priority (scope-based)
     */
    async updateMenuPriorityByScope(scope, menuName, priority) {
        this.validateMenuName(menuName, 'update priority for');
        const customization = await this.loadCustomization(scope);
        this.ensureOverrideExists(customization, menuName);
        customization.overrides[menuName].priority = priority;
        await this.saveCustomization(scope, customization);
    }
    /**
     * Update menu item properties (scope-based)
     */
    async updateMenuPropertiesByScope(scope, menuName, properties) {
        this.validateMenuName(menuName, 'update properties for');
        const customization = await this.loadCustomization(scope);
        this.ensureOverrideExists(customization, menuName);
        customization.overrides[menuName].properties = {
            ...customization.overrides[menuName].properties,
            ...properties,
        };
        await this.saveCustomization(scope, customization);
    }
    /**
     * Add custom menu item (scope-based)
     */
    async addCustomMenuItemByScope(scope, menuItem, parent) {
        const customization = await this.loadCustomization(scope);
        // Generate unique name if not provided
        if (!menuItem.name) {
            menuItem.name = `custom-menu-${Date.now()}`;
        }
        customization.customItems.push(menuItem);
        await this.saveCustomization(scope, customization);
    }
    /**
     * Update custom menu item (scope-based)
     */
    async updateCustomMenuItemByScope(scope, menuName, menuItem) {
        this.validateMenuName(menuName, 'update');
        const customization = await this.loadCustomization(scope);
        const index = customization.customItems.findIndex((item) => item.name === menuName);
        if (index === -1) {
            throw new Error(`Custom menu item '${menuName}' not found`);
        }
        customization.customItems[index] = menuItem;
        await this.saveCustomization(scope, customization);
    }
    /**
     * Delete custom menu item (scope-based)
     */
    async deleteCustomMenuItemByScope(scope, menuName) {
        this.validateMenuName(menuName, 'delete');
        const customization = await this.loadCustomization(scope);
        const initialLength = customization.customItems.length;
        customization.customItems = customization.customItems.filter((item) => item.name !== menuName);
        if (customization.customItems.length === initialLength) {
            throw new Error(`Custom menu item '${menuName}' not found`);
        }
        await this.saveCustomization(scope, customization);
    }
    /**
     * Reset all customizations for a scope (scope-based)
     */
    async resetCustomizationsByScope(scope) {
        await this.saveCustomization(scope, cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT));
    }
    //#endregion
    //#region ----   Key-Based Public Methods   ----
    /**
     * Get menu tree using a generic scope key (e.g., 'edition:123', 'tenant:456')
     */
    async getMenuTreeByKey(scopeKey) {
        // Get RAW menu items WITHOUT middleware (for management purposes)
        const baseItems = await this.menuProviderService.rawItems();
        // Load customizations for the given scope key
        const customization = await this.loadCustomizationByKey(scopeKey);
        // Merge custom items with base items
        const allItems = [...baseItems, ...customization.customItems];
        // Apply parent overrides to restructure items BEFORE building tree
        const restructuredItems = this.applyParentOverrides(allItems, customization);
        // Convert to tree nodes with metadata
        return this.convertToTreeNodes(restructuredItems, customization);
    }
    /**
     * Sync tree changes using a generic scope key
     */
    async syncTreeChangesByKey(scopeKey, treeNodes) {
        const customization = await this.loadCustomizationByKey(scopeKey);
        // Extract and update priorities and parent relationships from tree structure
        this.updateCustomizationFromTree(treeNodes, customization);
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Load menu customization using a generic scope key
     */
    async loadCustomizationByKey(scopeKey) {
        try {
            const storageKey = buildCustomizationKey(scopeKey);
            const scopedSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
            const saved = await scopedSettings.get(storageKey);
            if (saved && saved.version) {
                return saved;
            }
            return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
        }
        catch {
            return cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT);
        }
    }
    /**
     * Save menu customization using a generic scope key
     */
    async saveCustomizationByKey(scopeKey, customization) {
        const storageKey = buildCustomizationKey(scopeKey);
        const scopedSettings = this.settingsService.scope(AXPPlatformScope.Tenant);
        await scopedSettings.set(storageKey, customization);
        // Clear menu cache to force reload
        this.menuProviderService.clearCache();
    }
    /**
     * Hide a menu item using a generic scope key
     */
    async hideMenuItemByKey(scopeKey, menuName) {
        this.validateMenuName(menuName, 'hide');
        const customization = await this.loadCustomizationByKey(scopeKey);
        this.ensureOverrideExists(customization, menuName);
        customization.overrides[menuName].hidden = true;
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Show a menu item using a generic scope key
     */
    async showMenuItemByKey(scopeKey, menuName) {
        this.validateMenuName(menuName, 'show');
        const customization = await this.loadCustomizationByKey(scopeKey);
        if (customization.overrides[menuName]) {
            delete customization.overrides[menuName].hidden;
            this.cleanupEmptyOverride(customization, menuName);
        }
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Update menu item properties using a generic scope key
     */
    async updateMenuPropertiesByKey(scopeKey, menuName, properties) {
        this.validateMenuName(menuName, 'update properties for');
        const customization = await this.loadCustomizationByKey(scopeKey);
        this.ensureOverrideExists(customization, menuName);
        customization.overrides[menuName].properties = {
            ...customization.overrides[menuName].properties,
            ...properties,
        };
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Add custom menu item using a generic scope key
     */
    async addCustomMenuItemByKey(scopeKey, menuItem, parent) {
        const customization = await this.loadCustomizationByKey(scopeKey);
        // Generate unique name if not provided
        if (!menuItem.name) {
            menuItem.name = `custom-menu-${Date.now()}`;
        }
        customization.customItems.push(menuItem);
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Update custom menu item using a generic scope key
     */
    async updateCustomMenuItemByKey(scopeKey, menuName, menuItem) {
        this.validateMenuName(menuName, 'update');
        const customization = await this.loadCustomizationByKey(scopeKey);
        const index = customization.customItems.findIndex((item) => item.name === menuName);
        if (index === -1) {
            throw new Error(`Custom menu item '${menuName}' not found`);
        }
        customization.customItems[index] = menuItem;
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Delete custom menu item using a generic scope key
     */
    async deleteCustomMenuItemByKey(scopeKey, menuName) {
        this.validateMenuName(menuName, 'delete');
        const customization = await this.loadCustomizationByKey(scopeKey);
        const initialLength = customization.customItems.length;
        customization.customItems = customization.customItems.filter((item) => item.name !== menuName);
        if (customization.customItems.length === initialLength) {
            throw new Error(`Custom menu item '${menuName}' not found`);
        }
        await this.saveCustomizationByKey(scopeKey, customization);
    }
    /**
     * Reset all customizations using a generic scope key
     */
    async resetCustomizationsByKey(scopeKey) {
        await this.saveCustomizationByKey(scopeKey, cloneDeep(AXP_MENU_CUSTOMIZATION_DEFAULT));
    }
    //#endregion
    //#region ----   Private Methods   ----
    /**
     * Apply parent overrides from customization to restructure menu items
     * This ensures the tree reflects saved parent changes (moves)
     */
    applyParentOverrides(items, customization) {
        // First, flatten all items into a map for easy lookup
        const itemMap = this.flattenMenuItems(items);
        // Build new structure based on effective parent relationships
        const rootItems = [];
        const childrenMap = new Map();
        for (const [itemName, item] of itemMap.entries()) {
            const override = customization.overrides[itemName];
            // Determine effective parent (override takes precedence)
            let effectiveParent;
            if (override?.parentName !== undefined) {
                // parentName is explicitly set (could be null for root, or a parent name)
                effectiveParent = override.parentName;
            }
            else {
                // No override - find original parent by searching original structure
                effectiveParent = this.findOriginalParent(items, itemName);
            }
            if (effectiveParent === null || effectiveParent === undefined) {
                // Root level item
                rootItems.push(item);
            }
            else {
                // Child item - add to parent's children
                if (!childrenMap.has(effectiveParent)) {
                    childrenMap.set(effectiveParent, []);
                }
                childrenMap.get(effectiveParent).push(item);
            }
        }
        // Attach children to their parents recursively
        const attachChildren = (item) => {
            if (item.name && childrenMap.has(item.name)) {
                item.children = childrenMap.get(item.name);
                item.children?.forEach(attachChildren);
            }
        };
        rootItems.forEach(attachChildren);
        return rootItems;
    }
    /**
     * Find the original parent name of an item in the original structure
     * Returns undefined for root items, string for items with parents, null for not found
     */
    findOriginalParent(items, targetName, currentParent) {
        for (const item of items) {
            if (item.name === targetName) {
                return currentParent; // undefined if root, string if has parent
            }
            if (item.children) {
                const found = this.findOriginalParent(item.children, targetName, item.name);
                if (found !== null) {
                    // Found in children (could be undefined for root of subtree, or string for nested item)
                    return found;
                }
                // found === null means not found in this subtree, continue searching
            }
        }
        return null; // Not found in this level or any children
    }
    /**
     * Convert menu items to AXTreeNode[] with metadata
     */
    convertToTreeNodes(items, customization, parentName) {
        const nodes = items.map((item) => {
            const itemName = item.name;
            const override = itemName ? customization.overrides[itemName] : undefined;
            const isCustom = itemName ? customization.customItems.some((ci) => ci.name === itemName) : false;
            // Create metadata
            const metadata = {
                isBuiltIn: !isCustom,
                isCustom,
                isHidden: override?.hidden || false,
                originalPriority: item.priority,
                originalParentName: parentName,
            };
            // Apply ALL overrides: priority AND properties (text, icon, description, etc.)
            const effectivePriority = override?.priority !== undefined ? override.priority : item.priority;
            const effectiveItem = {
                ...item,
                ...override?.properties, // Apply property overrides (text, icon, description)
                priority: effectivePriority,
            };
            // Create tree node data with effective (overridden) values
            const nodeData = {
                menuItem: effectiveItem,
                metadata,
            };
            // Create tree node using effective (overridden) values
            const treeNode = {
                id: itemName || item.path || this.generateNodeId(),
                title: effectiveItem.text || effectiveItem.path || 'Unnamed',
                icon: effectiveItem.icon,
                expanded: false,
                selected: false,
                ['children']: item.children ? this.convertToTreeNodes(item.children, customization, itemName) : undefined,
                childrenCount: item.children?.length,
                data: nodeData,
            };
            return treeNode;
        });
        // Sort by priority
        nodes.sort((a, b) => {
            const aPriority = a['data']?.menuItem.priority ?? 0;
            const bPriority = b['data']?.menuItem.priority ?? 0;
            return aPriority - bPriority;
        });
        return nodes;
    }
    /**
     * Update customization from tree structure
     * Extracts priorities and parent relationships from tree nodes
     */
    updateCustomizationFromTree(treeNodes, customization, parentName) {
        // Calculate base priority for this level to maintain relative ordering
        const basePriority = parentName ? PRIORITY_BASE_NESTED : PRIORITY_BASE_ROOT;
        const priorityStep = PRIORITY_STEP;
        treeNodes.forEach((node, index) => {
            const nodeData = node['data'] || null;
            const menuItem = nodeData?.menuItem;
            if (menuItem?.name) {
                this.ensureOverrideExists(customization, menuItem.name);
                // Calculate new priority based on current position
                const newPriority = basePriority + index * priorityStep;
                // Get current effective priority (considering existing overrides)
                const currentEffectivePriority = customization.overrides[menuItem.name]?.priority ?? nodeData.metadata.originalPriority ?? 0;
                // Always update priority to reflect current position in tree
                // This ensures reordering works correctly even after multiple moves
                if (newPriority !== currentEffectivePriority) {
                    customization.overrides[menuItem.name].priority = newPriority;
                }
                // Determine current effective parent (considering existing overrides)
                const currentEffectiveParent = customization.overrides[menuItem.name]?.parentName ?? nodeData.metadata.originalParentName;
                // Update parent relationship if it changed from current effective parent
                if (parentName !== currentEffectiveParent) {
                    if (parentName) {
                        customization.overrides[menuItem.name].parentName = parentName;
                    }
                    else {
                        // Moving to root - set to null (not undefined) so middleware will process it
                        // moveTo(null) moves the item to root level
                        customization.overrides[menuItem.name].parentName = null;
                    }
                }
                // Clean up empty overrides
                this.cleanupEmptyOverride(customization, menuItem.name);
                // Recursively process children
                const nodeChildren = node['children'];
                if (nodeChildren && nodeChildren.length > 0) {
                    this.updateCustomizationFromTree(nodeChildren, customization, menuItem.name);
                }
            }
        });
    }
    /**
     * Validate menu name before operations
     */
    validateMenuName(menuName, operation) {
        if (!menuName) {
            throw new Error(`Menu item must have a name to be ${operation}`);
        }
    }
    /**
     * Ensure override object exists for a menu item
     */
    ensureOverrideExists(customization, menuName) {
        if (!customization.overrides[menuName]) {
            customization.overrides[menuName] = {};
        }
    }
    /**
     * Clean up empty override objects
     */
    cleanupEmptyOverride(customization, menuName) {
        if (Object.keys(customization.overrides[menuName] || {}).length === 0) {
            delete customization.overrides[menuName];
        }
    }
    /**
     * Flatten menu items recursively into a map
     */
    flattenMenuItems(items) {
        const itemMap = new Map();
        const flatten = (itemList) => {
            for (const item of itemList) {
                if (item.name) {
                    // Clone item without children to rebuild structure
                    itemMap.set(item.name, { ...item, children: undefined });
                }
                if (item.children) {
                    flatten(item.children);
                }
            }
        };
        flatten(items);
        return itemMap;
    }
    /**
     * Generate unique ID for tree nodes
     */
    generateNodeId() {
        return `node-${Date.now()}-${Math.floor(Math.random() * 10000)}`;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPMenuManagementService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPMenuManagementService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPMenuManagementService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }] });

//#endregion
//#region ----   Menu Customizer Popup Component   ----
/**
 * Popup wrapper for the menu customizer component.
 * Provides a popup layout with actions for managing menu customizations.
 *
 * Pass the following data when opening the popup:
 * - scopeKey: string - The scope key for menu customizations
 * - showToolbar?: boolean - Whether to show the toolbar (default: true)
 * - allowAddItems?: boolean - Whether to allow adding items (default: true)
 * - dragBehavior?: AXTreeViewDragBehavior - Drag behavior (default: 'move')
 * - dragArea?: AXTreeViewDragArea - Drag area (default: 'handler')
 */
class AXPMenuCustomizerPopupComponent extends AXPPopupLayoutBaseComponent {
    constructor() {
        super(...arguments);
        //#region ----   Component State   ----
        /** Reference to the menu customizer component */
        this.menuCustomizer = viewChild(AXPMenuCustomizerComponent, ...(ngDevMode ? [{ debugName: "menuCustomizer" }] : []));
        /** The scope key for menu customizations (set by popup service) */
        this.scopeKey = signal('', ...(ngDevMode ? [{ debugName: "scopeKey" }] : []));
        /** Whether to show the toolbar */
        this.showToolbar = signal(true, ...(ngDevMode ? [{ debugName: "showToolbar" }] : []));
        /** Whether to allow adding custom items */
        this.allowAddItems = signal(true, ...(ngDevMode ? [{ debugName: "allowAddItems" }] : []));
        /** Drag behavior for the tree view */
        this.dragBehavior = signal('both', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : []));
        /** Drag area for the tree view */
        this.dragArea = signal('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : []));
        /** Whether the component is ready to render (scopeKey is set) */
        this.isReady = computed(() => this.scopeKey() !== '', ...(ngDevMode ? [{ debugName: "isReady" }] : []));
    }
    //#endregion
    //#region ----   Lifecycle Methods   ----
    async ngOnInit() {
        await super.ngOnInit();
        // Popup-specific initialization can go here
    }
    //#endregion
    //#region ----   UI Handlers   ----
    /**
     * Returns the primary menu items for the popup layout.
     */
    getPrimaryMenuItems() {
        return [
            {
                title: '@general:actions.close.title',
                icon: 'fa-solid fa-xmark',
                command: {
                    name: 'close',
                },
            },
        ];
    }
    /**
     * Handles when changes are saved
     */
    onSaved() {
        this.close(true);
    }
    /**
     * Handles when customization is cancelled
     */
    onCancelled() {
        this.close(false);
    }
    /**
     * Executes popup commands
     */
    execute(command) {
        if (command.name === 'close') {
            this.close(false);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPMenuCustomizerPopupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: AXPMenuCustomizerPopupComponent, isStandalone: true, selector: "axp-menu-customizer-popup", host: { classAttribute: "axp-menu-customizer-popup" }, providers: [
            {
                provide: AXPPopupLayoutBase,
                useExisting: AXPMenuCustomizerPopupComponent,
            },
        ], viewQueries: [{ propertyName: "menuCustomizer", first: true, predicate: AXPMenuCustomizerComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
    <axp-popup-layout>
      <axp-page-content>
        @if (isReady()) {
          <axp-menu-customizer
            [scopeKey]="scopeKey()"
            [showToolbar]="showToolbar()"
            [allowAddItems]="allowAddItems()"
            [dragBehavior]="dragBehavior()"
            [dragArea]="dragArea()"
            (saved)="onSaved()"
            (cancelled)="onCancelled()"
          ></axp-menu-customizer>
        }
      </axp-page-content>
    </axp-popup-layout>
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPopupLayoutComponent, selector: "axp-popup-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "    axp-page-content,     axp-page-footer-container,    axp-page-footer,    axp-page-header,    axp-page-header-container,    axp-page-toolbar,    axp-layout-content,     axp-layout-page-content,     axp-layout-sections,    axp-layout-body,    axp-layout-page-body,    axp-layout-prefix,    axp-layout-suffix,    axp-layout-title-bar,    axp-layout-title,     axp-layout-title-actions,     axp-layout-nav-button,     axp-layout-description,     axp-layout-breadcrumbs,    axp-layout-list-action,    " }, { kind: "component", type: AXPMenuCustomizerComponent, selector: "axp-menu-customizer", inputs: ["scopeKey", "showToolbar", "allowAddItems", "dragBehavior", "dragArea"], outputs: ["saved", "cancelled"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPMenuCustomizerPopupComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'axp-menu-customizer-popup',
                    template: `
    <axp-popup-layout>
      <axp-page-content>
        @if (isReady()) {
          <axp-menu-customizer
            [scopeKey]="scopeKey()"
            [showToolbar]="showToolbar()"
            [allowAddItems]="allowAddItems()"
            [dragBehavior]="dragBehavior()"
            [dragArea]="dragArea()"
            (saved)="onSaved()"
            (cancelled)="onCancelled()"
          ></axp-menu-customizer>
        }
      </axp-page-content>
    </axp-popup-layout>
  `,
                    imports: [
                        CommonModule,
                        AXTranslationModule,
                        AXPPopupLayoutComponent,
                        AXPThemeLayoutBlockComponent,
                        AXPMenuCustomizerComponent,
                    ],
                    encapsulation: ViewEncapsulation.None,
                    providers: [
                        {
                            provide: AXPPopupLayoutBase,
                            useExisting: AXPMenuCustomizerPopupComponent,
                        },
                    ],
                    host: { class: 'axp-menu-customizer-popup' },
                }]
        }], propDecorators: { menuCustomizer: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPMenuCustomizerComponent), { isSignal: true }] }] } });

//#region ----   Imports   ----
//#endregion
//#region ----   Open Menu Customizer Action   ----
/**
 * Workflow action that opens the menu customizer popup.
 * Expects the context to contain:
 * - data: The entity data (must have an 'id' property)
 * - options.scopePrefix: The prefix for the scope key (e.g., 'edition', 'tenant')
 * - options.title: Optional custom title for the popup
 * - options.showToolbar: Whether to show toolbar (default: true)
 * - options.allowAddItems: Whether to allow adding items (default: true)
 * - options.dragBehavior: Drag behavior - 'none' | 'move' | 'copy' (default: 'move')
 * - options.dragArea: Drag area - 'node' | 'handler' (default: 'handler')
 */
class AXMOpenMenuCustomizerAction extends AXPWorkflowAction {
    constructor() {
        super(...arguments);
        //#region ----   Dependencies   ----
        this.popupService = inject(AXPopupService);
        this.translateService = inject(AXTranslationService);
    }
    //#endregion
    //#region ----   Execute   ----
    async execute(context) {
        // Get entity data
        const data = context.getVariable('data');
        const entityId = data?.id;
        if (!entityId) {
            console.error('Menu customizer requires entity data with an id property');
            context.setOutput('result', false);
            return;
        }
        // Get scope configuration
        const scopePrefix = context.getVariable('options.scopePrefix') || 'entity';
        const scopeKey = `${scopePrefix}:${entityId}`;
        // Get optional title
        const customTitle = context.getVariable('options.title');
        const defaultTitle = await this.translateService.translateAsync('@platform-management:menu-management.components.menu-customizer-popup.title');
        const entityTitle = data?.title || data?.name || entityId;
        const title = customTitle || `${defaultTitle} - ${entityTitle}`;
        // Open popup using the component from platform/layout/components
        // Pass signals to properly bind to the popup component's signal properties
        const result = await this.popupService.open(AXPMenuCustomizerPopupComponent, {
            title,
            size: 'lg',
            data: {
                scopeKey: signal(scopeKey),
                showToolbar: signal(context.getVariable('options.showToolbar') ?? true),
                allowAddItems: signal(context.getVariable('options.allowAddItems') ?? true),
                dragBehavior: signal(context.getVariable('options.dragBehavior') ?? 'both'),
                dragArea: signal(context.getVariable('options.dragArea') ?? 'handler'),
            },
        });
        // Set result based on popup outcome
        context.setOutput('result', result?.data === true);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMOpenMenuCustomizerAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMOpenMenuCustomizerAction }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMOpenMenuCustomizerAction, decorators: [{
            type: Injectable
        }] });
//#endregion
//#region ----   Customize Menu Workflow   ----
/**
 * Workflow definition for customizing menus.
 * Opens the menu customizer popup and handles the result.
 */
const AXMCustomizeMenuWorkflow = {
    startStepId: 'open-customizer',
    steps: {
        'open-customizer': {
            action: 'open-menu-customizer',
            nextSteps: [
                {
                    conditions: [{ type: 'SINGLE', expression: 'context.getOutput("result") == true' }],
                    nextStepId: 'show-success-toast',
                },
            ],
        },
        'show-success-toast': {
            action: 'AXPToastAction',
            input: {
                color: 'success',
                title: '@platform-management:menu-management.messages.success.customization-saved',
            },
        },
    },
};

//#region ----   Imports   ----
//#endregion
//#region ----   Module   ----
/**
 * Module for menu management features including the menu customizer
 * and related workflows.
 */
class AXMMenuManagementModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMMenuManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: AXMMenuManagementModule, imports: [i1.AXPWorkflowModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMMenuManagementModule, providers: [
            {
                provide: AXP_MENU_CUSTOMIZER_SERVICE,
                useExisting: AXPMenuManagementService,
            },
        ], imports: [AXPWorkflowModule.forChild({
                workflows: {
                    'customize-menu': AXMCustomizeMenuWorkflow,
                },
                actions: {
                    'open-menu-customizer': AXMOpenMenuCustomizerAction,
                },
            })] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMMenuManagementModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        AXPWorkflowModule.forChild({
                            workflows: {
                                'customize-menu': AXMCustomizeMenuWorkflow,
                            },
                            actions: {
                                'open-menu-customizer': AXMOpenMenuCustomizerAction,
                            },
                        }),
                    ],
                    providers: [
                        {
                            provide: AXP_MENU_CUSTOMIZER_SERVICE,
                            useExisting: AXPMenuManagementService,
                        },
                    ],
                }]
        }] });

/**
 * Token that returns current ISO date-time string.
 */
class AXMTokenProvider {
    constructor() {
        this.name = 'now';
        this.title = 'Now';
        this.description = 'Current date and time in ISO format';
    }
    execute() {
        return Promise.resolve(new Date().toISOString());
    }
}

class AXMTokensService extends AXMEntityCrudServiceImpl {
}
class AXMTokensServiceImpl extends AXMEntityCrudServiceImpl {
    constructor() {
        super(`${RootConfig.module.name}.${RootConfig.entities.token.name}`);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokensServiceImpl, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokensServiceImpl }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokensServiceImpl, decorators: [{
            type: Injectable
        }], ctorParameters: () => [] });

//#region ----   Imports   ----
//#endregion
//#region ----   Factory Cache   ----
/**
 * Global cache for loaded token providers.
 * Cleared when token entity changes occur.
 */
let cachedProviders = null;
/**
 * Clears the cached providers, forcing reload on next access.
 */
function clearDynamicTokenProvidersCache() {
    cachedProviders = null;
}
//#endregion
//#region ----   Factory Function   ----
/**
 * Factory function that loads tokens from backend and creates providers for each.
 * Uses global caching - tokens are loaded once and cached until invalidated.
 *
 * @param injector Angular injector to resolve dependencies
 * @returns Promise that resolves to an array of token providers
 */
async function createDynamicTokenProviders(injector) {
    // Return cached providers if available
    if (cachedProviders) {
        return cachedProviders;
    }
    // Load providers and cache the promise
    cachedProviders = loadTokenProviders(injector);
    return cachedProviders;
}
/**
 * Internal function that loads tokens from backend and creates providers.
 */
async function loadTokenProviders(injector) {
    const tokensService = injector.get(AXMTokensService);
    // const entityResolver = injector.get(AXPEntityDefinitionRegistryService);
    // const tokenEntityDef = await entityResolver.exists(RootConfig.module.name, RootConfig.entities.token.name);
    // if (!tokenEntityDef) {
    //     return [];
    // }
    try {
        // Load all tokens from backend
        const queryResult = await tokensService.query({
            skip: 0,
            take: 1000, // Load all tokens (adjust if needed)
        });
        if (!queryResult || !queryResult.items || queryResult.items.length === 0) {
            return [];
        }
        // Convert each token entity to a provider
        // Pass injector instead of expressionEvaluator to avoid circular dependency
        return queryResult.items.map((token) => {
            return createTokenProvider(token, injector);
        });
    }
    catch (error) {
        console.error('[DynamicTokenProvider] Failed to load tokens from backend:', error);
        throw error; // Throw error as requested
    }
}
/**
 * Creates a token provider from a token entity model.
 * Uses lazy injection for expression evaluator to avoid circular dependency.
 * Reloads token data from backend on each execution to ensure fresh data.
 */
function createTokenProvider(token, injector) {
    const tokenName = token.name;
    return {
        name: tokenName,
        title: token.title,
        description: token.description,
        async execute() {
            // Reload token from backend to get fresh data
            // This ensures we always have the latest token configuration
            // const entityResolver = injector.get(AXPEntityDefinitionRegistryService);
            // const tokenEntityDef = await entityResolver.exists(RootConfig.module.name, RootConfig.entities.token.name);
            // if (!tokenEntityDef) {
            //     return;
            // }
            const tokensService = injector.get(AXMTokensService);
            let currentToken = null;
            try {
                // Try to get the token by name (assuming name is unique)
                const queryResult = await tokensService.query({
                    skip: 0,
                    take: 1000,
                    filter: {
                        field: 'name',
                        operator: { type: 'equal' },
                        value: tokenName,
                    },
                });
                if (queryResult?.items && queryResult.items.length > 0) {
                    currentToken = queryResult.items[0];
                }
            }
            catch (error) {
                console.warn(`[DynamicTokenProvider] Failed to reload token "${tokenName}", using cached data:`, error);
                // Fallback to original token data if reload fails
                currentToken = token;
            }
            // Use reloaded token if available, otherwise fallback to original
            const tokenToUse = currentToken || token;
            if (!tokenToUse.expression) {
                throw new Error(`Token "${tokenName}" has no expression defined`);
            }
            // Normalize type field - handle case where select box returns object instead of string
            const normalizedType = normalizeType(tokenToUse.type);
            if (normalizedType === 'Expression') {
                // Expression type: evaluate the expression using expression evaluator
                // Expression can use: tokens.get(), identifier.peek(), session.currentUser(), etc.
                // Lazy inject expression evaluator to avoid circular dependency
                try {
                    const expressionEvaluator = injector.get(AXPExpressionEvaluatorService);
                    return await expressionEvaluator.evaluate(tokenToUse.expression);
                }
                catch (error) {
                    console.error(`[DynamicTokenProvider] Error evaluating token "${tokenName}":`, error);
                    throw error;
                }
            }
            else {
                // Static types (String, Integer, Boolean): return direct value from expression field (no evaluation)
                // Optionally convert to appropriate type
                const expressionValue = tokenToUse.expression;
                if (normalizedType === 'Integer') {
                    const numValue = parseInt(expressionValue, 10);
                    if (isNaN(numValue)) {
                        throw new Error(`Token "${tokenName}" expression is not a valid integer: ${expressionValue}`);
                    }
                    return numValue;
                }
                else if (normalizedType === 'Boolean') {
                    const lowerValue = expressionValue.toLowerCase().trim();
                    if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {
                        return true;
                    }
                    else if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {
                        return false;
                    }
                    throw new Error(`Token "${tokenName}" expression is not a valid boolean: ${expressionValue}`);
                }
                else {
                    // String type: return as-is
                    return expressionValue;
                }
            }
        },
    };
}
/**
 * Normalizes the type field to a string value.
 * Handles cases where select box widgets return objects instead of strings.
 * @param type The type value (can be string or object with value property)
 * @returns Normalized type string ('String', 'Integer', 'Boolean', or 'Expression')
 */
function normalizeType(type) {
    if (typeof type === 'string') {
        const validTypes = ['String', 'Integer', 'Boolean', 'Expression'];
        if (validTypes.includes(type)) {
            return type;
        }
    }
    if (type && typeof type === 'object' && 'value' in type) {
        const validTypes = ['String', 'Integer', 'Boolean', 'Expression'];
        if (validTypes.includes(type.value)) {
            return type.value;
        }
    }
    // Fallback: try to convert to string
    const typeString = String(type);
    const validTypes = ['String', 'Integer', 'Boolean', 'Expression'];
    if (validTypes.includes(typeString)) {
        return typeString;
    }
    throw new Error(`Invalid type value: ${JSON.stringify(type)}. Must be one of: String, Integer, Boolean, Expression`);
}
//#endregion

//#region ----   Imports   ----
//#endregion
//#region ----   Token Refresh Event Listener   ----
/**
 * Event listener provider that listens to token entity changes
 * and clears the token cache when tokens are updated, inserted, or deleted.
 */
class AXMTokenRefreshProvider {
    constructor() {
        this.tokenService = inject(AXPTokenDefinitionService);
        /**
         * Event keys to listen to for token entity changes.
         * Supports wildcard patterns for entity events.
         * Format: entity.{operation}.{ModuleName}.{EntityName}
         * Example: entity.updated.PlatformManagement.Tokens
         */
        this.key = `entity.*.${RootConfig.module.name}.${RootConfig.entities.token.name}`;
    }
    /**
     * Executes when a token entity event occurs (inserted, updated, or deleted).
     * Clears both the token definition service cache and the dynamic providers cache.
     */
    async execute(data) {
        // Clear token definition service cache
        this.tokenService.clearDefinitionsCache();
        // Clear dynamic token providers cache to force reload
        clearDynamicTokenProvidersCache();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenRefreshProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenRefreshProvider }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenRefreshProvider, decorators: [{
            type: Injectable
        }] });

//#region ----   Imports   ----
//#endregion
//#region ----   Token Module   ----
/**
 * Token feature module.
 * Provides token definition providers (static and dynamic) and refresh listeners.
 */
class AXMTokenModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenModule }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenModule, providers: [
            // Static token provider (built-in tokens)
            {
                provide: AXP_TOKEN_DEFINITION_PROVIDER,
                useClass: AXMTokenProvider,
                multi: true,
            },
            // Dynamic token provider (tokens from backend)
            {
                provide: AXP_TOKEN_DEFINITION_PROVIDER,
                useFactory: (injector) => createDynamicTokenProviders(injector),
                deps: [Injector],
                multi: true,
            },
            // Token refresh listener (clears cache on entity changes)
            {
                provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
                useClass: AXMTokenRefreshProvider,
                multi: true,
            },
            // Execute token command
            provideCommandSetups([
                {
                    key: `${RootConfig.module.name}.${RootConfig.entities.token.name}:Execute`,
                    command: () => import('./acorex-modules-platform-management-execute-token.command-C1ZoX8lQ.mjs').then((c) => c.ExecuteTokenCommand),
                },
            ]),
        ] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    exports: [],
                    declarations: [],
                    providers: [
                        // Static token provider (built-in tokens)
                        {
                            provide: AXP_TOKEN_DEFINITION_PROVIDER,
                            useClass: AXMTokenProvider,
                            multi: true,
                        },
                        // Dynamic token provider (tokens from backend)
                        {
                            provide: AXP_TOKEN_DEFINITION_PROVIDER,
                            useFactory: (injector) => createDynamicTokenProviders(injector),
                            deps: [Injector],
                            multi: true,
                        },
                        // Token refresh listener (clears cache on entity changes)
                        {
                            provide: AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER,
                            useClass: AXMTokenRefreshProvider,
                            multi: true,
                        },
                        // Execute token command
                        provideCommandSetups([
                            {
                                key: `${RootConfig.module.name}.${RootConfig.entities.token.name}:Execute`,
                                command: () => import('./acorex-modules-platform-management-execute-token.command-C1ZoX8lQ.mjs').then((c) => c.ExecuteTokenCommand),
                            },
                        ]),
                    ],
                }]
        }] });

class AXPUpdaterService {
    constructor() {
        const swUpdate = inject(SwUpdate, { optional: true });
        const dialogService = inject(AXDialogService);
        const translateService = inject(AXTranslationService);
        if (swUpdate?.isEnabled) {
            swUpdate.versionUpdates.subscribe((event) => {
                if (event.type === 'VERSION_READY') {
                    console.log('New version available');
                    const scope = RootConfig.config.i18n;
                    const dialog = dialogService.open({
                        icon: 'fa-regular fa-info',
                        content: translateService.translateSync('updater.content', { scope: scope }),
                        title: translateService.translateSync('updater.title', { scope: scope }),
                        type: 'primary',
                        orientation: 'horizontal',
                        buttons: [
                            {
                                text: translateService.translateSync('updater.update', { scope: scope }),
                                color: 'primary',
                                onClick: async (e) => {
                                    try {
                                        document.location.reload();
                                        dialog.close();
                                    }
                                    catch (error) {
                                        console.error(error);
                                    }
                                },
                            },
                            {
                                text: translateService.translateSync('updater.cancel', { scope: scope }),
                                color: 'default',
                                autofocus: true,
                                onClick: (e) => {
                                    dialog.close();
                                },
                            },
                        ],
                        closeButton: false,
                    });
                }
            });
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPUpdaterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPUpdaterService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXPUpdaterService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [] });

class AXMUpdaterModule {
    constructor(updaterService) {
        this.updaterService = updaterService;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMUpdaterModule, deps: [{ token: AXPUpdaterService }], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: AXMUpdaterModule }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMUpdaterModule, providers: [AXPUpdaterService] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMUpdaterModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    exports: [],
                    declarations: [],
                    providers: [AXPUpdaterService],
                }]
        }], ctorParameters: () => [{ type: AXPUpdaterService }] });

//#region ----   Imports   ----
//#endregion
//#region ----   Manifest Definition   ----
/**
 * Platform Management Module Manifest.
 * Defines module metadata, features, and provider references.
 */
const PlatformManagementManifest = {
    name: RootConfig.module.name,
    version: '1.0.0',
    title: RootConfig.module.title,
    icon: RootConfig.module.icon,
    i18n: RootConfig.config.i18n,
    dependencies: [
        'SecurityManagement',
        'ApplicationManagement',
        'SystemInsight',
        'TenantManagement',
        'SubscriptionManagement',
    ],
};
//#endregion

const AXPPlatformManagementMenuKeys = {
    AdministrationGroup: 'administration:group',
    Root: 'platform-management:menu',
    Tokens: 'platform-management:menu:tokens',
    Glossary: 'platform-management:menu:glossary',
    UserMenuManagement: 'platform-management:user:menus',
    MenuManagement: 'platform-management:menus',
};

const AXPPlatformManagementPermissionKeys = {
    PlatformManagement: {
        Management: 'PlatformManagement:Permission:Management',
        Administration: 'PlatformManagement:Permission:Administration',
        Token: {
            Management: 'PlatformManagement:Permission:Token.Management',
            View: 'PlatformManagement:Permission:Token.View',
            Edit: 'PlatformManagement:Permission:Token.Edit',
            Delete: 'PlatformManagement:Permission:Token.Delete',
            Create: 'PlatformManagement:Permission:Token.Create',
        },
        MenuManagement: {
            Management: 'PlatformManagement:Permission:MenuManagement.Management',
            View: 'PlatformManagement:Permission:MenuManagement.View',
            Edit: 'PlatformManagement:Permission:MenuManagement.Edit',
            Delete: 'PlatformManagement:Permission:MenuManagement.Delete',
            Create: 'PlatformManagement:Permission:MenuManagement.Create',
        },
    },
};

class AXMMenuProvider {
    constructor() {
        this.entityService = inject(AXPEntityService);
    }
    async provide(context) {
        const scope = RootConfig.config.i18n;
        // Add Tokens under Data Definitions
        const dataDefinitionsMenu = context.find(AXPDataManagementMenuKeys.Root);
        if (dataDefinitionsMenu.exists) {
            dataDefinitionsMenu.addItems([
                {
                    name: AXPPlatformManagementMenuKeys.Tokens,
                    priority: 9009,
                    text: `@${scope}:tokens.terms.tokens`,
                    path: this.entityService.createPath(RootConfig.module.name, RootConfig.entities.token.name),
                    icon: RootConfig.entities.token.icon,
                    policy: {
                        features: [RootConfig.module.name],
                        permissions: [AXPPlatformManagementPermissionKeys.PlatformManagement.Token.Management],
                    },
                },
            ]);
        }
    }
}

class AXMPermissionDefinitionProvider {
    constructor(injector) {
        this.injector = injector;
        this.translateService = this.injector.get(AXTranslationService);
    }
    async define(context) {
        const keys = AXPPlatformManagementPermissionKeys.PlatformManagement;
        context.addGroup(RootConfig.module.name, await this.translateService.translateAsync('@platform-management:permissions.manage.title'), await this.translateService.translateAsync('@platform-management:permissions.manage.description'))
            //
            .addPermission(keys.Token.Management, await this.translateService.translateAsync('@platform-management:tokens.permissions.token.manage.title'), await this.translateService.translateAsync('@platform-management:tokens.permissions.token.manage.description'))
            .addChild(keys.Token.View, await this.translateService.translateAsync('@platform-management:tokens.permissions.token.view.title'), await this.translateService.translateAsync('@platform-management:tokens.permissions.token.view.description'))
            .addChild(keys.Token.Create, await this.translateService.translateAsync('@platform-management:tokens.permissions.token.create.title'), await this.translateService.translateAsync('@platform-management:tokens.permissions.token.create.description'))
            .addChild(keys.Token.Edit, await this.translateService.translateAsync('@platform-management:tokens.permissions.token.edit.title'), await this.translateService.translateAsync('@platform-management:tokens.permissions.token.edit.description'))
            .addChild(keys.Token.Delete, await this.translateService.translateAsync('@platform-management:tokens.permissions.token.delete.title'), await this.translateService.translateAsync('@platform-management:tokens.permissions.token.delete.description'))
            .endPermission()
            //
            .addPermission(keys.MenuManagement.Management, await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.manage.title'), await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.manage.description'), [AXPPlatformManagementFeatureKeys.MenuCustomization] // Require menu-customization feature
        )
            .addChild(keys.MenuManagement.View, await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.view.title'), await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.view.description'))
            .addChild(keys.MenuManagement.Create, await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.create.title'), await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.create.description'))
            .addChild(keys.MenuManagement.Edit, await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.edit.title'), await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.edit.description'))
            .addChild(keys.MenuManagement.Delete, await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.delete.title'), await this.translateService.translateAsync('@platform-management:menu-management.permissions.menu-management.actions.delete.description'))
            .endPermission()
            //
            .endGroup();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPermissionDefinitionProvider, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPermissionDefinitionProvider }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPermissionDefinitionProvider, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i0.Injector }] });

async function tokenEntityFactory(injector) {
    const i18n = RootConfig.config.i18n;
    const entityDef = {
        module: RootConfig.module.name,
        name: RootConfig.entities.token.name,
        title: RootConfig.entities.token.title,
        icon: RootConfig.entities.token.icon,
        formats: {
            individual: 'Token',
            plural: 'Tokens',
        },
        plugins: [
            {
                name: 'unique-fields',
                options: {
                    fields: 'name',
                    scope: 'global',
                },
            },
            { name: 'history' },
            { name: 'compare' },
        ],
        relatedEntities: [],
        groups: [
            {
                id: 'basic-info',
                title: `@${i18n}:tokens.entities.token.groups.basic-info`,
            },
            {
                id: 'value',
                title: `@${i18n}:tokens.entities.token.groups.value`,
            },
        ],
        properties: [
            {
                name: 'name',
                title: '@general:terms.common.name',
                groupId: 'basic-info',
                schema: {
                    dataType: 'string',
                    interface: {
                        type: AXPWidgetsCatalog.text,
                    },
                },
                validations: [
                    {
                        rule: 'required',
                    },
                ],
                options: {
                    filter: {
                        inline: {
                            enabled: true,
                        },
                    },
                    sort: {
                        enabled: true,
                    },
                },
            },
            {
                name: 'title',
                title: '@general:terms.common.title',
                groupId: 'basic-info',
                schema: {
                    dataType: 'string',
                    interface: {
                        type: AXPWidgetsCatalog.text,
                    },
                },
                validations: [
                    {
                        rule: 'required',
                    },
                ],
                options: {
                    filter: {
                        inline: {
                            enabled: true,
                        },
                    },
                    sort: {
                        enabled: true,
                    },
                },
            },
            {
                name: 'description',
                title: '@general:terms.common.description',
                groupId: 'basic-info',
                schema: {
                    dataType: 'string',
                    interface: {
                        type: AXPWidgetsCatalog.largeText,
                    },
                },
                options: {
                    filter: {
                        advance: {
                            enabled: true,
                        },
                    },
                },
            },
            {
                name: 'type',
                title: `@${i18n}:tokens.entities.token.fields.type.title`,
                groupId: 'value',
                schema: {
                    dataType: 'string',
                    interface: {
                        type: AXPWidgetsCatalog.select,
                        options: {
                            valueField: 'value',
                            textField: 'title',
                            dataSource: [
                                { title: 'String', value: 'String' },
                                { title: 'Integer', value: 'Integer' },
                                { title: 'Boolean', value: 'Boolean' },
                                { title: 'Expression', value: 'Expression' },
                            ],
                            direction: 'horizontal',
                            multiple: false,
                        },
                    },
                },
                validations: [
                    {
                        rule: 'required',
                    },
                ],
                options: {
                    filter: {
                        advance: {
                            enabled: true,
                        },
                    },
                    sort: {
                        enabled: true,
                    },
                },
            },
            {
                name: 'expression',
                title: `@${i18n}:tokens.entities.token.fields.expression.title`,
                groupId: 'value',
                schema: {
                    dataType: 'string',
                    interface: {
                        type: AXPWidgetsList.Advanced.CodeEditor,
                    },
                },
                options: {
                    filter: {
                        advance: {
                            enabled: true,
                        },
                    },
                },
            },
        ],
        columns: [{ name: 'name' }, { name: 'title' }, { name: 'type' }, { name: 'expression' }],
        interfaces: {
            master: {
                create: {
                    sections: [
                        {
                            id: 'basic-info',
                        },
                        {
                            id: 'value',
                        },
                    ],
                    properties: [
                        {
                            name: 'name',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'title',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'description',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                        {
                            name: 'type',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'expression',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                    ],
                },
                update: {
                    sections: [
                        {
                            id: 'basic-info',
                        },
                        {
                            id: 'value',
                        },
                    ],
                    properties: [
                        {
                            name: 'name',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'title',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'description',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                        {
                            name: 'type',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'expression',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                    ],
                },
                single: {
                    title: '{{title}}',
                    sections: [
                        {
                            id: 'basic-info',
                        },
                        {
                            id: 'value',
                        },
                    ],
                    properties: [
                        {
                            name: 'name',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'title',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'description',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                        {
                            name: 'type',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 6,
                                    },
                                },
                            },
                        },
                        {
                            name: 'expression',
                            layout: {
                                positions: {
                                    lg: {
                                        colSpan: 12,
                                    },
                                },
                            },
                        },
                    ],
                    actions: [
                        ...entityMasterRecordActions(),
                        {
                            title: `@${i18n}:tokens.entities.token.actions.execute.title`,
                            command: {
                                name: `${RootConfig.module.name}.${RootConfig.entities.token.name}:Execute`,
                                options: {
                                    tokenName: '{{ context.eval("name") }}',
                                    tokenTitle: '{{ context.eval("title") }}',
                                },
                            },
                            priority: 'primary',
                            type: 'action',
                            icon: 'fa-light fa-play',
                            scope: AXPEntityCommandScope.Individual,
                        },
                    ],
                },
                list: {
                    actions: [
                        ...entityMasterCrudActions(),
                        {
                            title: `@${i18n}:tokens.entities.token.actions.execute.title`,
                            command: {
                                name: `${RootConfig.module.name}.${RootConfig.entities.token.name}:Execute`,
                                options: {
                                    tokenName: '{{ context.eval("name") }}',
                                    tokenTitle: '{{ context.eval("title") }}',
                                },
                            },
                            priority: 'primary',
                            type: 'action',
                            icon: 'fa-light fa-play',
                            scope: AXPEntityCommandScope.Individual,
                        },
                    ],
                    views: [createAllQueryView()],
                },
            },
        },
    };
    return entityDef;
}

class AXMTokenEntityModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenEntityModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenEntityModule }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenEntityModule, providers: [
            {
                provide: AXMTokensService,
                useClass: AXMTokensServiceImpl,
            },
        ] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMTokenEntityModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [],
                    exports: [],
                    declarations: [],
                    providers: [
                        {
                            provide: AXMTokensService,
                            useClass: AXMTokensServiceImpl,
                        },
                    ],
                }]
        }] });

// Entity Services

var index = /*#__PURE__*/Object.freeze({
    __proto__: null,
    AXMTokenEntityModule: AXMTokenEntityModule,
    AXMTokensService: AXMTokensService,
    AXMTokensServiceImpl: AXMTokensServiceImpl,
    tokenEntityFactory: tokenEntityFactory
});

//#region ----   Routes Factory   ----
function routesFactory() {
    const routes = [
        {
            path: ':app/platform-management/menus/:scope',
            canActivate: [AXPAuthGuard],
            loadComponent: () => AXPRootLayoutComponent,
            children: [
                {
                    path: '',
                    loadComponent: () => import('./acorex-modules-platform-management-menu-list.component-DMEgu6_w.mjs').then((c) => c.AXMMenuListComponent),
                    data: { reuse: true },
                },
            ],
        },
    ];
    return routes;
}
//#endregion
class AXMPlatformManagementModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPlatformManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: AXMPlatformManagementModule, imports: [AXMUpdaterModule,
            AXMTokenModule,
            AXMMenuManagementModule,
            // Entity Modules
            AXMTokenEntityModule] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPlatformManagementModule, providers: [
            // Module-specific providers (not part of manifest system)
            {
                provide: AXP_MENU_MIDDLEWARE,
                useClass: AXPCustomMenuMiddleware,
                multi: true,
            },
            {
                provide: ROUTES,
                multi: true,
                useFactory: routesFactory,
            },
            // Module Manifest Provider
            {
                provide: AXP_MODULE_MANIFEST_PROVIDER,
                useValue: PlatformManagementManifest,
                multi: true,
            },
            // Provider references (now using tokens)
            {
                provide: AXP_PERMISSION_DEFINITION_PROVIDER,
                useClass: AXMPermissionDefinitionProvider,
                multi: true,
            },
            {
                provide: AXP_MENU_PROVIDER,
                useClass: AXMMenuProvider,
                multi: true,
            },
            {
                provide: AXP_ENTITY_DEFINITION_LOADER,
                useClass: AXMEntityLoader,
                multi: true,
            },
            {
                provide: AXP_FEATURE_DEFINITION_PROVIDER,
                useClass: AXPPlatformManagementFeatureDefinitionProvider,
                multi: true,
            },
        ], imports: [AXMUpdaterModule,
            AXMTokenModule,
            AXMMenuManagementModule,
            // Entity Modules
            AXMTokenEntityModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AXMPlatformManagementModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        AXMUpdaterModule,
                        AXMTokenModule,
                        AXMMenuManagementModule,
                        // Entity Modules
                        AXMTokenEntityModule,
                    ],
                    exports: [],
                    declarations: [],
                    providers: [
                        // Module-specific providers (not part of manifest system)
                        {
                            provide: AXP_MENU_MIDDLEWARE,
                            useClass: AXPCustomMenuMiddleware,
                            multi: true,
                        },
                        {
                            provide: ROUTES,
                            multi: true,
                            useFactory: routesFactory,
                        },
                        // Module Manifest Provider
                        {
                            provide: AXP_MODULE_MANIFEST_PROVIDER,
                            useValue: PlatformManagementManifest,
                            multi: true,
                        },
                        // Provider references (now using tokens)
                        {
                            provide: AXP_PERMISSION_DEFINITION_PROVIDER,
                            useClass: AXMPermissionDefinitionProvider,
                            multi: true,
                        },
                        {
                            provide: AXP_MENU_PROVIDER,
                            useClass: AXMMenuProvider,
                            multi: true,
                        },
                        {
                            provide: AXP_ENTITY_DEFINITION_LOADER,
                            useClass: AXMEntityLoader,
                            multi: true,
                        },
                        {
                            provide: AXP_FEATURE_DEFINITION_PROVIDER,
                            useClass: AXPPlatformManagementFeatureDefinitionProvider,
                            multi: true,
                        },
                    ],
                }]
        }] });

// export * from './lib/features';

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

export { AXPMenuManagementService as A, RootConfig as R, AXMPlatformManagementModule as a, AXMTokenEntityModule as b, AXMTokensService as c, AXMTokensServiceImpl as d, AXPPlatformManagementFeatureKeys as e, tokenEntityFactory as t };
//# sourceMappingURL=acorex-modules-platform-management-acorex-modules-platform-management-BmAtaDRT.mjs.map
