viewlogic 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/plugins/I18nManager.js", "../src/plugins/AuthManager.js", "../src/plugins/CacheManager.js", "../src/plugins/QueryManager.js", "../src/core/RouteLoader.js", "../src/core/ErrorHandler.js", "../src/core/ComponentLoader.js", "../src/viewlogic-router.js"],
|
|
4
|
-
"sourcesContent": ["/**\r\n * ViewLogic Internationalization System\r\n * \uB2E4\uAD6D\uC5B4 \uC9C0\uC6D0 \uC2DC\uC2A4\uD15C\r\n */\r\nexport class I18nManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enabled: options.useI18n !== undefined ? options.useI18n : true,\r\n defaultLanguage: options.defaultLanguage || 'ko',\r\n fallbackLanguage: options.defaultLanguage || 'ko',\r\n cacheKey: options.cacheKey || 'viewlogic_lang',\r\n dataCacheKey: options.dataCacheKey || 'viewlogic_i18n_data',\r\n cacheVersion: options.cacheVersion || '1.0.0',\r\n enableDataCache: options.enableDataCache !== false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC694\uC2DC \uC5B8\uC5B4 \uBCC0\uACBD \uC2DC \uB77C\uC6B0\uD130 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8)\r\n this.router = router;\r\n \r\n this.messages = new Map();\r\n this.currentLanguage = this.config.defaultLanguage;\r\n this.isLoading = false;\r\n this.loadPromises = new Map();\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108\uB4E4\r\n this.listeners = {\r\n languageChanged: []\r\n };\r\n \r\n // \uBE44\uB3D9\uAE30 \uCD08\uAE30\uD654 \uC2DC\uC791 (constructor \uB0B4\uC5D0\uC11C\uB294 await \uBD88\uAC00)\r\n this.initPromise = this.init();\r\n }\r\n\r\n async init() {\r\n // i18n\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uCD08\uAE30\uD654\uD558\uC9C0 \uC54A\uC74C\r\n if (!this.config.enabled) {\r\n this.log('info', 'I18n system disabled');\r\n return;\r\n }\r\n \r\n // \uCE90\uC2DC\uC5D0\uC11C \uC5B8\uC5B4 \uC124\uC815 \uB85C\uB4DC\r\n this.loadLanguageFromCache();\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uCE90\uC2DC \uBE44\uD65C\uC131\uD654\r\n if (this.config.debug) {\r\n this.config.enableDataCache = false;\r\n this.log('debug', 'Data cache disabled in debug mode');\r\n }\r\n \r\n // \uCD08\uAE30 \uC5B8\uC5B4 \uD30C\uC77C \uC790\uB3D9 \uB85C\uB4DC (\uC544\uC9C1 \uB85C\uB4DC\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0\uC5D0\uB9CC)\r\n if (!this.messages.has(this.currentLanguage)) {\r\n try {\r\n await this.loadMessages(this.currentLanguage);\r\n } catch (error) {\r\n this.log('error', 'Failed to load initial language file:', error);\r\n }\r\n } else {\r\n this.log('debug', 'Language messages already loaded:', this.currentLanguage);\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC\uC5D0\uC11C \uC5B8\uC5B4 \uC124\uC815 \uB85C\uB4DC\r\n */\r\n loadLanguageFromCache() {\r\n try {\r\n const cachedLang = localStorage.getItem(this.config.cacheKey);\r\n if (cachedLang && this.isValidLanguage(cachedLang)) {\r\n this.currentLanguage = cachedLang;\r\n this.log('debug', 'Language loaded from cache:', cachedLang);\r\n }\r\n } catch (error) {\r\n this.log('warn', 'Failed to load language from cache:', error);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\n isValidLanguage(lang) {\r\n return typeof lang === 'string' && /^[a-z]{2}$/.test(lang);\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC5B8\uC5B4 \uBC18\uD658\r\n */\r\n getCurrentLanguage() {\r\n return this.currentLanguage;\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD\r\n */\r\n async setLanguage(language) {\r\n if (!this.isValidLanguage(language)) {\r\n this.log('warn', 'Invalid language code:', language);\r\n return false;\r\n }\r\n\r\n if (this.currentLanguage === language) {\r\n this.log('debug', 'Language already set to:', language);\r\n return true;\r\n }\r\n\r\n const oldLanguage = this.currentLanguage;\r\n this.currentLanguage = language;\r\n\r\n try {\r\n // \uC5B8\uC5B4 \uD30C\uC77C \uB85C\uB4DC\r\n await this.loadMessages(language);\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n this.saveLanguageToCache(language);\r\n \r\n // \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n this.emit('languageChanged', {\r\n from: oldLanguage,\r\n to: language,\r\n messages: this.messages.get(language)\r\n });\r\n \r\n this.log('info', 'Language changed successfully', { from: oldLanguage, to: language });\r\n return true;\r\n } catch (error) {\r\n // \uC2E4\uD328 \uC2DC \uC774\uC804 \uC5B8\uC5B4\uB85C \uBCF5\uC6D0\r\n this.currentLanguage = oldLanguage;\r\n this.log('error', 'Failed to change language:', error);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uB97C \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n */\r\n saveLanguageToCache(language) {\r\n try {\r\n localStorage.setItem(this.config.cacheKey, language);\r\n this.log('debug', 'Language saved to cache:', language);\r\n } catch (error) {\r\n this.log('warn', 'Failed to save language to cache:', error);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBA54\uC2DC\uC9C0 \uD30C\uC77C \uB85C\uB4DC\r\n */\r\n async loadMessages(language) {\r\n // \uC774\uBBF8 \uB85C\uB4DC\uB41C \uACBD\uC6B0\r\n if (this.messages.has(language)) {\r\n this.log('debug', 'Messages already loaded for:', language);\r\n return this.messages.get(language);\r\n }\r\n\r\n // \uC774\uBBF8 \uB85C\uB529 \uC911\uC778 \uACBD\uC6B0\r\n if (this.loadPromises.has(language)) {\r\n this.log('debug', 'Messages loading in progress for:', language);\r\n return await this.loadPromises.get(language);\r\n }\r\n\r\n const loadPromise = this._loadMessagesFromFile(language);\r\n this.loadPromises.set(language, loadPromise);\r\n\r\n try {\r\n const messages = await loadPromise;\r\n this.messages.set(language, messages);\r\n this.loadPromises.delete(language);\r\n this.log('debug', 'Messages loaded successfully for:', language);\r\n return messages;\r\n } catch (error) {\r\n this.loadPromises.delete(language);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * \uD30C\uC77C\uC5D0\uC11C \uBA54\uC2DC\uC9C0 \uB85C\uB4DC (\uCE90\uC2F1 \uC9C0\uC6D0)\r\n */\r\n async _loadMessagesFromFile(language) {\r\n // \uCE90\uC2DC\uC5D0\uC11C \uBA3C\uC800 \uC2DC\uB3C4\r\n if (this.config.enableDataCache) {\r\n const cachedData = this.getDataFromCache(language);\r\n if (cachedData) {\r\n this.log('debug', 'Messages loaded from cache:', language);\r\n return cachedData;\r\n }\r\n }\r\n \r\n try {\r\n // JSON \uD30C\uC77C\uB85C \uBCC0\uACBD - config\uC758 i18nPath \uC0AC\uC6A9\r\n const i18nPath = `${this.router.config.i18nPath}/${language}.json`;\r\n const response = await fetch(i18nPath);\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n const messages = await response.json();\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n if (this.config.enableDataCache) {\r\n this.saveDataToCache(language, messages);\r\n }\r\n \r\n return messages;\r\n } catch (error) {\r\n this.log('error', 'Failed to load messages file for:', language, error);\r\n \r\n // \uD3F4\uBC31 \uC5B8\uC5B4 \uC2DC\uB3C4\r\n if (language !== this.config.fallbackLanguage) {\r\n this.log('info', 'Trying fallback language:', this.config.fallbackLanguage);\r\n return await this._loadMessagesFromFile(this.config.fallbackLanguage);\r\n }\r\n \r\n throw new Error(`Failed to load messages for language: ${language}`);\r\n }\r\n }\r\n \r\n /**\r\n * \uC5B8\uC5B4 \uB370\uC774\uD130\uB97C \uCE90\uC2DC\uC5D0\uC11C \uAC00\uC838\uC624\uAE30\r\n */\r\n getDataFromCache(language) {\r\n try {\r\n const cacheKey = `${this.config.dataCacheKey}_${language}_${this.config.cacheVersion}`;\r\n const cachedItem = localStorage.getItem(cacheKey);\r\n \r\n if (cachedItem) {\r\n const { data, timestamp, version } = JSON.parse(cachedItem);\r\n \r\n // \uBC84\uC804 \uD655\uC778\r\n if (version !== this.config.cacheVersion) {\r\n this.log('debug', 'Cache version mismatch, clearing:', language);\r\n localStorage.removeItem(cacheKey);\r\n return null;\r\n }\r\n \r\n // TTL \uD655\uC778 (24\uC2DC\uAC04)\r\n const now = Date.now();\r\n const maxAge = 24 * 60 * 60 * 1000; // 24\uC2DC\uAC04\r\n \r\n if (now - timestamp > maxAge) {\r\n this.log('debug', 'Cache expired, removing:', language);\r\n localStorage.removeItem(cacheKey);\r\n return null;\r\n }\r\n \r\n return data;\r\n }\r\n } catch (error) {\r\n this.log('warn', 'Failed to read from cache:', error);\r\n }\r\n \r\n return null;\r\n }\r\n \r\n /**\r\n * \uC5B8\uC5B4 \uB370\uC774\uD130\uB97C \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n */\r\n saveDataToCache(language, data) {\r\n try {\r\n const cacheKey = `${this.config.dataCacheKey}_${language}_${this.config.cacheVersion}`;\r\n const cacheItem = {\r\n data,\r\n timestamp: Date.now(),\r\n version: this.config.cacheVersion\r\n };\r\n \r\n localStorage.setItem(cacheKey, JSON.stringify(cacheItem));\r\n this.log('debug', 'Data saved to cache:', language);\r\n } catch (error) {\r\n this.log('warn', 'Failed to save to cache:', error);\r\n }\r\n }\r\n\r\n /**\r\n * \uBA54\uC2DC\uC9C0 \uBC88\uC5ED\r\n */\r\n t(key, params = {}) {\r\n // i18n\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uD0A4 \uC790\uCCB4\uB97C \uBC18\uD658\r\n if (!this.config.enabled) {\r\n return key;\r\n }\r\n \r\n const messages = this.messages.get(this.currentLanguage);\r\n if (!messages) {\r\n this.log('warn', 'No messages loaded for current language:', this.currentLanguage);\r\n return key;\r\n }\r\n\r\n const message = this.getNestedValue(messages, key);\r\n if (message === undefined) {\r\n this.log('warn', 'Translation not found for key:', key);\r\n \r\n // \uD3F4\uBC31 \uC5B8\uC5B4\uC5D0\uC11C \uCC3E\uAE30\r\n const fallbackMessages = this.messages.get(this.config.fallbackLanguage);\r\n if (fallbackMessages && this.currentLanguage !== this.config.fallbackLanguage) {\r\n const fallbackMessage = this.getNestedValue(fallbackMessages, key);\r\n if (fallbackMessage !== undefined) {\r\n return this.interpolate(fallbackMessage, params);\r\n }\r\n }\r\n \r\n return key;\r\n }\r\n\r\n return this.interpolate(message, params);\r\n }\r\n\r\n /**\r\n * \uC911\uCCA9\uB41C \uAC1D\uCCB4\uC5D0\uC11C \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getNestedValue(obj, path) {\r\n return path.split('.').reduce((current, key) => {\r\n return current && current[key] !== undefined ? current[key] : undefined;\r\n }, obj);\r\n }\r\n\r\n /**\r\n * \uBB38\uC790\uC5F4 \uBCF4\uAC04 \uCC98\uB9AC\r\n */\r\n interpolate(message, params) {\r\n if (typeof message !== 'string') {\r\n return message;\r\n }\r\n\r\n return message.replace(/\\{(\\w+)\\}/g, (match, key) => {\r\n return params.hasOwnProperty(key) ? params[key] : match;\r\n });\r\n }\r\n\r\n /**\r\n * \uBCF5\uC218\uD615 \uCC98\uB9AC\r\n */\r\n plural(key, count, params = {}) {\r\n const pluralKey = count === 1 ? `${key}.singular` : `${key}.plural`;\r\n return this.t(pluralKey, { ...params, count });\r\n }\r\n\r\n /**\r\n * \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC5B8\uC5B4 \uBAA9\uB85D\r\n */\r\n getAvailableLanguages() {\r\n return ['ko', 'en']; // \uCD94\uD6C4 \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\uD558\uB3C4\uB85D \uBCC0\uACBD \uAC00\uB2A5\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D\r\n */\r\n on(event, callback) {\r\n if (this.listeners[event]) {\r\n this.listeners[event].push(callback);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n */\r\n off(event, callback) {\r\n if (this.listeners[event]) {\r\n const index = this.listeners[event].indexOf(callback);\r\n if (index > -1) {\r\n this.listeners[event].splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n */\r\n emit(event, data) {\r\n if (this.listeners[event]) {\r\n this.listeners[event].forEach(callback => {\r\n try {\r\n callback(data);\r\n } catch (error) {\r\n this.log('error', 'Error in event listener:', error);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC5B8\uC5B4\uC758 \uBAA8\uB4E0 \uBA54\uC2DC\uC9C0 \uBC18\uD658\r\n */\r\n getMessages() {\r\n return this.messages.get(this.currentLanguage) || {};\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uBCC4 \uB0A0\uC9DC \uD3EC\uB9F7\uD305\r\n */\r\n formatDate(date, options = {}) {\r\n const locale = this.currentLanguage === 'ko' ? 'ko-KR' : 'en-US';\r\n return new Intl.DateTimeFormat(locale, options).format(new Date(date));\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uBCC4 \uC22B\uC790 \uD3EC\uB9F7\uD305\r\n */\r\n formatNumber(number, options = {}) {\r\n const locale = this.currentLanguage === 'ko' ? 'ko-KR' : 'en-US';\r\n return new Intl.NumberFormat(locale, options).format(number);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'I18nManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * i18n \uD65C\uC131\uD654 \uC5EC\uBD80 \uD655\uC778\r\n */\r\n isEnabled() {\r\n return this.config.enabled;\r\n }\r\n \r\n /**\r\n * \uCD08\uAE30 \uB85C\uB529\uC774 \uC644\uB8CC\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n */\r\n async isReady() {\r\n if (!this.config.enabled) {\r\n return true;\r\n }\r\n \r\n try {\r\n await this.initPromise;\r\n return true;\r\n } catch (error) {\r\n this.log('error', 'I18n initialization failed:', error);\r\n return false;\r\n }\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uCD08\uAE30\uD654 (\uBC84\uC804 \uBCC0\uACBD \uC2DC \uC0AC\uC6A9)\r\n */\r\n clearCache() {\r\n try {\r\n const keys = Object.keys(localStorage);\r\n const cacheKeys = keys.filter(key => key.startsWith(this.config.dataCacheKey));\r\n \r\n cacheKeys.forEach(key => {\r\n localStorage.removeItem(key);\r\n });\r\n \r\n this.log('debug', 'Cache cleared, removed', cacheKeys.length, 'items');\r\n } catch (error) {\r\n this.log('warn', 'Failed to clear cache:', error);\r\n }\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uC0C1\uD0DC \uD655\uC778\r\n */\r\n getCacheInfo() {\r\n const info = {\r\n enabled: this.config.enableDataCache,\r\n version: this.config.cacheVersion,\r\n languages: {}\r\n };\r\n \r\n try {\r\n const keys = Object.keys(localStorage);\r\n const cacheKeys = keys.filter(key => key.startsWith(this.config.dataCacheKey));\r\n \r\n cacheKeys.forEach(key => {\r\n const match = key.match(new RegExp(`${this.config.dataCacheKey}_(\\w+)_(.+)`));\r\n if (match) {\r\n const [, language, version] = match;\r\n const cachedItem = JSON.parse(localStorage.getItem(key));\r\n \r\n info.languages[language] = {\r\n version,\r\n timestamp: cachedItem.timestamp,\r\n age: Date.now() - cachedItem.timestamp\r\n };\r\n }\r\n });\r\n } catch (error) {\r\n this.log('warn', 'Failed to get cache info:', error);\r\n }\r\n \r\n return info;\r\n }\r\n \r\n /**\r\n * \uC2DC\uC2A4\uD15C \uCD08\uAE30\uD654 (\uD604\uC7AC \uC5B8\uC5B4\uC758 \uBA54\uC2DC\uC9C0 \uB85C\uB4DC)\r\n */\r\n async initialize() {\r\n if (!this.config.enabled) {\r\n this.log('info', 'I18n system is disabled, skipping initialization');\r\n return true;\r\n }\r\n \r\n try {\r\n // \uCD08\uAE30 \uC124\uC815\uC774 \uC644\uB8CC\uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30\r\n await this.initPromise;\r\n this.log('info', 'I18n system fully initialized');\r\n return true;\r\n } catch (error) {\r\n this.log('error', 'Failed to initialize I18n system:', error);\r\n return false;\r\n }\r\n }\r\n}", "/**\r\n * ViewLogic Authentication Management System\r\n * \uC778\uC99D \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class AuthManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enabled: options.authEnabled || false,\r\n loginRoute: options.loginRoute || 'login',\r\n protectedRoutes: options.protectedRoutes || [],\r\n protectedPrefixes: options.protectedPrefixes || [],\r\n publicRoutes: options.publicRoutes || ['login', 'register', 'home'],\r\n checkAuthFunction: options.checkAuthFunction || null,\r\n redirectAfterLogin: options.redirectAfterLogin || 'home',\r\n // \uCFE0\uD0A4/\uC2A4\uD1A0\uB9AC\uC9C0 \uC124\uC815\r\n authCookieName: options.authCookieName || 'authToken',\r\n authFallbackCookieNames: options.authFallbackCookieNames || ['accessToken', 'token', 'jwt'],\r\n authStorage: options.authStorage || 'cookie',\r\n authCookieOptions: options.authCookieOptions || {},\r\n authSkipValidation: options.authSkipValidation || false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC218 \uC758\uC874\uC131)\r\n this.router = router;\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108\uB4E4\r\n this.eventListeners = new Map();\r\n \r\n this.log('info', 'AuthManager initialized', { enabled: this.config.enabled });\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'AuthManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD2B8 \uC778\uC99D \uD655\uC778\r\n */\r\n async checkAuthentication(routeName) {\r\n // \uC778\uC99D \uC2DC\uC2A4\uD15C\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0\r\n if (!this.config.enabled) {\r\n return { allowed: true, reason: 'auth_disabled' };\r\n }\r\n\r\n this.log('debug', `\uD83D\uDD10 Checking authentication for route: ${routeName}`);\r\n\r\n // \uACF5\uAC1C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n if (this.isPublicRoute(routeName)) {\r\n return { allowed: true, reason: 'public_route' };\r\n }\r\n\r\n // \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n const isProtected = this.isProtectedRoute(routeName);\r\n if (!isProtected) {\r\n return { allowed: true, reason: 'not_protected' };\r\n }\r\n\r\n // \uC0AC\uC6A9\uC790 \uC815\uC758 \uC778\uC99D \uCCB4\uD06C \uD568\uC218\uAC00 \uC788\uB294 \uACBD\uC6B0\r\n if (typeof this.config.checkAuthFunction === 'function') {\r\n try {\r\n const isAuthenticated = await this.config.checkAuthFunction(routeName);\r\n return {\r\n allowed: isAuthenticated, \r\n reason: isAuthenticated ? 'custom_auth_success' : 'custom_auth_failed',\r\n routeName\r\n };\r\n } catch (error) {\r\n this.log('error', 'Custom auth function failed:', error);\r\n return { allowed: false, reason: 'custom_auth_error', error };\r\n }\r\n }\r\n\r\n // \uAE30\uBCF8 \uC778\uC99D \uD655\uC778\r\n const isAuthenticated = this.isUserAuthenticated();\r\n return {\r\n allowed: isAuthenticated, \r\n reason: isAuthenticated ? 'authenticated' : 'not_authenticated',\r\n routeName\r\n };\r\n }\r\n\r\n /**\r\n * \uC0AC\uC6A9\uC790 \uC778\uC99D \uC0C1\uD0DC \uD655\uC778\r\n */\r\n isUserAuthenticated() {\r\n this.log('debug', '\uD83D\uDD0D Checking user authentication status');\r\n\r\n // 1. localStorage \uD655\uC778\r\n const token = localStorage.getItem('authToken') || localStorage.getItem('accessToken');\r\n if (token) {\r\n try {\r\n if (token.includes('.')) {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('debug', 'localStorage token expired, removing...');\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n return false;\r\n }\r\n }\r\n this.log('debug', '\u2705 Valid token found in localStorage');\r\n return true;\r\n } catch (error) {\r\n this.log('warn', 'Invalid token in localStorage:', error);\r\n }\r\n }\r\n\r\n // 2. sessionStorage \uD655\uC778\r\n const sessionToken = sessionStorage.getItem('authToken') || sessionStorage.getItem('accessToken');\r\n if (sessionToken) {\r\n this.log('debug', '\u2705 Token found in sessionStorage');\r\n return true;\r\n }\r\n\r\n // 3. \uCFE0\uD0A4 \uD655\uC778\r\n const authCookie = this.getAuthCookie();\r\n if (authCookie) {\r\n try {\r\n if (authCookie.includes('.')) {\r\n const payload = JSON.parse(atob(authCookie.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('debug', 'Cookie token expired, removing...');\r\n this.removeAuthCookie();\r\n return false;\r\n }\r\n }\r\n this.log('debug', '\u2705 Valid token found in cookies');\r\n return true;\r\n } catch (error) {\r\n this.log('warn', 'Cookie token validation failed:', error);\r\n }\r\n }\r\n\r\n // 4. \uC804\uC5ED \uBCC0\uC218 \uD655\uC778 (\uB808\uAC70\uC2DC \uC9C0\uC6D0)\r\n if (window.user || window.isAuthenticated) {\r\n this.log('debug', '\u2705 Global authentication variable found');\r\n return true;\r\n }\r\n\r\n this.log('debug', '\u274C No valid authentication found');\r\n return false;\r\n }\r\n\r\n /**\r\n * \uACF5\uAC1C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n */\r\n isPublicRoute(routeName) {\r\n return this.config.publicRoutes.includes(routeName);\r\n }\r\n\r\n /**\r\n * \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n */\r\n isProtectedRoute(routeName) {\r\n // \uD2B9\uC815 \uB77C\uC6B0\uD2B8\uAC00 \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8 \uBAA9\uB85D\uC5D0 \uC788\uB294\uC9C0 \uD655\uC778\r\n if (this.config.protectedRoutes.includes(routeName)) {\r\n return true;\r\n }\r\n\r\n // prefix\uB85C \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n for (const prefix of this.config.protectedPrefixes) {\r\n if (routeName.startsWith(prefix)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uAC00\uC838\uC624\uAE30\r\n */\r\n getAuthCookie() {\r\n // \uC8FC \uCFE0\uD0A4 \uC774\uB984 \uD655\uC778\r\n const primaryCookie = this.getCookieValue(this.config.authCookieName);\r\n if (primaryCookie) {\r\n return primaryCookie;\r\n }\r\n\r\n // \uB300\uCCB4 \uCFE0\uD0A4 \uC774\uB984\uB4E4 \uD655\uC778\r\n for (const cookieName of this.config.authFallbackCookieNames) {\r\n const cookieValue = this.getCookieValue(cookieName);\r\n if (cookieValue) {\r\n this.log('debug', `Found auth token in fallback cookie: ${cookieName}`);\r\n return cookieValue;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * \uCFE0\uD0A4 \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getCookieValue(name) {\r\n const value = `; ${document.cookie}`;\r\n const parts = value.split(`; ${name}=`);\r\n if (parts.length === 2) {\r\n return decodeURIComponent(parts.pop().split(';').shift());\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uC81C\uAC70\r\n */\r\n removeAuthCookie() {\r\n const cookiesToRemove = [this.config.authCookieName, ...this.config.authFallbackCookieNames];\r\n \r\n cookiesToRemove.forEach(cookieName => {\r\n // \uD604\uC7AC \uACBD\uB85C\uC640 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0\uC11C \uBAA8\uB450 \uC81C\uAC70\r\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\r\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${window.location.pathname};`;\r\n });\r\n \r\n this.log('debug', 'Auth cookies removed');\r\n }\r\n\r\n /**\r\n * \uC561\uC138\uC2A4 \uD1A0\uD070 \uAC00\uC838\uC624\uAE30\r\n */\r\n getAccessToken() {\r\n // localStorage \uD655\uC778\r\n let token = localStorage.getItem('authToken') || localStorage.getItem('accessToken');\r\n if (token) return token;\r\n\r\n // sessionStorage \uD655\uC778\r\n token = sessionStorage.getItem('authToken') || sessionStorage.getItem('accessToken');\r\n if (token) return token;\r\n\r\n // \uCFE0\uD0A4 \uD655\uC778\r\n token = this.getAuthCookie();\r\n if (token) return token;\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * \uC561\uC138\uC2A4 \uD1A0\uD070 \uC124\uC815\r\n */\r\n setAccessToken(token, options = {}) {\r\n if (!token) {\r\n this.log('warn', 'Empty token provided');\r\n return false;\r\n }\r\n\r\n const {\r\n storage = this.config.authStorage,\r\n cookieOptions = this.config.authCookieOptions,\r\n skipValidation = this.config.authSkipValidation\r\n } = options;\r\n\r\n try {\r\n // JWT \uD1A0\uD070 \uAC80\uC99D (\uC635\uC158)\r\n if (!skipValidation && token.includes('.')) {\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('warn', '\u274C Token is expired');\r\n return false;\r\n }\r\n this.log('debug', '\u2705 JWT token validated');\r\n } catch (error) {\r\n this.log('warn', '\u26A0\uFE0F JWT validation failed, but proceeding:', error.message);\r\n }\r\n }\r\n\r\n // \uC2A4\uD1A0\uB9AC\uC9C0\uBCC4 \uC800\uC7A5\r\n switch (storage) {\r\n case 'localStorage':\r\n localStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to localStorage');\r\n break;\r\n\r\n case 'sessionStorage':\r\n sessionStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to sessionStorage');\r\n break;\r\n\r\n case 'cookie':\r\n this.setAuthCookie(token, cookieOptions);\r\n break;\r\n\r\n default:\r\n // \uAE30\uBCF8\uAC12: localStorage\r\n localStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to localStorage (default)');\r\n }\r\n\r\n this.emitAuthEvent('token_set', { \r\n storage,\r\n tokenLength: token.length,\r\n hasExpiration: token.includes('.')\r\n });\r\n\r\n return true;\r\n\r\n } catch (error) {\r\n this.log('Failed to set token:', error);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uC124\uC815\r\n */\r\n setAuthCookie(token, options = {}) {\r\n const {\r\n cookieName = this.config.authCookieName,\r\n secure = window.location.protocol === 'https:',\r\n sameSite = 'Strict',\r\n path = '/',\r\n domain = null\r\n } = options;\r\n\r\n let cookieString = `${cookieName}=${encodeURIComponent(token)}; path=${path}`;\r\n\r\n if (secure) {\r\n cookieString += '; Secure';\r\n }\r\n\r\n if (sameSite) {\r\n cookieString += `; SameSite=${sameSite}`;\r\n }\r\n\r\n if (domain) {\r\n cookieString += `; Domain=${domain}`;\r\n }\r\n\r\n // JWT\uC5D0\uC11C \uB9CC\uB8CC \uC2DC\uAC04 \uCD94\uCD9C\r\n try {\r\n if (token.includes('.')) {\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp) {\r\n const expireDate = new Date(payload.exp * 1000);\r\n cookieString += `; Expires=${expireDate.toUTCString()}`;\r\n }\r\n } catch (error) {\r\n this.log('Could not extract expiration from JWT token');\r\n }\r\n }\r\n } catch (error) {\r\n this.log('Token processing error:', error);\r\n }\r\n\r\n document.cookie = cookieString;\r\n this.log(`Auth cookie set: ${cookieName}`);\r\n }\r\n\r\n /**\r\n * \uD1A0\uD070 \uC81C\uAC70\r\n */\r\n removeAccessToken(storage = 'all') {\r\n switch (storage) {\r\n case 'localStorage':\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n break;\r\n\r\n case 'sessionStorage':\r\n sessionStorage.removeItem('authToken');\r\n sessionStorage.removeItem('accessToken');\r\n break;\r\n\r\n case 'cookie':\r\n this.removeAuthCookie();\r\n break;\r\n\r\n case 'all':\r\n default:\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n sessionStorage.removeItem('authToken');\r\n sessionStorage.removeItem('accessToken');\r\n this.removeAuthCookie();\r\n break;\r\n }\r\n\r\n this.emitAuthEvent('token_removed', { storage });\r\n this.log(`Token removed from: ${storage}`);\r\n }\r\n\r\n /**\r\n * \uB85C\uADF8\uC778 \uC131\uACF5 \uCC98\uB9AC\r\n */\r\n handleLoginSuccess(targetRoute = null) {\r\n const redirectRoute = targetRoute || this.config.redirectAfterLogin;\r\n \r\n this.log(`\uD83C\uDF89 Login success, redirecting to: ${redirectRoute}`);\r\n \r\n this.emitAuthEvent('login_success', { targetRoute: redirectRoute });\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC788\uC73C\uBA74 \uC9C1\uC811 \uB124\uBE44\uAC8C\uC774\uC158\r\n if (this.router && typeof this.router.navigateTo === 'function') {\r\n this.router.navigateTo(redirectRoute);\r\n }\r\n \r\n return redirectRoute;\r\n }\r\n\r\n /**\r\n * \uB85C\uADF8\uC544\uC6C3 \uCC98\uB9AC\r\n */\r\n handleLogout() {\r\n this.log('\uD83D\uDC4B Logging out user');\r\n \r\n // \uBAA8\uB4E0 \uC800\uC7A5\uC18C\uC5D0\uC11C \uD1A0\uD070 \uC81C\uAC70\r\n this.removeAccessToken();\r\n \r\n // \uC804\uC5ED \uBCC0\uC218 \uC815\uB9AC\r\n if (window.user) window.user = null;\r\n if (window.isAuthenticated) window.isAuthenticated = false;\r\n \r\n this.emitAuthEvent('logout', {});\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC788\uC73C\uBA74 \uC9C1\uC811 \uB124\uBE44\uAC8C\uC774\uC158\r\n if (this.router && typeof this.router.navigateTo === 'function') {\r\n this.router.navigateTo(this.config.loginRoute);\r\n }\r\n \r\n return this.config.loginRoute;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n */\r\n emitAuthEvent(eventType, data) {\r\n const event = new CustomEvent('router:auth', {\r\n detail: {\r\n type: eventType,\r\n timestamp: Date.now(),\r\n ...data\r\n }\r\n });\r\n \r\n document.dispatchEvent(event);\r\n \r\n // \uB0B4\uBD80 \uB9AC\uC2A4\uB108\uB4E4\uC5D0\uAC8C\uB3C4 \uC54C\uB9BC\r\n if (this.eventListeners.has(eventType)) {\r\n this.eventListeners.get(eventType).forEach(listener => {\r\n try {\r\n listener(data);\r\n } catch (error) {\r\n this.log('Event listener error:', error);\r\n }\r\n });\r\n }\r\n \r\n this.log(`\uD83D\uDD14 Auth event emitted: ${eventType}`, data);\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D\r\n */\r\n on(eventType, listener) {\r\n if (!this.eventListeners.has(eventType)) {\r\n this.eventListeners.set(eventType, []);\r\n }\r\n this.eventListeners.get(eventType).push(listener);\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n */\r\n off(eventType, listener) {\r\n if (this.eventListeners.has(eventType)) {\r\n const listeners = this.eventListeners.get(eventType);\r\n const index = listeners.indexOf(listener);\r\n if (index > -1) {\r\n listeners.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uC0C1\uD0DC \uD1B5\uACC4\r\n */\r\n getAuthStats() {\r\n return {\r\n enabled: this.config.enabled,\r\n isAuthenticated: this.isUserAuthenticated(),\r\n hasToken: !!this.getAccessToken(),\r\n protectedRoutesCount: this.config.protectedRoutes.length,\r\n protectedPrefixesCount: this.config.protectedPrefixes.length,\r\n publicRoutesCount: this.config.publicRoutes.length,\r\n storage: this.config.authStorage,\r\n loginRoute: this.config.loginRoute\r\n };\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.eventListeners.clear();\r\n this.log('debug', 'AuthManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Cache Management System\r\n * \uCE90\uC2DC \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class CacheManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n cacheMode: options.cacheMode || 'memory', // 'memory' \uB610\uB294 'lru'\r\n cacheTTL: options.cacheTTL || 300000, // 5\uBD84 (\uBC00\uB9AC\uCD08)\r\n maxCacheSize: options.maxCacheSize || 50, // LRU \uCE90\uC2DC \uCD5C\uB300 \uD06C\uAE30\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC694\uC2DC \uB77C\uC6B0\uD130 \uC0C1\uD0DC \uD655\uC778\uC6A9)\r\n this.router = router;\r\n \r\n // \uCE90\uC2DC \uC800\uC7A5\uC18C\uB4E4\r\n this.cache = new Map();\r\n this.cacheTimestamps = new Map();\r\n this.lruOrder = []; // LRU \uC21C\uC11C \uCD94\uC801\r\n \r\n this.log('info', 'CacheManager initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'CacheManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC\uC5D0 \uAC12 \uC800\uC7A5\r\n */\r\n setCache(key, value) {\r\n const now = Date.now();\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n // LRU \uCE90\uC2DC \uAD00\uB9AC\r\n if (this.cache.size >= this.config.maxCacheSize && !this.cache.has(key)) {\r\n const oldestKey = this.lruOrder.shift();\r\n if (oldestKey) {\r\n this.cache.delete(oldestKey);\r\n this.cacheTimestamps.delete(oldestKey);\r\n this.log('debug', `\uD83D\uDDD1\uFE0F LRU evicted cache key: ${oldestKey}`);\r\n }\r\n }\r\n \r\n // \uAE30\uC874 \uD0A4\uAC00 \uC788\uC73C\uBA74 LRU \uC21C\uC11C\uC5D0\uC11C \uC81C\uAC70\r\n const existingIndex = this.lruOrder.indexOf(key);\r\n if (existingIndex > -1) {\r\n this.lruOrder.splice(existingIndex, 1);\r\n }\r\n \r\n // \uCD5C\uC2E0 \uC21C\uC11C\uB85C \uCD94\uAC00\r\n this.lruOrder.push(key);\r\n }\r\n \r\n this.cache.set(key, value);\r\n this.cacheTimestamps.set(key, now);\r\n \r\n this.log('debug', `\uD83D\uDCBE Cached: ${key} (size: ${this.cache.size})`);\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC\uC5D0\uC11C \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getFromCache(key) {\r\n const now = Date.now();\r\n const timestamp = this.cacheTimestamps.get(key);\r\n \r\n // TTL \uCCB4\uD06C\r\n if (timestamp && (now - timestamp) > this.config.cacheTTL) {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n \r\n this.log('debug', `\u23F0 Cache expired and removed: ${key}`);\r\n return null;\r\n }\r\n \r\n const value = this.cache.get(key);\r\n \r\n if (value && this.config.cacheMode === 'lru') {\r\n // LRU \uC21C\uC11C \uC5C5\uB370\uC774\uD2B8\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n this.lruOrder.push(key);\r\n }\r\n }\r\n \r\n if (value) {\r\n this.log('debug', `\uD83C\uDFAF Cache hit: ${key}`);\r\n } else {\r\n this.log('debug', `\u274C Cache miss: ${key}`);\r\n }\r\n \r\n return value;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC\uC5D0 \uD0A4\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n */\r\n hasCache(key) {\r\n return this.cache.has(key) && this.getFromCache(key) !== null;\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uD0A4 \uD328\uD134\uC758 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n invalidateByPattern(pattern) {\r\n const keysToDelete = [];\r\n \r\n for (const key of this.cache.keys()) {\r\n if (key.includes(pattern) || key.startsWith(pattern)) {\r\n keysToDelete.push(key);\r\n }\r\n }\r\n \r\n keysToDelete.forEach(key => {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n });\r\n \r\n this.log('debug', `\uD83E\uDDF9 Invalidated ${keysToDelete.length} cache entries matching: ${pattern}`);\r\n return keysToDelete.length;\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uCEF4\uD3EC\uB10C\uD2B8 \uCE90\uC2DC \uBB34\uD6A8\uD654\r\n */\r\n invalidateComponentCache(routeName) {\r\n const patterns = [\r\n `component_${routeName}`,\r\n `script_${routeName}`,\r\n `template_${routeName}`,\r\n `style_${routeName}`,\r\n `layout_${routeName}`\r\n ];\r\n \r\n let totalInvalidated = 0;\r\n patterns.forEach(pattern => {\r\n totalInvalidated += this.invalidateByPattern(pattern);\r\n });\r\n \r\n this.log(`\uD83D\uDD04 Invalidated component cache for route: ${routeName} (${totalInvalidated} entries)`);\r\n return totalInvalidated;\r\n }\r\n \r\n /**\r\n * \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n clearComponentCache() {\r\n const componentPatterns = ['component_', 'script_', 'template_', 'style_', 'layout_'];\r\n let totalCleared = 0;\r\n \r\n componentPatterns.forEach(pattern => {\r\n totalCleared += this.invalidateByPattern(pattern);\r\n });\r\n \r\n this.log(`\uD83E\uDDFD Cleared all component caches (${totalCleared} entries)`);\r\n return totalCleared;\r\n }\r\n \r\n /**\r\n * \uC804\uCCB4 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n clearCache() {\r\n const size = this.cache.size;\r\n this.cache.clear();\r\n this.cacheTimestamps.clear();\r\n this.lruOrder = [];\r\n \r\n this.log(`\uD83D\uDD25 Cleared all cache (${size} entries)`);\r\n }\r\n \r\n /**\r\n * \uB9CC\uB8CC\uB41C \uCE90\uC2DC \uD56D\uBAA9\uB4E4 \uC815\uB9AC\r\n */\r\n cleanExpiredCache() {\r\n const now = Date.now();\r\n const expiredKeys = [];\r\n \r\n for (const [key, timestamp] of this.cacheTimestamps.entries()) {\r\n if ((now - timestamp) > this.config.cacheTTL) {\r\n expiredKeys.push(key);\r\n }\r\n }\r\n \r\n expiredKeys.forEach(key => {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n });\r\n \r\n if (expiredKeys.length > 0) {\r\n this.log(`\u23F1\uFE0F Cleaned ${expiredKeys.length} expired cache entries`);\r\n }\r\n \r\n return expiredKeys.length;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uD1B5\uACC4 \uC815\uBCF4\r\n */\r\n getCacheStats() {\r\n return {\r\n size: this.cache.size,\r\n maxSize: this.config.maxCacheSize,\r\n mode: this.config.cacheMode,\r\n ttl: this.config.cacheTTL,\r\n memoryUsage: this.getMemoryUsage(),\r\n hitRatio: this.getHitRatio(),\r\n categories: this.getCategorizedStats()\r\n };\r\n }\r\n \r\n /**\r\n * \uBA54\uBAA8\uB9AC \uC0AC\uC6A9\uB7C9 \uCD94\uC815\r\n */\r\n getMemoryUsage() {\r\n let estimatedBytes = 0;\r\n \r\n for (const [key, value] of this.cache.entries()) {\r\n // \uD0A4 \uD06C\uAE30\r\n estimatedBytes += key.length * 2; // UTF-16\r\n \r\n // \uAC12 \uD06C\uAE30 \uCD94\uC815\r\n if (typeof value === 'string') {\r\n estimatedBytes += value.length * 2;\r\n } else if (typeof value === 'object' && value !== null) {\r\n estimatedBytes += JSON.stringify(value).length * 2;\r\n } else {\r\n estimatedBytes += 8; // \uB300\uB7B5\uC801\uC778 \uD06C\uAE30\r\n }\r\n }\r\n \r\n return {\r\n bytes: estimatedBytes,\r\n kb: Math.round(estimatedBytes / 1024 * 100) / 100,\r\n mb: Math.round(estimatedBytes / (1024 * 1024) * 100) / 100\r\n };\r\n }\r\n \r\n /**\r\n * \uD788\uD2B8 \uBE44\uC728 \uACC4\uC0B0 (\uAC04\uB2E8\uD55C \uCD94\uC815)\r\n */\r\n getHitRatio() {\r\n // \uC2E4\uC81C \uD788\uD2B8/\uBBF8\uC2A4 \uCD94\uC801\uC744 \uC704\uD574\uC11C\uB294 \uBCC4\uB3C4\uC758 \uCE74\uC6B4\uD130\uAC00 \uD544\uC694\r\n // \uD604\uC7AC\uB294 \uCE90\uC2DC \uD06C\uAE30 \uAE30\uBC18 \uCD94\uC815\uCE58 \uBC18\uD658\r\n const ratio = this.cache.size > 0 ? Math.min(this.cache.size / this.config.maxCacheSize, 1) : 0;\r\n return Math.round(ratio * 100);\r\n }\r\n \r\n /**\r\n * \uCE74\uD14C\uACE0\uB9AC\uBCC4 \uCE90\uC2DC \uD1B5\uACC4\r\n */\r\n getCategorizedStats() {\r\n const categories = {\r\n components: 0,\r\n scripts: 0,\r\n templates: 0,\r\n styles: 0,\r\n layouts: 0,\r\n others: 0\r\n };\r\n \r\n for (const key of this.cache.keys()) {\r\n if (key.startsWith('component_')) categories.components++;\r\n else if (key.startsWith('script_')) categories.scripts++;\r\n else if (key.startsWith('template_')) categories.templates++;\r\n else if (key.startsWith('style_')) categories.styles++;\r\n else if (key.startsWith('layout_')) categories.layouts++;\r\n else categories.others++;\r\n }\r\n \r\n return categories;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uD0A4 \uBAA9\uB85D \uBC18\uD658\r\n */\r\n getCacheKeys() {\r\n return Array.from(this.cache.keys());\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uD328\uD134\uC758 \uCE90\uC2DC \uD0A4\uB4E4 \uBC18\uD658\r\n */\r\n getCacheKeysByPattern(pattern) {\r\n return this.getCacheKeys().filter(key => \r\n key.includes(pattern) || key.startsWith(pattern)\r\n );\r\n }\r\n \r\n /**\r\n * \uC790\uB3D9 \uC815\uB9AC \uC2DC\uC791 (\uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C \uB9CC\uB8CC\uB41C \uCE90\uC2DC \uC815\uB9AC)\r\n */\r\n startAutoCleanup(interval = 60000) { // \uAE30\uBCF8 1\uBD84 \uAC04\uACA9\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n }\r\n \r\n this.cleanupInterval = setInterval(() => {\r\n this.cleanExpiredCache();\r\n }, interval);\r\n \r\n this.log(`\uD83E\uDD16 Auto cleanup started (interval: ${interval}ms)`);\r\n }\r\n \r\n /**\r\n * \uC790\uB3D9 \uC815\uB9AC \uC911\uC9C0\r\n */\r\n stopAutoCleanup() {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n this.log('debug', '\uD83D\uDED1 Auto cleanup stopped');\r\n }\r\n }\r\n \r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.stopAutoCleanup();\r\n this.clearCache();\r\n this.log('debug', 'CacheManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Query Management System\r\n * URL \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class QueryManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enableParameterValidation: options.enableParameterValidation !== false,\r\n logSecurityWarnings: options.logSecurityWarnings !== false,\r\n maxParameterLength: options.maxParameterLength || 1000,\r\n maxArraySize: options.maxArraySize || 100,\r\n maxParameterCount: options.maxParameterCount || 50,\r\n allowedKeyPattern: options.allowedKeyPattern || /^[a-zA-Z0-9_\\-]+$/,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n \r\n // \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC0C1\uD0DC\r\n this.currentQueryParams = {};\r\n \r\n // \uD604\uC7AC \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC0C1\uD0DC (navigateTo\uB85C \uC804\uB2EC\uB41C params)\r\n this.currentRouteParams = {};\r\n \r\n this.log('info', 'QueryManager initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'QueryManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uD30C\uB77C\uBBF8\uD130 \uAC12 sanitize (XSS, SQL Injection \uBC29\uC5B4)\r\n */\r\n sanitizeParameter(value) {\r\n if (typeof value !== 'string') return value;\r\n \r\n // XSS \uBC29\uC5B4: HTML \uD0DC\uADF8\uC640 \uC2A4\uD06C\uB9BD\uD2B8 \uC81C\uAC70\r\n let sanitized = value\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '') // script \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '') // iframe \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<object\\b[^<]*(?:(?!<\\/object>)<[^<]*)*<\\/object>/gi, '') // object \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<embed\\b[^<]*(?:(?!<\\/embed>)<[^<]*)*<\\/embed>/gi, '') // embed \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<link\\b[^<]*>/gi, '') // link \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<meta\\b[^<]*>/gi, '') // meta \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/javascript:/gi, '') // javascript: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/vbscript:/gi, '') // vbscript: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/data:/gi, '') // data: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/on\\w+\\s*=/gi, '') // \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uC81C\uAC70 (onclick, onload \uB4F1)\r\n .replace(/expression\\s*\\(/gi, '') // CSS expression \uC81C\uAC70\r\n .replace(/url\\s*\\(/gi, ''); // CSS url() \uC81C\uAC70\r\n \r\n // SQL Injection \uBC29\uC5B4: \uC704\uD5D8\uD55C SQL \uD0A4\uC6CC\uB4DC \uD544\uD130\uB9C1\r\n const sqlPatterns = [\r\n /(\\b(union|select|insert|update|delete|drop|create|alter|exec|execute|sp_|xp_)\\b)/gi,\r\n /(;|\\||&|\\*|%|<|>)/g, // \uC704\uD5D8\uD55C \uD2B9\uC218\uBB38\uC790\r\n /(--|\\/\\*|\\*\\/)/g, // SQL \uC8FC\uC11D\r\n /(\\bor\\b.*\\b=\\b|\\band\\b.*\\b=\\b)/gi, // OR/AND \uC870\uAC74\uBB38\r\n /('.*'|\".*\")/g, // \uB530\uC634\uD45C\uB85C \uB458\uB7EC\uC2F8\uC778 \uBB38\uC790\uC5F4\r\n /(\\\\\\w+)/g // \uBC31\uC2AC\uB798\uC2DC \uC774\uC2A4\uCF00\uC774\uD504\r\n ];\r\n \r\n for (const pattern of sqlPatterns) {\r\n sanitized = sanitized.replace(pattern, '');\r\n }\r\n \r\n // \uCD94\uAC00 \uBCF4\uC548: \uC5F0\uC18D\uB41C \uD2B9\uC218\uBB38\uC790 \uC81C\uAC70\r\n sanitized = sanitized.replace(/[<>'\"&]{2,}/g, '');\r\n \r\n // \uAE38\uC774 \uC81C\uD55C (DoS \uBC29\uC5B4)\r\n if (sanitized.length > this.config.maxParameterLength) {\r\n sanitized = sanitized.substring(0, this.config.maxParameterLength);\r\n }\r\n \r\n return sanitized.trim();\r\n }\r\n\r\n /**\r\n * \uD30C\uB77C\uBBF8\uD130 \uC720\uD6A8\uC131 \uAC80\uC99D\r\n */\r\n validateParameter(key, value) {\r\n // \uBCF4\uC548 \uAC80\uC99D\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uD1B5\uACFC\r\n if (!this.config.enableParameterValidation) {\r\n return true;\r\n }\r\n \r\n // \uD30C\uB77C\uBBF8\uD130 \uD0A4 \uAC80\uC99D\r\n if (typeof key !== 'string' || key.length === 0) {\r\n return false;\r\n }\r\n \r\n // \uD0A4 \uC774\uB984 \uC81C\uD55C\r\n if (!this.config.allowedKeyPattern.test(key)) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Invalid parameter key format: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uD0A4 \uAE38\uC774 \uC81C\uD55C\r\n if (key.length > 50) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter key too long: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uAC12 \uD0C0\uC785 \uAC80\uC99D\r\n if (value !== null && value !== undefined) {\r\n if (typeof value === 'string') {\r\n // \uBB38\uC790\uC5F4 \uAE38\uC774 \uC81C\uD55C\r\n if (value.length > this.config.maxParameterLength) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter value too long for key: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uC704\uD5D8\uD55C \uD328\uD134 \uAC10\uC9C0\r\n const dangerousPatterns = [\r\n /<script|<iframe|<object|<embed/gi,\r\n /javascript:|vbscript:|data:/gi,\r\n /union.*select|insert.*into|delete.*from/gi,\r\n /\\.\\.\\//g, // \uACBD\uB85C \uD0D0\uC0C9 \uACF5\uACA9\r\n /[<>'\"&]{3,}/g // \uC5F0\uC18D\uB41C \uD2B9\uC218\uBB38\uC790\r\n ];\r\n \r\n for (const pattern of dangerousPatterns) {\r\n if (pattern.test(value)) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Dangerous pattern detected in parameter ${key}:`, value);\r\n }\r\n return false;\r\n }\r\n }\r\n } else if (Array.isArray(value)) {\r\n // \uBC30\uC5F4 \uAE38\uC774 \uC81C\uD55C\r\n if (value.length > this.config.maxArraySize) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter array too large for key: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uBC30\uC5F4 \uAC01 \uC694\uC18C \uAC80\uC99D\r\n for (const item of value) {\r\n if (!this.validateParameter(`${key}[]`, item)) {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC\uC2A4\uD2B8\uB9C1 \uD30C\uC2F1\r\n */\r\n parseQueryString(queryString) {\r\n const params = {};\r\n if (!queryString) return params;\r\n \r\n const pairs = queryString.split('&');\r\n for (const pair of pairs) {\r\n try {\r\n const [rawKey, rawValue] = pair.split('=');\r\n if (!rawKey) continue;\r\n \r\n let key, value;\r\n try {\r\n key = decodeURIComponent(rawKey);\r\n value = rawValue ? decodeURIComponent(rawValue) : '';\r\n } catch (e) {\r\n this.log('warn', 'Failed to decode URI component:', pair);\r\n continue;\r\n }\r\n \r\n // \uBCF4\uC548 \uAC80\uC99D\r\n if (!this.validateParameter(key, value)) {\r\n this.log('warn', `Parameter rejected by security filter: ${key}`);\r\n continue;\r\n }\r\n \r\n // \uAC12 sanitize\r\n const sanitizedValue = this.sanitizeParameter(value);\r\n \r\n // \uBC30\uC5F4 \uD615\uD0DC\uC758 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC (\uC608: tags[]=a&tags[]=b)\r\n if (key.endsWith('[]')) {\r\n const arrayKey = key.slice(0, -2);\r\n \r\n // \uBC30\uC5F4 \uD0A4\uB3C4 \uAC80\uC99D\r\n if (!this.validateParameter(arrayKey, [])) {\r\n continue;\r\n }\r\n \r\n if (!params[arrayKey]) params[arrayKey] = [];\r\n \r\n // \uBC30\uC5F4 \uD06C\uAE30 \uC81C\uD55C\r\n if (params[arrayKey].length < this.config.maxArraySize) {\r\n params[arrayKey].push(sanitizedValue);\r\n } else {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Array parameter ${arrayKey} size limit exceeded`);\r\n }\r\n }\r\n } else {\r\n params[key] = sanitizedValue;\r\n }\r\n } catch (error) {\r\n this.log('error', 'Error parsing query parameter:', pair, error);\r\n }\r\n }\r\n \r\n // \uC804\uCCB4 \uD30C\uB77C\uBBF8\uD130 \uAC1C\uC218 \uC81C\uD55C\r\n const paramCount = Object.keys(params).length;\r\n if (paramCount > this.config.maxParameterCount) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Too many parameters (${paramCount}). Limiting to first ${this.config.maxParameterCount}.`);\r\n }\r\n const limitedParams = {};\r\n let count = 0;\r\n for (const [key, value] of Object.entries(params)) {\r\n if (count >= this.config.maxParameterCount) break;\r\n limitedParams[key] = value;\r\n count++;\r\n }\r\n return limitedParams;\r\n }\r\n \r\n return params;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC\uC2A4\uD2B8\uB9C1 \uC0DD\uC131\r\n */\r\n buildQueryString(params) {\r\n if (!params || Object.keys(params).length === 0) return '';\r\n \r\n const pairs = [];\r\n for (const [key, value] of Object.entries(params)) {\r\n if (Array.isArray(value)) {\r\n // \uBC30\uC5F4 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC\r\n for (const item of value) {\r\n pairs.push(`${encodeURIComponent(key)}[]=${encodeURIComponent(item)}`);\r\n }\r\n } else if (value !== undefined && value !== null) {\r\n pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\r\n }\r\n }\r\n return pairs.join('&');\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uBCC0\uACBD \uAC10\uC9C0\r\n */\r\n hasQueryParamsChanged(newParams) {\r\n if (!this.currentQueryParams && !newParams) return false;\r\n if (!this.currentQueryParams || !newParams) return true;\r\n \r\n const oldKeys = Object.keys(this.currentQueryParams);\r\n const newKeys = Object.keys(newParams);\r\n \r\n if (oldKeys.length !== newKeys.length) return true;\r\n \r\n for (const key of oldKeys) {\r\n if (JSON.stringify(this.currentQueryParams[key]) !== JSON.stringify(newParams[key])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC804\uCCB4 \uAC00\uC838\uC624\uAE30\r\n */\r\n getQueryParams() {\r\n return { ...this.currentQueryParams };\r\n }\r\n\r\n /**\r\n * \uD2B9\uC815 \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uAC00\uC838\uC624\uAE30\r\n */\r\n getQueryParam(key, defaultValue = undefined) {\r\n const value = this.currentQueryParams ? this.currentQueryParams[key] : undefined;\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC124\uC815\r\n */\r\n setQueryParams(params, replace = false) {\r\n if (!params || typeof params !== 'object') {\r\n console.warn('Invalid parameters object provided to setQueryParams');\r\n return;\r\n }\r\n \r\n const currentParams = replace ? {} : { ...this.currentQueryParams };\r\n const sanitizedParams = {};\r\n \r\n // \uD30C\uB77C\uBBF8\uD130 \uAC80\uC99D \uBC0F sanitize\r\n for (const [key, value] of Object.entries(params)) {\r\n // \uD0A4\uC640 \uAC12 \uAC80\uC99D\r\n if (!this.validateParameter(key, value)) {\r\n console.warn(`Parameter ${key} rejected by security filter`);\r\n continue;\r\n }\r\n \r\n // \uAC12 \uCC98\uB9AC\r\n if (value !== undefined && value !== null) {\r\n if (Array.isArray(value)) {\r\n sanitizedParams[key] = value.map(item => this.sanitizeParameter(item));\r\n } else {\r\n sanitizedParams[key] = this.sanitizeParameter(value);\r\n }\r\n }\r\n }\r\n \r\n // \uD604\uC7AC \uD30C\uB77C\uBBF8\uD130 \uC5C5\uB370\uC774\uD2B8\r\n Object.assign(currentParams, sanitizedParams);\r\n \r\n // undefined\uB098 null \uAC12 \uC81C\uAC70\r\n for (const [key, value] of Object.entries(currentParams)) {\r\n if (value === undefined || value === null || value === '') {\r\n delete currentParams[key];\r\n }\r\n }\r\n \r\n // \uCD5C\uB300 \uD30C\uB77C\uBBF8\uD130 \uAC1C\uC218 \uD655\uC778\r\n const paramCount = Object.keys(currentParams).length;\r\n if (paramCount > this.config.maxParameterCount) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Too many parameters after update (${paramCount}). Some parameters may be dropped.`);\r\n }\r\n }\r\n \r\n this.currentQueryParams = currentParams;\r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC81C\uAC70\r\n */\r\n removeQueryParams(keys) {\r\n if (!keys) return;\r\n \r\n const keysToRemove = Array.isArray(keys) ? keys : [keys];\r\n for (const key of keysToRemove) {\r\n delete this.currentQueryParams[key];\r\n }\r\n \r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uCD08\uAE30\uD654\r\n */\r\n clearQueryParams() {\r\n this.currentQueryParams = {};\r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC124\uC815 (\uB77C\uC6B0\uD130\uC5D0\uC11C \uD638\uCD9C)\r\n */\r\n setCurrentQueryParams(params) {\r\n this.currentQueryParams = params || {};\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC124\uC815 (navigateTo\uC5D0\uC11C \uD638\uCD9C)\r\n */\r\n setCurrentRouteParams(params) {\r\n this.currentRouteParams = params || {};\r\n this.log('debug', 'Route params set:', this.currentRouteParams);\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uBC18\uD658 (\uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n */\r\n getAllParams() {\r\n return {\r\n ...this.currentRouteParams,\r\n ...this.currentQueryParams\r\n };\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uD2B9\uC815 \uD0A4 \uAC12 \uBC18\uD658\r\n */\r\n getParam(key, defaultValue = undefined) {\r\n // \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130\uAC00 \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uBCF4\uB2E4 \uC6B0\uC120\uC21C\uC704 \uB192\uC74C\r\n const value = this.currentQueryParams[key] !== undefined ? \r\n this.currentQueryParams[key] : \r\n this.currentRouteParams[key];\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uB9CC \uBC18\uD658\r\n */\r\n getRouteParams() {\r\n return { ...this.currentRouteParams };\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uD2B9\uC815 \uD0A4 \uAC12 \uBC18\uD658\r\n */\r\n getRouteParam(key, defaultValue = undefined) {\r\n const value = this.currentRouteParams[key];\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * URL \uC5C5\uB370\uC774\uD2B8 (\uB77C\uC6B0\uD130\uC758 updateURL \uBA54\uC18C\uB4DC \uD638\uCD9C)\r\n */\r\n updateURL() {\r\n if (this.router && typeof this.router.updateURL === 'function') {\r\n const route = this.router.currentHash || 'home';\r\n this.router.updateURL(route, this.currentQueryParams);\r\n }\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uD1B5\uACC4\r\n */\r\n getStats() {\r\n return {\r\n currentParams: Object.keys(this.currentQueryParams).length,\r\n maxAllowed: this.config.maxParameterCount,\r\n validationEnabled: this.config.enableParameterValidation,\r\n currentQueryString: this.buildQueryString(this.currentQueryParams)\r\n };\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.currentQueryParams = {};\r\n this.currentRouteParams = {};\r\n this.router = null;\r\n this.log('debug', 'QueryManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Route Loading System\r\n * \uB77C\uC6B0\uD2B8 \uB85C\uB529 \uBC0F \uCEF4\uD3EC\uB10C\uD2B8 \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class RouteLoader {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n basePath: options.basePath || '/src',\r\n routesPath: options.routesPath || '/routes',\r\n environment: options.environment || 'development',\r\n useLayout: options.useLayout !== false,\r\n defaultLayout: options.defaultLayout || 'default',\r\n useComponents: options.useComponents !== false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n this.log('debug', 'RouteLoader initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uC2A4\uD06C\uB9BD\uD2B8 \uD30C\uC77C \uB85C\uB4DC\r\n */\r\n async loadScript(routeName) {\r\n let script;\r\n try {\r\n if (this.config.environment === 'production') {\r\n // \uD504\uB85C\uB355\uC158 \uBAA8\uB4DC: routes \uD3F4\uB354\uC5D0\uC11C \uBE4C\uB4DC\uB41C JS \uB85C\uB4DC (\uC808\uB300 \uACBD\uB85C)\r\n const importPath = `${this.config.routesPath}/${routeName}.js`;\r\n this.log('debug', `Loading production route: ${importPath}`);\r\n const module = await import(importPath);\r\n script = module.default;\r\n } else {\r\n // \uAC1C\uBC1C \uBAA8\uB4DC: basePath\uB294 \uC774\uBBF8 origin\uC774 \uD3EC\uD568\uB418\uC5B4 \uC788\uC74C\r\n const importPath = `${this.config.basePath}/logic/${routeName}.js`;\r\n this.log('debug', `Loading development route: ${importPath}`);\r\n const module = await import(importPath);\r\n script = module.default;\r\n }\r\n \r\n if (!script) {\r\n throw new Error(`Route '${routeName}' not found - no default export`);\r\n }\r\n \r\n } catch (error) {\r\n // import \uC5D0\uB7EC\uB97C 404\uB85C \uBD84\uB958\r\n if (error.message.includes('Failed to resolve') || \r\n error.message.includes('Failed to fetch') ||\r\n error.message.includes('not found') ||\r\n error.name === 'TypeError') {\r\n throw new Error(`Route '${routeName}' not found - 404`);\r\n }\r\n // \uB2E4\uB978 \uC5D0\uB7EC\uB294 \uADF8\uB300\uB85C \uC804\uD30C\r\n throw error;\r\n }\r\n \r\n return script;\r\n }\r\n\r\n /**\r\n * \uD15C\uD50C\uB9BF \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC \uAE30\uBCF8\uAC12 \uBC18\uD658)\r\n */\r\n async loadTemplate(routeName) {\r\n try {\r\n const templatePath = `${this.config.basePath}/views/${routeName}.html`;\r\n const response = await fetch(templatePath);\r\n if (!response.ok) throw new Error(`Template not found: ${response.status}`);\r\n const template = await response.text();\r\n this.log('debug', `Template '${routeName}' loaded successfully`);\r\n return template;\r\n } catch (error) {\r\n this.log('warn', `Template '${routeName}' not found, using default:`, error.message);\r\n // \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uBC18\uD658\r\n return this.generateDefaultTemplate(routeName);\r\n }\r\n }\r\n\r\n /**\r\n * \uC2A4\uD0C0\uC77C \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC \uBE48 \uBB38\uC790\uC5F4 \uBC18\uD658)\r\n */\r\n async loadStyle(routeName) {\r\n try {\r\n const stylePath = `${this.config.basePath}/styles/${routeName}.css`;\r\n const response = await fetch(stylePath);\r\n if (!response.ok) throw new Error(`Style not found: ${response.status}`);\r\n const style = await response.text();\r\n this.log('debug', `Style '${routeName}' loaded successfully`);\r\n return style;\r\n } catch (error) {\r\n this.log('debug', `Style '${routeName}' not found, no styles applied:`, error.message);\r\n // \uC2A4\uD0C0\uC77C\uC774 \uC5C6\uC73C\uBA74 \uBE48 \uBB38\uC790\uC5F4 \uBC18\uD658\r\n return '';\r\n }\r\n }\r\n\r\n /**\r\n * \uB808\uC774\uC544\uC6C3 \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC null \uBC18\uD658)\r\n */\r\n async loadLayout(layoutName) {\r\n try {\r\n const layoutPath = `${this.config.basePath}/layouts/${layoutName}.html`;\r\n const response = await fetch(layoutPath);\r\n if (!response.ok) throw new Error(`Layout not found: ${response.status}`);\r\n const layout = await response.text();\r\n \r\n this.log('debug', `Layout '${layoutName}' loaded successfully`);\r\n return layout;\r\n } catch (error) {\r\n this.log('debug', `Layout '${layoutName}' not found, no layout applied:`, error.message);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * \uB808\uC774\uC544\uC6C3\uACFC \uD15C\uD50C\uB9BF \uBCD1\uD569\r\n */\r\n mergeLayoutWithTemplate(routeName, layout, template) {\r\n let result;\r\n // \uB808\uC774\uC544\uC6C3\uC5D0\uC11C <slot name=\"content\"> \uBD80\uBD84\uC744 \uD15C\uD50C\uB9BF\uC73C\uB85C \uAD50\uCCB4\r\n if (layout.includes('{{ content }}')) {\r\n result = layout.replace(\r\n /{{ content }}/s,\r\n template\r\n );\r\n }\r\n // slot\uC774 \uC5C6\uC73C\uBA74 main-content \uD074\uB798\uC2A4 \uB0B4\uC6A9 \uAD50\uCCB4\r\n else if (layout.includes('class=\"main-content\"')) {\r\n this.log('debug', 'Using main-content replacement');\r\n result = layout.replace(\r\n /(<div class=\"container\">).*?(<\\/div>\\s*<\\/main>)/s,\r\n `$1${template}$2`\r\n );\r\n }\r\n // \uB9C8\uC9C0\uB9C9 \uB300\uC548: \uC804\uCCB4 \uB808\uC774\uC544\uC6C3\uC744 \uD15C\uD50C\uB9BF\uC73C\uB85C \uAC10\uC2F8\uAE30\r\n else {\r\n this.log('debug', 'Wrapping template with layout');\r\n result = `${layout}\\n${template}`;\r\n }\r\n \r\n return result;\r\n }\r\n\r\n\r\n /**\r\n * Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n */\r\n async createVueComponent(routeName) {\r\n // \uCE90\uC2DC\uB41C Vue \uCEF4\uD3EC\uB10C\uD2B8\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n const cacheKey = `component_${routeName}`;\r\n const cached = this.router.cacheManager?.getFromCache(cacheKey);\r\n if (cached) {\r\n return cached;\r\n }\r\n \r\n const script = await this.loadScript(routeName);\r\n const router = this.router;\r\n const isProduction = this.config.environment === 'production';\r\n \r\n // \uD658\uACBD\uBCC4 \uB9AC\uC18C\uC2A4 \uB85C\uB529\r\n let template, style = '', layout = null;\r\n \r\n if (isProduction) {\r\n // \uD504\uB85C\uB355\uC158: \uC2A4\uD06C\uB9BD\uD2B8\uC5D0 \uC788\uB294 \uD15C\uD50C\uB9BF \uC0AC\uC6A9 \uB610\uB294 \uAE30\uBCF8\uAC12\r\n template = script.template || this.generateDefaultTemplate(routeName);\r\n } else {\r\n // \uAC1C\uBC1C: \uAC1C\uBCC4 \uD30C\uC77C\uB4E4 \uB85C\uB4DC\r\n template = await this.loadTemplate(routeName);\r\n style = await this.loadStyle(routeName);\r\n layout = this.config.useLayout && script.layout !== null ? \r\n await this.loadLayout(script.layout || this.config.defaultLayout) : null;\r\n \r\n // \uB808\uC774\uC544\uC6C3\uACFC \uD15C\uD50C\uB9BF \uBCD1\uD569\r\n if (layout) {\r\n template = this.mergeLayoutWithTemplate(routeName, layout, template);\r\n }\r\n }\r\n \r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 (\uC2E4\uD328\uD574\uB3C4 \uB77C\uC6B0\uD130\uB294 \uACC4\uC18D \uC791\uB3D9)\r\n let loadedComponents = {};\r\n if (this.config.useComponents && router.componentLoader) {\r\n try {\r\n loadedComponents = await router.componentLoader.loadAllComponents();\r\n this.log('debug', `Components loaded successfully for route: ${routeName}`);\r\n } catch (error) {\r\n this.log('warn', `Component loading failed for route '${routeName}', continuing without components:`, error.message);\r\n loadedComponents = {}; // \uBE48 \uAC1D\uCCB4\uB85C \uD3F4\uBC31\r\n }\r\n }\r\n\r\n // \uB2E8\uC77C \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n const component = {\r\n ...script,\r\n name: script.name || this.toPascalCase(routeName),\r\n template,\r\n components: loadedComponents,\r\n data() {\r\n const originalData = script.data ? script.data() : {};\r\n const commonData = {\r\n ...originalData,\r\n currentRoute: routeName,\r\n $query: router.queryManager?.getQueryParams() || {},\r\n $lang: router.i18nManager?.getCurrentLanguage() || router.config.i18nDefaultLanguage,\r\n $dataLoading: false\r\n };\r\n \r\n return commonData;\r\n },\r\n computed: {\r\n ...(script.computed || {}),\r\n // \uD558\uC704 \uD638\uD658\uC131\uC744 \uC704\uD574 params\uB294 \uC720\uC9C0\uD558\uB418 getAllParams \uC0AC\uC6A9\r\n params() {\r\n return router.queryManager?.getAllParams() || {};\r\n }\r\n },\r\n async mounted() {\r\n if (script.mounted) {\r\n await script.mounted.call(this);\r\n }\r\n if (script.dataURL) {\r\n if (typeof script.dataURL === 'string') {\r\n // \uAE30\uC874 \uB2E8\uC77C API \uBC29\uC2DD (\uD558\uC704 \uD638\uD658\uC131)\r\n await this.$fetchData();\r\n } else if (typeof script.dataURL === 'object') {\r\n // \uC0C8\uB85C\uC6B4 \uB2E4\uC911 API \uBC29\uC2DD\r\n await this.$fetchMultipleData();\r\n }\r\n }\r\n \r\n // \uD83C\uDD95 \uC790\uB3D9 \uD3FC \uBC14\uC778\uB529\r\n await this.$nextTick(); // DOM\uC774 \uC644\uC804\uD788 \uB80C\uB354\uB9C1\uB41C \uD6C4\r\n this.$bindAutoForms();\r\n },\r\n methods: {\r\n ...script.methods,\r\n // \uB77C\uC6B0\uD305 \uAD00\uB828\r\n navigateTo: (route, params) => router.navigateTo(route, params),\r\n getCurrentRoute: () => router.getCurrentRoute(),\r\n \r\n // \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC (\uB77C\uC6B0\uD305 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n getParams: () => router.queryManager?.getAllParams() || {},\r\n getParam: (key, defaultValue) => router.queryManager?.getParam(key, defaultValue),\r\n \r\n // i18n \uAD00\uB828\r\n $t: (key, params) => router.i18nManager?.t(key, params) || key,\r\n\r\n // \uC778\uC99D \uAD00\uB828\r\n $isAuthenticated: () => router.authManager?.isUserAuthenticated() || false,\r\n $logout: () => router.authManager ? router.navigateTo(router.authManager.handleLogout()) : null,\r\n $loginSuccess: (target) => router.authManager ? router.navigateTo(router.authManager.handleLoginSuccess(target)) : null,\r\n $checkAuth: (route) => router.authManager ? router.authManager.checkAuthentication(route) : Promise.resolve({ allowed: true, reason: 'auth_disabled' }),\r\n $getToken: () => router.authManager?.getAccessToken() || null,\r\n $setToken: (token, options) => router.authManager?.setAccessToken(token, options) || false,\r\n $removeToken: (storage) => router.authManager?.removeAccessToken(storage) || null,\r\n $getAuthCookie: () => router.authManager?.getAuthCookie() || null,\r\n $getCookie: (name) => router.authManager?.getCookieValue(name) || null,\r\n \r\n // \uB370\uC774\uD130 fetch (\uB2E8\uC77C API \uB610\uB294 \uD2B9\uC815 API)\r\n async $fetchData(apiName) {\r\n if (!script.dataURL) return;\r\n \r\n this.$dataLoading = true;\r\n try {\r\n if (typeof script.dataURL === 'string') {\r\n // \uAE30\uC874 \uB2E8\uC77C API \uBC29\uC2DD\r\n const data = await router.routeLoader.fetchComponentData(script.dataURL);\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Data fetched for ${routeName}:`, data);\r\n Object.assign(this, data);\r\n this.$emit('data-loaded', data);\r\n } else if (typeof script.dataURL === 'object' && apiName) {\r\n // \uD2B9\uC815 API\uB9CC \uC0C8\uB85C\uACE0\uCE68\r\n const url = script.dataURL[apiName];\r\n if (url) {\r\n const data = await router.routeLoader.fetchComponentData(url);\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Data fetched for ${routeName}.${apiName}:`, data);\r\n this[apiName] = data;\r\n this.$emit('data-loaded', { [apiName]: data });\r\n }\r\n } else {\r\n // \uB2E4\uC911 API - \uC804\uCCB4 \uC0C8\uB85C\uACE0\uCE68\r\n await this.$fetchMultipleData();\r\n }\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch data for ${routeName}:`, error);\r\n this.$emit('data-error', error);\r\n } finally {\r\n this.$dataLoading = false;\r\n }\r\n },\r\n\r\n // \uB2E4\uC911 API \uB370\uC774\uD130 fetch\r\n async $fetchMultipleData() {\r\n if (!script.dataURL || typeof script.dataURL !== 'object') return;\r\n \r\n const dataURLs = script.dataURL;\r\n this.$dataLoading = true;\r\n \r\n try {\r\n // \uBCD1\uB82C\uB85C \uBAA8\uB4E0 API \uD638\uCD9C\r\n const promises = Object.entries(dataURLs).map(async ([key, url]) => {\r\n try {\r\n const data = await router.routeLoader.fetchComponentData(url);\r\n return { key, data, success: true };\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch ${key} for ${routeName}:`, error);\r\n return { key, error, success: false };\r\n }\r\n });\r\n \r\n const results = await Promise.all(promises);\r\n const successfulResults = {};\r\n const errors = {};\r\n \r\n // \uACB0\uACFC \uCC98\uB9AC\r\n results.forEach(({ key, data, error, success }) => {\r\n if (success) {\r\n this[key] = data;\r\n successfulResults[key] = data;\r\n } else {\r\n errors[key] = error;\r\n }\r\n });\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Multiple data fetched for ${routeName}:`, successfulResults);\r\n \r\n // \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (Object.keys(successfulResults).length > 0) {\r\n this.$emit('data-loaded', successfulResults);\r\n }\r\n if (Object.keys(errors).length > 0) {\r\n this.$emit('data-error', errors);\r\n }\r\n \r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch multiple data for ${routeName}:`, error);\r\n this.$emit('data-error', error);\r\n } finally {\r\n this.$dataLoading = false;\r\n }\r\n },\r\n\r\n // \uC804\uCCB4 \uB370\uC774\uD130 \uC0C8\uB85C\uACE0\uCE68 (\uBA85\uC2DC\uC801 \uBA54\uC11C\uB4DC)\r\n async $fetchAllData() {\r\n if (typeof script.dataURL === 'string') {\r\n await this.$fetchData();\r\n } else if (typeof script.dataURL === 'object') {\r\n await this.$fetchMultipleData();\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uC790\uB3D9 \uD3FC \uBC14\uC778\uB529 \uBA54\uC11C\uB4DC\r\n $bindAutoForms() {\r\n const forms = document.querySelectorAll('form.auto-form, form[action]');\r\n \r\n forms.forEach(form => {\r\n // \uAE30\uC874 \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70 (\uC911\uBCF5 \uBC29\uC9C0)\r\n form.removeEventListener('submit', form._boundSubmitHandler);\r\n \r\n // \uC0C8 \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uCD94\uAC00\r\n const boundHandler = (e) => this.$handleFormSubmit(e);\r\n form._boundSubmitHandler = boundHandler;\r\n form.addEventListener('submit', boundHandler);\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Form auto-bound: ${form.getAttribute('action')}`);\r\n });\r\n },\r\n\r\n // \uD83C\uDD95 \uD3FC \uC11C\uBE0C\uBC0B \uD578\uB4E4\uB7EC\r\n async $handleFormSubmit(event) {\r\n event.preventDefault();\r\n \r\n const form = event.target;\r\n let action = form.getAttribute('action');\r\n const method = form.getAttribute('method') || 'POST';\r\n \r\n // \uD578\uB4E4\uB7EC \uD568\uC218\uB4E4 \uAC00\uC838\uC624\uAE30\r\n const successHandler = form.getAttribute('data-success-handler');\r\n const errorHandler = form.getAttribute('data-error-handler'); \r\n const loadingHandler = form.getAttribute('data-loading-handler');\r\n const redirectTo = form.getAttribute('data-redirect');\r\n\r\n try {\r\n // \uB85C\uB529 \uC2DC\uC791\r\n if (loadingHandler && this[loadingHandler]) {\r\n this[loadingHandler](true, form);\r\n }\r\n\r\n // \uD83C\uDD95 \uC561\uC158 URL\uC5D0 \uAC00\uBCC0 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC (\uAC04\uB2E8\uD55C \uD15C\uD50C\uB9BF \uCE58\uD658)\r\n action = this.$processActionParams(action);\r\n\r\n // \uD074\uB77C\uC774\uC5B8\uD2B8 \uC0AC\uC774\uB4DC \uAC80\uC99D\r\n if (!this.$validateForm(form)) {\r\n return;\r\n }\r\n\r\n // FormData \uC0DD\uC131\r\n const formData = new FormData(form);\r\n const data = Object.fromEntries(formData.entries());\r\n\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Form submitting to: ${action}`, data);\r\n\r\n // API \uD638\uCD9C\r\n const response = await this.$submitFormData(action, method, data, form);\r\n \r\n // \uC131\uACF5 \uD578\uB4E4\uB7EC \uD638\uCD9C\r\n if (successHandler && this[successHandler]) {\r\n this[successHandler](response, form);\r\n }\r\n\r\n // \uC790\uB3D9 \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n if (redirectTo) {\r\n setTimeout(() => {\r\n this.navigateTo(redirectTo);\r\n }, 1000); // 1\uCD08 \uD6C4 \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n }\r\n\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Form submission error:`, error);\r\n \r\n // \uC5D0\uB7EC \uD578\uB4E4\uB7EC \uD638\uCD9C\r\n if (errorHandler && this[errorHandler]) {\r\n this[errorHandler](error, form);\r\n } else {\r\n console.error('Form submission error:', error);\r\n }\r\n } finally {\r\n // \uB85C\uB529 \uC885\uB8CC\r\n if (loadingHandler && this[loadingHandler]) {\r\n this[loadingHandler](false, form);\r\n }\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uC561\uC158 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC \uBA54\uC11C\uB4DC (\uAC04\uB2E8\uD55C \uD15C\uD50C\uB9BF \uCE58\uD658)\r\n $processActionParams(actionTemplate) {\r\n let processedAction = actionTemplate;\r\n \r\n // {paramName} \uD328\uD134 \uCC3E\uAE30\r\n const paramMatches = actionTemplate.match(/\\{([^}]+)\\}/g);\r\n \r\n if (paramMatches) {\r\n paramMatches.forEach(match => {\r\n const paramName = match.slice(1, -1); // {id} -> id\r\n \r\n try {\r\n // \uCEF4\uD3EC\uB10C\uD2B8\uC758 data\uB098 computed, methods\uC5D0\uC11C \uAC12 \uCC3E\uAE30\r\n let paramValue = null;\r\n \r\n // 1. \uBA3C\uC800 getParam\uC73C\uB85C \uB77C\uC6B0\uD2B8 \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uCC3E\uAE30\r\n paramValue = this.getParam(paramName);\r\n \r\n // 2. \uCEF4\uD3EC\uB10C\uD2B8 data\uC5D0\uC11C \uCC3E\uAE30\r\n if (paramValue === null || paramValue === undefined) {\r\n paramValue = this[paramName];\r\n }\r\n \r\n // 3. computed \uC18D\uC131\uC5D0\uC11C \uCC3E\uAE30\r\n if (paramValue === null || paramValue === undefined) {\r\n if (this.$options.computed && this.$options.computed[paramName]) {\r\n paramValue = this[paramName];\r\n }\r\n }\r\n \r\n if (paramValue !== null && paramValue !== undefined) {\r\n // \uD15C\uD50C\uB9BF \uB300\uCCB4: {id} -> \uC2E4\uC81C\uAC12\r\n processedAction = processedAction.replace(\r\n match, \r\n encodeURIComponent(paramValue)\r\n );\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Parameter resolved: ${paramName} = ${paramValue}`);\r\n } else {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Parameter '${paramName}' not found in component data, computed, or route params`);\r\n // \uD30C\uB77C\uBBF8\uD130\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC73C\uBA74 \uC6D0\uBCF8 \uADF8\uB300\uB85C \uC720\uC9C0\r\n }\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Error processing parameter '${paramName}':`, error);\r\n // \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD574\uB3C4 \uC6D0\uBCF8 \uADF8\uB300\uB85C \uC720\uC9C0\r\n }\r\n });\r\n }\r\n \r\n return processedAction;\r\n },\r\n\r\n\r\n // \uD83C\uDD95 \uD3FC \uB370\uC774\uD130 \uC11C\uBE0C\uBC0B\r\n async $submitFormData(action, method, data, form) {\r\n // \uD30C\uC77C \uC5C5\uB85C\uB4DC \uCCB4\uD06C\r\n const hasFile = Array.from(form.elements).some(el => el.type === 'file' && el.files.length > 0);\r\n \r\n const headers = {\r\n 'Accept': 'application/json',\r\n // \uC778\uC99D \uD1A0\uD070 \uC790\uB3D9 \uCD94\uAC00\r\n ...(this.$getToken() && {\r\n 'Authorization': `Bearer ${this.$getToken()}`\r\n })\r\n };\r\n\r\n let body;\r\n if (hasFile) {\r\n // \uD30C\uC77C\uC774 \uC788\uC73C\uBA74 FormData \uADF8\uB300\uB85C \uC804\uC1A1\r\n body = new FormData(form);\r\n // Content-Type\uC744 \uC124\uC815\uD558\uC9C0 \uC54A\uC74C (\uBE0C\uB77C\uC6B0\uC800\uAC00 \uC790\uB3D9\uC73C\uB85C multipart/form-data\uB85C \uC124\uC815)\r\n } else {\r\n // JSON\uC73C\uB85C \uC804\uC1A1\r\n headers['Content-Type'] = 'application/json';\r\n body = JSON.stringify(data);\r\n }\r\n\r\n const response = await fetch(action, {\r\n method: method.toUpperCase(),\r\n headers,\r\n body\r\n });\r\n\r\n if (!response.ok) {\r\n let error;\r\n try {\r\n error = await response.json();\r\n } catch (e) {\r\n error = { message: `HTTP ${response.status}: ${response.statusText}` };\r\n }\r\n throw new Error(error.message || `HTTP ${response.status}`);\r\n }\r\n\r\n try {\r\n return await response.json();\r\n } catch (e) {\r\n // \uC751\uB2F5\uC774 JSON\uC774 \uC544\uB2CC \uACBD\uC6B0 (\uC608: 204 No Content)\r\n return { success: true };\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uD074\uB77C\uC774\uC5B8\uD2B8 \uC0AC\uC774\uB4DC \uD3FC \uAC80\uC99D\r\n $validateForm(form) {\r\n let isValid = true;\r\n const inputs = form.querySelectorAll('input, textarea, select');\r\n\r\n inputs.forEach(input => {\r\n // \uAE30\uBCF8 HTML5 \uAC80\uC99D\r\n if (!input.checkValidity()) {\r\n isValid = false;\r\n input.classList.add('error');\r\n return;\r\n }\r\n\r\n // \uCEE4\uC2A4\uD140 \uAC80\uC99D \uD568\uC218 \uD655\uC778\r\n const validationFunction = input.getAttribute('data-validation');\r\n if (validationFunction) {\r\n const isInputValid = this.$validateInput(input, validationFunction);\r\n if (!isInputValid) {\r\n isValid = false;\r\n input.classList.add('error');\r\n } else {\r\n input.classList.remove('error');\r\n }\r\n } else {\r\n input.classList.remove('error');\r\n }\r\n });\r\n\r\n return isValid;\r\n },\r\n\r\n // \uD83C\uDD95 \uAC1C\uBCC4 \uC785\uB825 \uAC80\uC99D\r\n $validateInput(input, validationFunction) {\r\n const value = input.value;\r\n \r\n // \uCEE4\uC2A4\uD140 \uAC80\uC99D \uD568\uC218 \uD638\uCD9C\r\n if (typeof this[validationFunction] === 'function') {\r\n try {\r\n return this[validationFunction](value, input);\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Validation function '${validationFunction}' error:`, error);\r\n return false;\r\n }\r\n }\r\n \r\n // \uD568\uC218\uAC00 \uC5C6\uC73C\uBA74 true \uBC18\uD658\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Validation function '${validationFunction}' not found`);\r\n return true;\r\n }\r\n },\r\n _routeName: routeName\r\n };\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB9CC \uC2A4\uD0C0\uC77C \uBA54\uD0C0\uB370\uC774\uD130 \uC800\uC7A5 (\uB80C\uB354\uB9C1 \uC2DC \uC8FC\uC785\uC6A9)\r\n if (!isProduction && style) {\r\n component._style = style;\r\n }\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n this.router.cacheManager?.setCache(cacheKey, component);\r\n \r\n return component;\r\n }\r\n\r\n /**\r\n * \uBB38\uC790\uC5F4\uC744 PascalCase\uB85C \uBCC0\uD658\r\n */\r\n toPascalCase(str) {\r\n return str\r\n .split(/[-_\\s]+/) // \uD558\uC774\uD508, \uC5B8\uB354\uC2A4\uCF54\uC5B4, \uACF5\uBC31\uC73C\uB85C \uBD84\uB9AC\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join('');\r\n }\r\n\r\n /**\r\n * \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uC0DD\uC131\r\n */\r\n generateDefaultTemplate(routeName) {\r\n return `<div class=\"route-${routeName}\"><h1>Route: ${routeName}</h1></div>`;\r\n }\r\n\r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uB370\uC774\uD130 \uAC00\uC838\uC624\uAE30\r\n */\r\n async fetchComponentData(dataURL) {\r\n try {\r\n // \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130\uB97C URL\uC5D0 \uCD94\uAC00\r\n const queryString = this.router.queryManager?.buildQueryString(this.router.queryManager?.getQueryParams()) || '';\r\n const fullURL = queryString ? `${dataURL}?${queryString}` : dataURL;\r\n \r\n this.log('debug', `Fetching data from: ${fullURL}`);\r\n \r\n const response = await fetch(fullURL, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n });\r\n \r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n \r\n const data = await response.json();\r\n \r\n // \uB370\uC774\uD130 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n if (typeof data !== 'object' || data === null) {\r\n throw new Error('Invalid data format: expected object');\r\n }\r\n \r\n return data;\r\n \r\n } catch (error) {\r\n this.log('error', 'Failed to fetch component data:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC \uBB34\uD6A8\uD654\r\n */\r\n invalidateCache(routeName) {\r\n if (this.router.cacheManager) {\r\n this.router.cacheManager.invalidateComponentCache(routeName);\r\n }\r\n this.log('debug', `Cache invalidated for route: ${routeName}`);\r\n }\r\n\r\n /**\r\n * \uD1B5\uACC4 \uC815\uBCF4 \uBC18\uD658\r\n */\r\n getStats() {\r\n return {\r\n environment: this.config.environment,\r\n basePath: this.config.basePath,\r\n routesPath: this.config.routesPath,\r\n useLayout: this.config.useLayout,\r\n useComponents: this.config.useComponents\r\n };\r\n }\r\n\r\n /**\r\n * \uD398\uC774\uC9C0 \uC81C\uBAA9 \uC0DD\uC131\r\n */\r\n generatePageTitle(routeName) {\r\n return this.toPascalCase(routeName).replace(/([A-Z])/g, ' $1').trim();\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'RouteLoader', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.log('debug', 'RouteLoader destroyed');\r\n this.router = null;\r\n }\r\n}", "/**\r\n * ViewLogic Error Handling System\r\n * \uB77C\uC6B0\uD2B8 \uBC0F \uC2DC\uC2A4\uD15C \uC5D0\uB7EC \uCC98\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class ErrorHandler {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enableErrorReporting: options.enableErrorReporting !== false,\r\n debug: options.debug || false,\r\n logLevel: options.logLevel || (options.debug ? 'debug' : 'info'),\r\n environment: options.environment || 'development'\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n \r\n // \uB85C\uADF8 \uB808\uBCA8 \uB9E4\uD551\r\n this.logLevels = {\r\n error: 0,\r\n warn: 1, \r\n info: 2,\r\n debug: 3\r\n };\r\n \r\n this.log('info', 'ErrorHandler', 'ErrorHandler initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD2B8 \uC5D0\uB7EC \uCC98\uB9AC\r\n */\r\n async handleRouteError(routeName, error) {\r\n let errorCode = 500;\r\n let errorMessage = '\uD398\uC774\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.';\r\n \r\n this.debug('ErrorHandler', '\uC5D0\uB7EC \uC0C1\uC138:', error.message, error.name);\r\n \r\n // \uC5D0\uB7EC \uD0C0\uC785 \uBD84\uC11D (\uB354 \uC815\uD655\uD55C 404 \uAC10\uC9C0)\r\n if (error.message.includes('not found') || \r\n error.message.includes('404') ||\r\n error.message.includes('Failed to resolve') ||\r\n error.message.includes('Failed to fetch') ||\r\n (error.name === 'TypeError' && error.message.includes('resolve'))) {\r\n errorCode = 404;\r\n errorMessage = `'${routeName}' \uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`;\r\n } else if (error.message.includes('network') && !error.message.includes('not found')) {\r\n errorCode = 503;\r\n errorMessage = '\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD574 \uC8FC\uC138\uC694.';\r\n } else if (error.message.includes('permission') || error.message.includes('403')) {\r\n errorCode = 403;\r\n errorMessage = '\uD398\uC774\uC9C0\uC5D0 \uC811\uADFC\uD560 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.';\r\n }\r\n \r\n this.debug('ErrorHandler', `\uC5D0\uB7EC \uCF54\uB4DC \uACB0\uC815: ${errorCode} (\uB77C\uC6B0\uD2B8: ${routeName})`);\r\n \r\n // \uC5D0\uB7EC \uB9AC\uD3EC\uD305\r\n if (this.config.enableErrorReporting) {\r\n this.reportError(routeName, error, errorCode);\r\n }\r\n \r\n try {\r\n // 404 \uD398\uC774\uC9C0 \uC804\uC6A9 \uCC98\uB9AC\r\n if (errorCode === 404) {\r\n await this.load404Page();\r\n } else {\r\n // \uC77C\uBC18 \uC5D0\uB7EC \uD398\uC774\uC9C0\r\n await this.loadErrorPage(errorCode, errorMessage);\r\n }\r\n } catch (fallbackError) {\r\n this.error('ErrorHandler', '\uC5D0\uB7EC \uD398\uC774\uC9C0 \uB85C\uB529 \uC2E4\uD328:', fallbackError);\r\n // \uBAA8\uB4E0 \uC5D0\uB7EC \uD398\uC774\uC9C0\uAC00 \uC2E4\uD328\uD588\uC744 \uB54C \uCD5C\uD6C4\uC758 \uD3F4\uBC31 \uD398\uC774\uC9C0 \uD45C\uC2DC\r\n this.showFallbackErrorPage(errorCode, errorMessage);\r\n }\r\n }\r\n\r\n /**\r\n * 404 \uD398\uC774\uC9C0 \uB85C\uB529\r\n */\r\n async load404Page() {\r\n try {\r\n this.info('ErrorHandler', 'Loading 404 page...');\r\n const component = await this.createVueComponent('404');\r\n await this.renderComponentWithTransition(component, '404');\r\n this.info('ErrorHandler', '404 page loaded successfully');\r\n } catch (error) {\r\n this.error('ErrorHandler', '404 page loading failed:', error);\r\n // 404 \uD398\uC774\uC9C0\uB3C4 \uC5C6\uC73C\uBA74 \uAC04\uB2E8\uD55C \uC5D0\uB7EC \uBA54\uC2DC\uC9C0 \uD45C\uC2DC\r\n this.showFallbackErrorPage('404', '\uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.');\r\n }\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uD398\uC774\uC9C0 \uB85C\uB529\r\n */\r\n async loadErrorPage(errorCode, errorMessage) {\r\n try {\r\n this.info('ErrorHandler', `Loading error page for ${errorCode}...`);\r\n \r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n const errorComponent = await this.createErrorComponent(errorCode, errorMessage);\r\n await this.renderComponentWithTransition(errorComponent, 'error');\r\n this.info('ErrorHandler', `Error page ${errorCode} loaded successfully`);\r\n } catch (error) {\r\n this.error('ErrorHandler', `Error page ${errorCode} loading failed:`, error);\r\n // \uC5D0\uB7EC \uD398\uC774\uC9C0\uB3C4 \uB85C\uB529 \uC2E4\uD328\uD558\uBA74 \uD3F4\uBC31 \uD45C\uC2DC\r\n this.showFallbackErrorPage(errorCode, errorMessage);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n */\r\n async createErrorComponent(errorCode, errorMessage) {\r\n try {\r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\r\n const component = await this.createVueComponent('error');\r\n \r\n // \uC5D0\uB7EC \uC815\uBCF4\uB97C props\uB85C \uC804\uB2EC\r\n const errorComponent = {\r\n ...component,\r\n data() {\r\n const originalData = component.data ? component.data() : {};\r\n return {\r\n ...originalData,\r\n errorCode,\r\n errorMessage,\r\n showRetry: true,\r\n showGoHome: true\r\n };\r\n }\r\n };\r\n \r\n return errorComponent;\r\n } catch (error) {\r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8\uB3C4 \uB85C\uB4DC\uD560 \uC218 \uC5C6\uB294 \uACBD\uC6B0 \uAC04\uB2E8\uD55C \uC5D0\uB7EC \uD45C\uC2DC\r\n this.error('ErrorHandler', 'Error component load failed:', error);\r\n throw new Error(`Cannot load error page: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * \uD3F4\uBC31 \uC5D0\uB7EC \uD398\uC774\uC9C0 \uD45C\uC2DC (\uBAA8\uB4E0 \uC5D0\uB7EC \uD398\uC774\uC9C0\uAC00 \uC2E4\uD328\uD588\uC744 \uB54C)\r\n */\r\n showFallbackErrorPage(errorCode, errorMessage) {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n const fallbackHTML = `\r\n <div class=\"fallback-error-page\" style=\"\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 100vh;\r\n padding: 2rem;\r\n text-align: center;\r\n background: #f8f9fa;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n \">\r\n <div style=\"\r\n background: white;\r\n padding: 3rem;\r\n border-radius: 12px;\r\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\r\n max-width: 500px;\r\n \">\r\n <h1 style=\"\r\n font-size: 4rem;\r\n margin: 0;\r\n color: #dc3545;\r\n font-weight: 300;\r\n \">${errorCode}</h1>\r\n <h2 style=\"\r\n margin: 1rem 0;\r\n color: #495057;\r\n font-weight: 400;\r\n \">${errorMessage}</h2>\r\n <p style=\"\r\n color: #6c757d;\r\n margin-bottom: 2rem;\r\n line-height: 1.5;\r\n \">\uC694\uCCAD\uD558\uC2E0 \uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.</p>\r\n <button onclick=\"window.location.hash = '#/'\" style=\"\r\n background: #007bff;\r\n color: white;\r\n border: none;\r\n padding: 12px 24px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n font-size: 1rem;\r\n transition: background 0.2s;\r\n \" onmouseover=\"this.style.background='#0056b3'\" onmouseout=\"this.style.background='#007bff'\">\r\n \uD648\uC73C\uB85C \uB3CC\uC544\uAC00\uAE30\r\n </button>\r\n </div>\r\n </div>\r\n `;\r\n\r\n // \uAE30\uC874 \uCEE8\uD14C\uC774\uB108\uB4E4 \uC815\uB9AC\r\n appElement.innerHTML = fallbackHTML;\r\n \r\n this.info('ErrorHandler', `Fallback error page displayed for ${errorCode}`);\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uB9AC\uD3EC\uD305\r\n */\r\n reportError(routeName, error, errorCode) {\r\n const errorReport = {\r\n route: routeName,\r\n errorCode,\r\n errorMessage: error.message,\r\n stack: error.stack,\r\n url: window.location.href,\r\n userAgent: navigator.userAgent,\r\n timestamp: new Date().toISOString(),\r\n routerConfig: {\r\n environment: this.router.config.environment,\r\n mode: this.router.config.mode\r\n }\r\n };\r\n \r\n this.error('ErrorHandler', '\uB77C\uC6B0\uD130 \uC5D0\uB7EC \uB9AC\uD3EC\uD2B8:', errorReport);\r\n \r\n // \uCD94\uD6C4 \uC5D0\uB7EC \uCD94\uC801 \uC11C\uBE44\uC2A4\uB85C \uC804\uC1A1\uD560 \uC218 \uC788\uC74C\r\n // \uC608: analytics.track('router_error', errorReport);\r\n }\r\n\r\n /**\r\n * Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131 (RouteLoader \uC704\uC784)\r\n */\r\n async createVueComponent(routeName) {\r\n if (this.router.routeLoader) {\r\n return await this.router.routeLoader.createVueComponent(routeName);\r\n }\r\n throw new Error('RouteLoader not available');\r\n }\r\n\r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1 (ViewManager \uC704\uC784)\r\n */\r\n async renderComponentWithTransition(component, routeName) {\r\n if (this.router.renderComponentWithTransition) {\r\n return await this.router.renderComponentWithTransition(component, routeName);\r\n }\r\n throw new Error('Render function not available');\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569 \uB85C\uAE45 \uC2DC\uC2A4\uD15C\r\n * @param {string} level - \uB85C\uADF8 \uB808\uBCA8 (error, warn, info, debug)\r\n * @param {string} component - \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 (\uC120\uD0DD\uC801)\r\n * @param {...any} args - \uB85C\uADF8 \uBA54\uC2DC\uC9C0\r\n */\r\n log(level, component, ...args) {\r\n // \uD558\uC704 \uD638\uD658\uC131: \uAE30\uC874 \uBC29\uC2DD\uB3C4 \uC9C0\uC6D0\r\n if (typeof level !== 'string' || !this.logLevels.hasOwnProperty(level)) {\r\n args = [component, ...args];\r\n component = level;\r\n level = this.config.debug ? 'debug' : 'info';\r\n }\r\n \r\n // \uB85C\uADF8 \uB808\uBCA8 \uD655\uC778\r\n const currentLevelValue = this.logLevels[this.config.logLevel] || this.logLevels.info;\r\n const messageLevelValue = this.logLevels[level] || this.logLevels.info;\r\n \r\n if (messageLevelValue > currentLevelValue) {\r\n return; // \uD604\uC7AC \uC124\uC815\uB41C \uB808\uBCA8\uBCF4\uB2E4 \uB192\uC73C\uBA74 \uCD9C\uB825 \uC548\uD568\r\n }\r\n \r\n // \uD504\uB85C\uB355\uC158 \uD658\uACBD\uC5D0\uC11C\uB294 error\uC640 warn\uB9CC \uCD9C\uB825\r\n if (this.config.environment === 'production' && messageLevelValue > this.logLevels.warn) {\r\n return;\r\n }\r\n \r\n const prefix = component ? `[${component}]` : '[ViewLogic]';\r\n const timestamp = new Date().toISOString().substring(11, 23); // HH:MM:SS.mmm\r\n \r\n switch (level) {\r\n case 'error':\r\n console.error(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'warn':\r\n console.warn(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'info':\r\n console.info(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'debug':\r\n console.log(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n default:\r\n console.log(`${timestamp} ${prefix}`, ...args);\r\n }\r\n }\r\n \r\n /**\r\n * \uC5D0\uB7EC \uB85C\uADF8 (\uD56D\uC0C1 \uCD9C\uB825)\r\n */\r\n error(component, ...args) {\r\n this.log('error', component, ...args);\r\n }\r\n \r\n /**\r\n * \uACBD\uACE0 \uB85C\uADF8\r\n */\r\n warn(component, ...args) {\r\n this.log('warn', component, ...args);\r\n }\r\n \r\n /**\r\n * \uC815\uBCF4 \uB85C\uADF8\r\n */\r\n info(component, ...args) {\r\n this.log('info', component, ...args);\r\n }\r\n \r\n /**\r\n * \uB514\uBC84\uADF8 \uB85C\uADF8\r\n */\r\n debug(component, ...args) {\r\n this.log('debug', component, ...args);\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.router = null;\r\n this.info('ErrorHandler', 'ErrorHandler destroyed');\r\n }\r\n}", "/**\r\n * ComponentLoader\r\n * \uB3D9\uC801\uC73C\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uB85C\uB4DC\uD558\uACE0 \uB4F1\uB85D\uD558\uB294 \uC2DC\uC2A4\uD15C\r\n */\r\nexport class ComponentLoader {\r\n constructor(router = null, options = {}) {\r\n\r\n this.config = {\r\n basePath: options.basePath || '/src/components',\r\n debug: options.debug || false,\r\n environment: options.environment || 'development',\r\n ...options\r\n };\r\n \r\n this.router = router;\r\n this.loadingPromises = new Map();\r\n this.unifiedComponents = null;\r\n }\r\n \r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'ComponentLoader', ...args);\r\n }\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uBE44\uB3D9\uAE30\uB85C \uB85C\uB4DC\r\n */\r\n async loadComponent(componentName) {\r\n if (!componentName || typeof componentName !== 'string') {\r\n throw new Error('Component name must be a non-empty string');\r\n }\r\n \r\n // \uC774\uBBF8 \uB85C\uB529 \uC911\uC778 \uACBD\uC6B0 \uAE30\uC874 Promise \uBC18\uD658\r\n if (this.loadingPromises.has(componentName)) {\r\n return this.loadingPromises.get(componentName);\r\n }\r\n \r\n const loadPromise = this._loadComponentFromFile(componentName);\r\n this.loadingPromises.set(componentName, loadPromise);\r\n \r\n try {\r\n const component = await loadPromise;\r\n return component;\r\n } catch (error) {\r\n throw error;\r\n } finally {\r\n this.loadingPromises.delete(componentName);\r\n }\r\n }\r\n \r\n /**\r\n * \uD30C\uC77C\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB4DC\r\n */\r\n async _loadComponentFromFile(componentName) {\r\n const componentPath = `${this.config.basePath}/${componentName}.js`;\r\n \r\n try {\r\n const module = await import(componentPath);\r\n const component = module.default;\r\n \r\n if (!component) {\r\n throw new Error(`Component '${componentName}' has no default export`);\r\n }\r\n \r\n if (!component.name) {\r\n component.name = componentName;\r\n }\r\n \r\n this.log('debug', `Component '${componentName}' loaded successfully`);\r\n return component;\r\n \r\n } catch (error) {\r\n this.log('error', `Failed to load component '${componentName}':`, error);\r\n throw new Error(`Component '${componentName}' not found: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uBAA8\uB4C8 \uD074\uB9AC\uC5B4\r\n */\r\n clearComponents() {\r\n this.loadingPromises.clear();\r\n this.unifiedComponents = null;\r\n this.log('debug', 'All components cleared');\r\n }\r\n \r\n /**\r\n * \uD658\uACBD\uC5D0 \uB530\uB978 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 (\uCE90\uC2F1 \uC9C0\uC6D0)\r\n */\r\n async loadAllComponents() {\r\n // \uC774\uBBF8 \uB85C\uB4DC\uB41C unifiedComponents\uAC00 \uC788\uC73C\uBA74 \uBC18\uD658\r\n if (this.unifiedComponents) {\r\n this.log('debug', 'Using existing unified components');\r\n return this.unifiedComponents;\r\n }\r\n \r\n // \uC6B4\uC601 \uBAA8\uB4DC: \uD1B5\uD569 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 \uC2DC\uB3C4\r\n if (this.config.environment === 'production') {\r\n return await this._loadProductionComponents();\r\n }\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC: \uAC1C\uBCC4 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n return await this._loadDevelopmentComponents();\r\n }\r\n \r\n /**\r\n * \uC6B4\uC601 \uBAA8\uB4DC: \uD1B5\uD569 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n */\r\n async _loadProductionComponents() {\r\n try {\r\n const componentsPath = `${this.config.routesPath}/_components.js`;\r\n this.log('info', '[PRODUCTION] Loading unified components from:', componentsPath);\r\n \r\n const componentsModule = await import(componentsPath);\r\n \r\n if (typeof componentsModule.registerComponents === 'function') {\r\n this.unifiedComponents = componentsModule.components || {};\r\n this.log('info', `[PRODUCTION] Unified components loaded: ${Object.keys(this.unifiedComponents).length} components`);\r\n return this.unifiedComponents;\r\n } else {\r\n throw new Error('registerComponents function not found in components module');\r\n }\r\n } catch (error) {\r\n this.log('warn', '[PRODUCTION] Failed to load unified components:', error.message);\r\n this.unifiedComponents = {};\r\n return {};\r\n }\r\n }\r\n \r\n /**\r\n * \uAC1C\uBC1C \uBAA8\uB4DC: \uAC1C\uBCC4 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n */\r\n async _loadDevelopmentComponents() {\r\n const componentNames = this._getComponentNames();\r\n const components = {};\r\n \r\n this.log('info', `[DEVELOPMENT] Loading individual components: ${componentNames.join(', ')}`);\r\n \r\n for (const name of componentNames) {\r\n try {\r\n const component = await this.loadComponent(name);\r\n if (component) {\r\n components[name] = component;\r\n }\r\n } catch (loadError) {\r\n this.log('warn', `[DEVELOPMENT] Failed to load component ${name}:`, loadError.message);\r\n }\r\n }\r\n \r\n this.unifiedComponents = components;\r\n this.log('info', `[DEVELOPMENT] Individual components loaded: ${Object.keys(components).length} components`);\r\n return components;\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 \uBAA9\uB85D \uAC00\uC838\uC624\uAE30\r\n */\r\n _getComponentNames() {\r\n if (Array.isArray(this.config.componentNames) && this.config.componentNames.length > 0) {\r\n return [...this.config.componentNames];\r\n }\r\n \r\n // \uD3F4\uBC31: \uAE30\uC874 \uD558\uB4DC\uCF54\uB529 \uBAA9\uB85D\r\n return [\r\n 'Button', 'Modal', 'Card', 'Toast', 'Input', 'Tabs',\r\n 'Checkbox', 'Alert', 'DynamicInclude', 'HtmlInclude'\r\n ];\r\n }\r\n \r\n /**\r\n * \uBA54\uBAA8\uB9AC \uC815\uB9AC\r\n */\r\n dispose() {\r\n this.clearComponents();\r\n this.log('debug', 'ComponentLoader disposed');\r\n this.router = null;\r\n }\r\n}", "// ViewLogic Router - ES6 Module\r\nimport { I18nManager } from './plugins/I18nManager.js';\r\nimport { AuthManager } from './plugins/AuthManager.js';\r\nimport { CacheManager } from './plugins/CacheManager.js';\r\nimport { QueryManager } from './plugins/QueryManager.js';\r\nimport { RouteLoader } from './core/RouteLoader.js';\r\nimport { ErrorHandler } from './core/ErrorHandler.js';\r\nimport { ComponentLoader } from './core/ComponentLoader.js';\r\n\r\nexport class ViewLogicRouter {\r\n constructor(options = {}) {\r\n // \uBC84\uC804 \uC815\uBCF4\r\n this.version = options.version || '1.0.0';\r\n \r\n // \uAE30\uBCF8 \uD658\uACBD\uC124\uC815 \uCD5C\uC801\uD654\r\n this.config = this._buildConfig(options);\r\n \r\n this.currentHash = '';\r\n this.currentVueApp = null;\r\n this.previousVueApp = null; // \uC774\uC804 Vue \uC571 (\uC804\uD658 \uD6A8\uACFC\uB97C \uC704\uD574 \uBCF4\uAD00)\r\n this.componentLoader = null; // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB354 \uC778\uC2A4\uD134\uC2A4\r\n\r\n // LoadingManager\uAC00 \uC5C6\uC744 \uB54C\uB97C \uC704\uD55C \uAE30\uBCF8 \uC804\uD658 \uC0C1\uD0DC\r\n this.transitionInProgress = false;\r\n \r\n // \uCD08\uAE30\uD654 \uC900\uBE44 \uC0C1\uD0DC\r\n this.isReady = false;\r\n this.readyPromise = null;\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uBC14\uC778\uB529 \uCD5C\uC801\uD654\r\n this._boundHandleRouteChange = this.handleRouteChange.bind(this);\r\n \r\n // \uBAA8\uB4E0 \uCD08\uAE30\uD654\uB97C \uD55C\uBC88\uC5D0 \uCC98\uB9AC\r\n this.readyPromise = this.initialize();\r\n }\r\n\r\n /**\r\n * \uC124\uC815 \uBE4C\uB4DC (\uBD84\uB9AC\uD558\uC5EC \uAC00\uB3C5\uC131 \uD5A5\uC0C1)\r\n */\r\n _buildConfig(options) {\r\n const currentOrigin = window.location.origin;\r\n \r\n const defaults = {\r\n basePath: `${currentOrigin}/src`,\r\n mode: 'hash',\r\n cacheMode: 'memory',\r\n cacheTTL: 300000,\r\n maxCacheSize: 50,\r\n useLayout: true,\r\n defaultLayout: 'default',\r\n environment: 'development',\r\n routesPath: `${currentOrigin}/routes`,\r\n enableErrorReporting: true,\r\n useComponents: true,\r\n componentNames: ['Button', 'Modal', 'Card', 'Toast', 'Input', 'Tabs', 'Checkbox', 'Alert', 'DynamicInclude', 'HtmlInclude'],\r\n useI18n: true,\r\n defaultLanguage: 'ko',\r\n i18nPath: `${currentOrigin}/i18n`,\r\n logLevel: 'info',\r\n authEnabled: false,\r\n loginRoute: 'login',\r\n protectedRoutes: [],\r\n protectedPrefixes: [],\r\n publicRoutes: ['login', 'register', 'home'],\r\n checkAuthFunction: null,\r\n redirectAfterLogin: 'home',\r\n authCookieName: 'authToken',\r\n authFallbackCookieNames: ['accessToken', 'token', 'jwt'],\r\n authStorage: 'cookie',\r\n authCookieOptions: {},\r\n authSkipValidation: false,\r\n enableParameterValidation: true,\r\n maxParameterLength: 1000,\r\n maxParameterCount: 50,\r\n maxArraySize: 100,\r\n allowedKeyPattern: /^[a-zA-Z0-9_-]+$/,\r\n logSecurityWarnings: true\r\n };\r\n \r\n const config = { ...defaults, ...options };\r\n \r\n // \uC0AC\uC6A9\uC790\uAC00 \uC81C\uACF5\uD55C basePath\uC640 routesPath\uC5D0 origin\uC774 \uC5C6\uC73C\uBA74 \uCD94\uAC00\r\n if (options.basePath && !options.basePath.startsWith('http')) {\r\n config.basePath = `${currentOrigin}${options.basePath}`;\r\n }\r\n if (options.routesPath && !options.routesPath.startsWith('http')) {\r\n config.routesPath = `${currentOrigin}${options.routesPath}`;\r\n }\r\n if (options.i18nPath && !options.i18nPath.startsWith('http')) {\r\n config.i18nPath = `${currentOrigin}${options.i18nPath}`;\r\n }\r\n \r\n return config;\r\n }\r\n\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.errorHandler) {\r\n this.errorHandler.log(level, 'Router', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569 \uCD08\uAE30\uD654 - \uB9E4\uB2C8\uC800 \uC0DD\uC131 \u2192 \uBE44\uB3D9\uAE30 \uB85C\uB529 \u2192 \uB77C\uC6B0\uD130 \uC2DC\uC791\r\n */\r\n async initialize() {\r\n try {\r\n // 1. \uB9E4\uB2C8\uC800 \uCD08\uAE30\uD654 (\uB3D9\uAE30)\r\n // \uD56D\uC0C1 \uD544\uC694\uD55C \uB9E4\uB2C8\uC800\uB4E4\r\n this.cacheManager = new CacheManager(this, this.config);\r\n this.routeLoader = new RouteLoader(this, this.config);\r\n this.queryManager = new QueryManager(this, this.config);\r\n this.errorHandler = new ErrorHandler(this, this.config);\r\n \r\n // \uC870\uAC74\uBD80 \uB9E4\uB2C8\uC800\uB4E4\r\n if (this.config.useI18n) {\r\n this.i18nManager = new I18nManager(this, this.config);\r\n if (this.i18nManager.initPromise) {\r\n await this.i18nManager.initPromise;\r\n }\r\n }\r\n \r\n if (this.config.authEnabled) {\r\n this.authManager = new AuthManager(this, this.config);\r\n }\r\n \r\n if (this.config.useComponents) {\r\n try {\r\n this.componentLoader = new ComponentLoader(this, {\r\n ...this.config,\r\n basePath: `${this.config.basePath}/components`,\r\n cache: true,\r\n componentNames: this.config.componentNames\r\n });\r\n await this.componentLoader.loadAllComponents();\r\n this.log('info', 'ComponentLoader initialized successfully');\r\n } catch (componentError) {\r\n this.log('warn', 'ComponentLoader initialization failed, continuing without components:', componentError.message);\r\n this.componentLoader = null; // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB354 \uBE44\uD65C\uC131\uD654\r\n }\r\n }\r\n \r\n // 2. \uB77C\uC6B0\uD130 \uC2DC\uC791\r\n this.isReady = true;\r\n this.init();\r\n \r\n } catch (error) {\r\n this.log('error', 'Router initialization failed:', error);\r\n // \uC2E4\uD328\uD574\uB3C4 \uB77C\uC6B0\uD130\uB294 \uC2DC\uC791 (graceful degradation)\r\n this.isReady = true;\r\n this.init();\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD130\uAC00 \uC900\uBE44\uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30\r\n */\r\n async waitForReady() {\r\n if (this.isReady) return true;\r\n if (this.readyPromise) {\r\n await this.readyPromise;\r\n }\r\n return this.isReady;\r\n }\r\n\r\n\r\n init() {\r\n const isHashMode = this.config.mode === 'hash';\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D (\uBA54\uBAA8\uB9AC \uCD5C\uC801\uD654)\r\n window.addEventListener(\r\n isHashMode ? 'hashchange' : 'popstate',\r\n this._boundHandleRouteChange\r\n );\r\n \r\n // DOM \uB85C\uB4DC \uCC98\uB9AC \uD1B5\uD569\r\n const initRoute = () => {\r\n if (isHashMode && !window.location.hash) {\r\n window.location.hash = '#/';\r\n } else if (!isHashMode && window.location.pathname === '/') {\r\n this.navigateTo('home');\r\n } else {\r\n this.handleRouteChange();\r\n }\r\n };\r\n \r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', initRoute);\r\n } else {\r\n // requestAnimationFrame\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n requestAnimationFrame(initRoute);\r\n }\r\n }\r\n\r\n handleRouteChange() {\r\n const { route, queryParams } = this._parseCurrentLocation();\r\n \r\n // Store current query parameters in QueryManager\r\n this.queryManager?.setCurrentQueryParams(queryParams);\r\n \r\n // \uBCC0\uACBD\uC0AC\uD56D\uC774 \uC788\uC744 \uB54C\uB9CC \uB85C\uB4DC (\uC131\uB2A5 \uCD5C\uC801\uD654)\r\n if (route !== this.currentHash || this.queryManager?.hasQueryParamsChanged(queryParams)) {\r\n this.currentHash = route;\r\n this.loadRoute(route);\r\n }\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC704\uCE58 \uD30C\uC2F1 (\uBD84\uB9AC\uD558\uC5EC \uAC00\uB3C5\uC131 \uD5A5\uC0C1)\r\n */\r\n _parseCurrentLocation() {\r\n if (this.config.mode === 'hash') {\r\n const hashPath = window.location.hash.slice(1) || '/';\r\n const [pathPart, queryPart] = hashPath.split('?');\r\n \r\n // \uACBD\uB85C \uD30C\uC2F1 \uCD5C\uC801\uD654\r\n let route = 'home';\r\n if (pathPart && pathPart !== '/') {\r\n route = pathPart.startsWith('/') ? pathPart.slice(1) : pathPart;\r\n }\r\n \r\n return {\r\n route: route || 'home',\r\n queryParams: this.queryManager?.parseQueryString(queryPart || window.location.search.slice(1)) || {}\r\n };\r\n } else {\r\n return {\r\n route: window.location.pathname.slice(1) || 'home',\r\n queryParams: this.queryManager?.parseQueryString(window.location.search.slice(1)) || {}\r\n };\r\n }\r\n }\r\n\r\n async loadRoute(routeName) {\r\n // \uC804\uD658\uC774 \uC9C4\uD589 \uC911\uC774\uBA74 \uBB34\uC2DC\r\n const inProgress = this.transitionInProgress;\r\n \r\n if (inProgress) {\r\n return;\r\n }\r\n\r\n try {\r\n this.transitionInProgress = true;\r\n \r\n // \uC778\uC99D \uCCB4\uD06C\r\n const authResult = this.authManager ? \r\n await this.authManager.checkAuthentication(routeName) :\r\n { allowed: true, reason: 'auth_disabled' };\r\n if (!authResult.allowed) {\r\n // \uC778\uC99D \uC2E4\uD328 \uC2DC \uB85C\uADF8\uC778 \uD398\uC774\uC9C0\uB85C \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n if (this.authManager) {\r\n this.authManager.emitAuthEvent('auth_required', { \r\n originalRoute: routeName,\r\n loginRoute: this.config.loginRoute \r\n });\r\n \r\n // navigateTo\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC774\uC804 \uD398\uC774\uC9C0\uB85C \uB3CC\uC544\uAC00\uAE30 \uC9C0\uC6D0\r\n if (routeName !== this.config.loginRoute) {\r\n this.navigateTo(this.config.loginRoute, { redirect: routeName });\r\n } else {\r\n this.navigateTo(this.config.loginRoute);\r\n }\r\n }\r\n return;\r\n }\r\n \r\n const appElement = document.getElementById('app');\r\n if (!appElement) {\r\n throw new Error('App element not found');\r\n }\r\n\r\n // Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131 (\uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C)\r\n const component = await this.routeLoader.createVueComponent(routeName);\r\n \r\n // \uC0C8\uB85C\uC6B4 \uD398\uC774\uC9C0\uB97C \uC624\uBC84\uB808\uC774\uB85C \uB80C\uB354\uB9C1\r\n await this.renderComponentWithTransition(component, routeName);\r\n \r\n // \uB85C\uB529 \uC644\uB8CC\r\n \r\n } catch (error) {\r\n this.log('error', `Route loading failed [${routeName}]:`, error.message);\r\n \r\n \r\n // \uC5D0\uB7EC \uD0C0\uC785\uC5D0 \uB530\uB978 \uCC98\uB9AC\r\n if (this.errorHandler) {\r\n await this.errorHandler.handleRouteError(routeName, error);\r\n } else {\r\n console.error('[Router] No error handler available');\r\n }\r\n } finally {\r\n // \uBAA8\uB4E0 \uCC98\uB9AC\uAC00 \uC644\uB8CC\uB41C \uD6C4 \uC804\uD658 \uC0C1\uD0DC \uB9AC\uC14B\r\n this.transitionInProgress = false;\r\n }\r\n }\r\n\r\n async renderComponentWithTransition(vueComponent, routeName) {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n // \uC0C8\uB85C\uC6B4 \uD398\uC774\uC9C0 \uCEE8\uD14C\uC774\uB108 \uC0DD\uC131\r\n const newPageContainer = document.createElement('div');\r\n newPageContainer.className = 'page-container page-entered';\r\n newPageContainer.id = `page-${routeName}-${Date.now()}`;\r\n \r\n // \uAE30\uC874 \uCEE8\uD14C\uC774\uB108\uAC00 \uC788\uB2E4\uBA74 \uC989\uC2DC \uC228\uAE30\uAE30\r\n const existingContainers = appElement.querySelectorAll('.page-container');\r\n existingContainers.forEach(container => {\r\n container.classList.remove('page-entered');\r\n container.classList.add('page-exiting');\r\n });\r\n\r\n // \uC0C8 \uCEE8\uD14C\uC774\uB108\uB97C \uC571\uC5D0 \uCD94\uAC00\r\n appElement.appendChild(newPageContainer);\r\n\r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB9CC \uC2A4\uD0C0\uC77C \uC801\uC6A9 (\uD504\uB85C\uB355\uC158 \uBAA8\uB4DC\uB294 \uBE4C\uB4DC\uB41C JS\uC5D0\uC11C \uC790\uB3D9 \uCC98\uB9AC)\r\n if (this.config.environment === 'development' && vueComponent._style) {\r\n this.applyStyle(vueComponent._style, routeName);\r\n }\r\n \r\n // \uC0C8\uB85C\uC6B4 Vue \uC571\uC744 \uC0C8 \uCEE8\uD14C\uC774\uB108\uC5D0 \uB9C8\uC6B4\uD2B8\r\n const { createApp } = Vue;\r\n const newVueApp = createApp(vueComponent);\r\n \r\n // Vue 3 \uC804\uC5ED \uC18D\uC131 \uC124\uC815\r\n newVueApp.config.globalProperties.$router = {\r\n navigateTo: (route, params) => this.navigateTo(route, params),\r\n getCurrentRoute: () => this.getCurrentRoute(),\r\n \r\n // \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC (\uB77C\uC6B0\uD305 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n getParams: () => this.queryManager?.getAllParams() || {},\r\n getParam: (key, defaultValue) => this.queryManager?.getParam(key, defaultValue),\r\n \r\n // \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC804\uC6A9 \uBA54\uC11C\uB4DC (\uD558\uC704 \uD638\uD658\uC131)\r\n getQueryParams: () => this.queryManager?.getQueryParams() || {},\r\n getQueryParam: (key, defaultValue) => this.queryManager?.getQueryParam(key, defaultValue),\r\n setQueryParams: (params, replace) => this.queryManager?.setQueryParams(params, replace),\r\n removeQueryParams: (keys) => this.queryManager?.removeQueryParams(keys),\r\n \r\n // \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC804\uC6A9 \uBA54\uC11C\uB4DC\r\n getRouteParams: () => this.queryManager?.getRouteParams() || {},\r\n getRouteParam: (key, defaultValue) => this.queryManager?.getRouteParam(key, defaultValue),\r\n \r\n currentRoute: this.currentHash,\r\n currentQuery: this.queryManager?.getQueryParams() || {}\r\n };\r\n\r\n // \uBAA8\uBC14\uC77C \uBA54\uB274 \uC804\uC5ED \uD568\uC218 \uCD94\uAC00\r\n\r\n newVueApp.mount(`#${newPageContainer.id}`);\r\n\r\n // requestAnimationFrame\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n requestAnimationFrame(() => {\r\n this.cleanupPreviousPages();\r\n this.transitionInProgress = false;\r\n });\r\n\r\n // \uC774\uC804 \uC571 \uC815\uB9AC \uC900\uBE44\r\n if (this.currentVueApp) {\r\n this.previousVueApp = this.currentVueApp;\r\n }\r\n \r\n this.currentVueApp = newVueApp;\r\n }\r\n\r\n cleanupPreviousPages() {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n // \uBC30\uCE58 DOM \uC870\uC791\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n const fragment = document.createDocumentFragment();\r\n const exitingContainers = appElement.querySelectorAll('.page-container.page-exiting');\r\n \r\n // \uD55C\uBC88\uC5D0 \uC81C\uAC70\r\n exitingContainers.forEach(container => container.remove());\r\n\r\n // \uC774\uC804 Vue \uC571 \uC815\uB9AC\r\n if (this.previousVueApp) {\r\n try {\r\n this.previousVueApp.unmount();\r\n } catch (error) {\r\n // \uBB34\uC2DC (\uC774\uBBF8 \uC5B8\uB9C8\uC6B4\uD2B8\uB41C \uACBD\uC6B0)\r\n }\r\n this.previousVueApp = null;\r\n }\r\n\r\n // \uB85C\uB529 \uC5D8\uB9AC\uBA3C\uD2B8 \uC81C\uAC70\r\n \r\n appElement.querySelector('.loading')?.remove();\r\n }\r\n\r\n applyStyle(css, routeName) {\r\n // \uAE30\uC874 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const existing = document.querySelector(`style[data-route=\"${routeName}\"]`);\r\n if (existing) existing.remove();\r\n\r\n if (css) {\r\n const style = document.createElement('style');\r\n style.textContent = css;\r\n style.setAttribute('data-route', routeName);\r\n document.head.appendChild(style);\r\n }\r\n }\r\n\r\n\r\n navigateTo(routeName, params = null) {\r\n // If routeName is an object, treat it as {route, params}\r\n if (typeof routeName === 'object') {\r\n params = routeName.params || null;\r\n routeName = routeName.route;\r\n }\r\n \r\n // Clear current query params if navigating to a different route\r\n if (routeName !== this.currentHash && this.queryManager) {\r\n this.queryManager.clearQueryParams();\r\n }\r\n \r\n // Set route parameters\r\n if (this.queryManager) {\r\n this.queryManager.setCurrentRouteParams(params);\r\n }\r\n \r\n // Update URL with new route and params\r\n this.updateURL(routeName, params);\r\n }\r\n\r\n getCurrentRoute() {\r\n return this.currentHash;\r\n }\r\n\r\n\r\n updateURL(route, params = null) {\r\n const queryParams = params || this.queryManager?.getQueryParams() || {};\r\n const queryString = this.queryManager?.buildQueryString(queryParams) || '';\r\n \r\n // URL \uBE4C\uB4DC \uCD5C\uC801\uD654\r\n const buildURL = (route, queryString, isHash = true) => {\r\n const base = route === 'home' ? '/' : `/${route}`;\r\n const url = queryString ? `${base}?${queryString}` : base;\r\n return isHash ? `#${url}` : url;\r\n };\r\n \r\n if (this.config.mode === 'hash') {\r\n const newHash = buildURL(route, queryString);\r\n \r\n // \uB3D9\uC77C\uD55C URL\uC774\uBA74 \uC5C5\uB370\uC774\uD2B8\uD558\uC9C0 \uC54A\uC74C (\uC131\uB2A5 \uCD5C\uC801\uD654)\r\n if (window.location.hash !== newHash) {\r\n window.location.hash = newHash;\r\n }\r\n } else {\r\n const newPath = buildURL(route, queryString, false);\r\n const isSameRoute = window.location.pathname === (route === 'home' ? '/' : `/${route}`);\r\n \r\n if (isSameRoute) {\r\n window.history.replaceState({}, '', newPath);\r\n } else {\r\n window.history.pushState({}, '', newPath);\r\n }\r\n this.handleRouteChange();\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD130 \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n window.removeEventListener(\r\n this.config.mode === 'hash' ? 'hashchange' : 'popstate',\r\n this._boundHandleRouteChange\r\n );\r\n \r\n // \uD604\uC7AC Vue \uC571 \uC5B8\uB9C8\uC6B4\uD2B8\r\n if (this.currentVueApp) {\r\n this.currentVueApp.unmount();\r\n this.currentVueApp = null;\r\n }\r\n \r\n // \uC774\uC804 Vue \uC571 \uC5B8\uB9C8\uC6B4\uD2B8\r\n if (this.previousVueApp) {\r\n this.previousVueApp.unmount();\r\n this.previousVueApp = null;\r\n }\r\n \r\n // \uB9E4\uB2C8\uC800 \uC815\uB9AC\r\n Object.values(this).forEach(manager => {\r\n if (manager && typeof manager.destroy === 'function') {\r\n manager.destroy();\r\n }\r\n });\r\n \r\n // \uCE90\uC2DC \uD074\uB9AC\uC5B4\r\n this.cacheManager?.clearAll();\r\n \r\n // DOM \uC815\uB9AC\r\n const appElement = document.getElementById('app');\r\n if (appElement) {\r\n appElement.innerHTML = '';\r\n }\r\n \r\n this.log('info', 'Router destroyed');\r\n }\r\n}\r\n// \uC804\uC5ED \uB77C\uC6B0\uD130\uB294 index.html\uC5D0\uC11C \uD658\uACBD\uC124\uC815\uACFC \uD568\uAED8 \uC0DD\uC131\uB428"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["isAuthenticated", "route", "queryString"]
|
|
4
|
+
"sourcesContent": ["/**\r\n * ViewLogic Internationalization System\r\n * \uB2E4\uAD6D\uC5B4 \uC9C0\uC6D0 \uC2DC\uC2A4\uD15C\r\n */\r\nexport class I18nManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enabled: options.useI18n !== undefined ? options.useI18n : true,\r\n defaultLanguage: options.defaultLanguage || 'ko',\r\n fallbackLanguage: options.defaultLanguage || 'ko',\r\n cacheKey: options.cacheKey || 'viewlogic_lang',\r\n dataCacheKey: options.dataCacheKey || 'viewlogic_i18n_data',\r\n cacheVersion: options.cacheVersion || '1.0.0',\r\n enableDataCache: options.enableDataCache !== false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC694\uC2DC \uC5B8\uC5B4 \uBCC0\uACBD \uC2DC \uB77C\uC6B0\uD130 \uC0C1\uD0DC \uC5C5\uB370\uC774\uD2B8)\r\n this.router = router;\r\n \r\n this.messages = new Map();\r\n this.currentLanguage = this.config.defaultLanguage;\r\n this.isLoading = false;\r\n this.loadPromises = new Map();\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108\uB4E4\r\n this.listeners = {\r\n languageChanged: []\r\n };\r\n \r\n // \uBE44\uB3D9\uAE30 \uCD08\uAE30\uD654 \uC2DC\uC791 (constructor \uB0B4\uC5D0\uC11C\uB294 await \uBD88\uAC00)\r\n this.initPromise = this.init();\r\n }\r\n\r\n async init() {\r\n // i18n\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uCD08\uAE30\uD654\uD558\uC9C0 \uC54A\uC74C\r\n if (!this.config.enabled) {\r\n this.log('info', 'I18n system disabled');\r\n return;\r\n }\r\n \r\n // \uCE90\uC2DC\uC5D0\uC11C \uC5B8\uC5B4 \uC124\uC815 \uB85C\uB4DC\r\n this.loadLanguageFromCache();\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uCE90\uC2DC \uBE44\uD65C\uC131\uD654\r\n if (this.config.debug) {\r\n this.config.enableDataCache = false;\r\n this.log('debug', 'Data cache disabled in debug mode');\r\n }\r\n \r\n // \uCD08\uAE30 \uC5B8\uC5B4 \uD30C\uC77C \uC790\uB3D9 \uB85C\uB4DC (\uC544\uC9C1 \uB85C\uB4DC\uB418\uC9C0 \uC54A\uC740 \uACBD\uC6B0\uC5D0\uB9CC)\r\n if (!this.messages.has(this.currentLanguage)) {\r\n try {\r\n await this.loadMessages(this.currentLanguage);\r\n } catch (error) {\r\n this.log('error', 'Failed to load initial language file:', error);\r\n // \uD3F4\uBC31\uC73C\uB85C \uBE48 \uBA54\uC2DC\uC9C0 \uAC1D\uCCB4 \uC124\uC815\uD558\uC5EC \uC2DC\uC2A4\uD15C\uC774 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D\r\n this.messages.set(this.currentLanguage, {});\r\n this.log('info', 'Using empty message object as fallback');\r\n }\r\n } else {\r\n this.log('debug', 'Language messages already loaded:', this.currentLanguage);\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC\uC5D0\uC11C \uC5B8\uC5B4 \uC124\uC815 \uB85C\uB4DC\r\n */\r\n loadLanguageFromCache() {\r\n try {\r\n const cachedLang = localStorage.getItem(this.config.cacheKey);\r\n if (cachedLang && this.isValidLanguage(cachedLang)) {\r\n this.currentLanguage = cachedLang;\r\n this.log('debug', 'Language loaded from cache:', cachedLang);\r\n }\r\n } catch (error) {\r\n this.log('warn', 'Failed to load language from cache:', error);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n */\r\n isValidLanguage(lang) {\r\n return typeof lang === 'string' && /^[a-z]{2}$/.test(lang);\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC5B8\uC5B4 \uBC18\uD658\r\n */\r\n getCurrentLanguage() {\r\n return this.currentLanguage;\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD\r\n */\r\n async setLanguage(language) {\r\n if (!this.isValidLanguage(language)) {\r\n this.log('warn', 'Invalid language code:', language);\r\n return false;\r\n }\r\n\r\n if (this.currentLanguage === language) {\r\n this.log('debug', 'Language already set to:', language);\r\n return true;\r\n }\r\n\r\n const oldLanguage = this.currentLanguage;\r\n this.currentLanguage = language;\r\n\r\n try {\r\n // \uC5B8\uC5B4 \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uD574\uB3C4 \uBE48 \uAC1D\uCCB4\uB77C\uB3C4 \uBC1B\uC744 \uC218 \uC788\uB3C4\uB85D)\r\n await this.loadMessages(language);\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n this.saveLanguageToCache(language);\r\n \r\n // \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n this.emit('languageChanged', {\r\n from: oldLanguage,\r\n to: language,\r\n messages: this.messages.get(language)\r\n });\r\n \r\n this.log('info', 'Language changed successfully', { from: oldLanguage, to: language });\r\n return true;\r\n } catch (error) {\r\n // \uC2E4\uD328\uD574\uB3C4 \uC5B8\uC5B4\uB294 \uBCC0\uACBD\uD558\uB418, \uBE48 \uBA54\uC2DC\uC9C0 \uAC1D\uCCB4 \uC0AC\uC6A9\r\n this.log('error', 'Failed to load messages for language change, using empty messages:', error);\r\n this.messages.set(language, {});\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n this.saveLanguageToCache(language);\r\n \r\n // \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n this.emit('languageChanged', {\r\n from: oldLanguage,\r\n to: language,\r\n messages: {},\r\n error: true\r\n });\r\n \r\n this.log('warn', 'Language changed with empty messages', { from: oldLanguage, to: language });\r\n return true; // true \uBC18\uD658\uD558\uC5EC \uB77C\uC6B0\uD130\uAC00 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uB97C \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n */\r\n saveLanguageToCache(language) {\r\n try {\r\n localStorage.setItem(this.config.cacheKey, language);\r\n this.log('debug', 'Language saved to cache:', language);\r\n } catch (error) {\r\n this.log('warn', 'Failed to save language to cache:', error);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBA54\uC2DC\uC9C0 \uD30C\uC77C \uB85C\uB4DC\r\n */\r\n async loadMessages(language) {\r\n // \uC774\uBBF8 \uB85C\uB4DC\uB41C \uACBD\uC6B0\r\n if (this.messages.has(language)) {\r\n this.log('debug', 'Messages already loaded for:', language);\r\n return this.messages.get(language);\r\n }\r\n\r\n // \uC774\uBBF8 \uB85C\uB529 \uC911\uC778 \uACBD\uC6B0\r\n if (this.loadPromises.has(language)) {\r\n this.log('debug', 'Messages loading in progress for:', language);\r\n return await this.loadPromises.get(language);\r\n }\r\n\r\n const loadPromise = this._loadMessagesFromFile(language);\r\n this.loadPromises.set(language, loadPromise);\r\n\r\n try {\r\n const messages = await loadPromise;\r\n this.messages.set(language, messages);\r\n this.loadPromises.delete(language);\r\n this.log('debug', 'Messages loaded successfully for:', language);\r\n return messages;\r\n } catch (error) {\r\n this.loadPromises.delete(language);\r\n // \uC2E4\uD328\uD574\uB3C4 \uBE48 \uAC1D\uCCB4 \uC124\uC815\uD558\uC5EC \uC2DC\uC2A4\uD15C\uC774 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D\r\n this.log('error', 'Failed to load messages, using empty fallback for:', language, error);\r\n const emptyMessages = {};\r\n this.messages.set(language, emptyMessages);\r\n return emptyMessages;\r\n }\r\n }\r\n\r\n /**\r\n * \uD30C\uC77C\uC5D0\uC11C \uBA54\uC2DC\uC9C0 \uB85C\uB4DC (\uCE90\uC2F1 \uC9C0\uC6D0)\r\n */\r\n async _loadMessagesFromFile(language) {\r\n // \uCE90\uC2DC\uC5D0\uC11C \uBA3C\uC800 \uC2DC\uB3C4\r\n if (this.config.enableDataCache) {\r\n const cachedData = this.getDataFromCache(language);\r\n if (cachedData) {\r\n this.log('debug', 'Messages loaded from cache:', language);\r\n return cachedData;\r\n }\r\n }\r\n \r\n try {\r\n // JSON \uD30C\uC77C\uB85C \uBCC0\uACBD - config\uC758 i18nPath \uC0AC\uC6A9\r\n const i18nPath = `${this.router.config.i18nPath}/${language}.json`;\r\n const response = await fetch(i18nPath);\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n const messages = await response.json();\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n if (this.config.enableDataCache) {\r\n this.saveDataToCache(language, messages);\r\n }\r\n \r\n return messages;\r\n } catch (error) {\r\n this.log('error', 'Failed to load messages file for:', language, error);\r\n \r\n // \uD3F4\uBC31 \uC5B8\uC5B4 \uC2DC\uB3C4\r\n if (language !== this.config.fallbackLanguage) {\r\n this.log('info', 'Trying fallback language:', this.config.fallbackLanguage);\r\n try {\r\n return await this._loadMessagesFromFile(this.config.fallbackLanguage);\r\n } catch (fallbackError) {\r\n this.log('error', 'Fallback language also failed:', fallbackError);\r\n // \uD3F4\uBC31\uB3C4 \uC2E4\uD328\uD558\uBA74 \uBE48 \uAC1D\uCCB4 \uBC18\uD658\uD558\uC5EC \uC2DC\uC2A4\uD15C\uC774 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D\r\n return {};\r\n }\r\n }\r\n \r\n // \uB9C8\uC9C0\uB9C9 \uD3F4\uBC31: \uBE48 \uAC1D\uCCB4 \uBC18\uD658\r\n this.log('warn', `No messages available for language: ${language}, using empty fallback`);\r\n return {};\r\n }\r\n }\r\n \r\n /**\r\n * \uC5B8\uC5B4 \uB370\uC774\uD130\uB97C \uCE90\uC2DC\uC5D0\uC11C \uAC00\uC838\uC624\uAE30\r\n */\r\n getDataFromCache(language) {\r\n try {\r\n const cacheKey = `${this.config.dataCacheKey}_${language}_${this.config.cacheVersion}`;\r\n const cachedItem = localStorage.getItem(cacheKey);\r\n \r\n if (cachedItem) {\r\n const { data, timestamp, version } = JSON.parse(cachedItem);\r\n \r\n // \uBC84\uC804 \uD655\uC778\r\n if (version !== this.config.cacheVersion) {\r\n this.log('debug', 'Cache version mismatch, clearing:', language);\r\n localStorage.removeItem(cacheKey);\r\n return null;\r\n }\r\n \r\n // TTL \uD655\uC778 (24\uC2DC\uAC04)\r\n const now = Date.now();\r\n const maxAge = 24 * 60 * 60 * 1000; // 24\uC2DC\uAC04\r\n \r\n if (now - timestamp > maxAge) {\r\n this.log('debug', 'Cache expired, removing:', language);\r\n localStorage.removeItem(cacheKey);\r\n return null;\r\n }\r\n \r\n return data;\r\n }\r\n } catch (error) {\r\n this.log('warn', 'Failed to read from cache:', error);\r\n }\r\n \r\n return null;\r\n }\r\n \r\n /**\r\n * \uC5B8\uC5B4 \uB370\uC774\uD130\uB97C \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n */\r\n saveDataToCache(language, data) {\r\n try {\r\n const cacheKey = `${this.config.dataCacheKey}_${language}_${this.config.cacheVersion}`;\r\n const cacheItem = {\r\n data,\r\n timestamp: Date.now(),\r\n version: this.config.cacheVersion\r\n };\r\n \r\n localStorage.setItem(cacheKey, JSON.stringify(cacheItem));\r\n this.log('debug', 'Data saved to cache:', language);\r\n } catch (error) {\r\n this.log('warn', 'Failed to save to cache:', error);\r\n }\r\n }\r\n\r\n /**\r\n * \uBA54\uC2DC\uC9C0 \uBC88\uC5ED\r\n */\r\n t(key, params = {}) {\r\n // i18n\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uD0A4 \uC790\uCCB4\uB97C \uBC18\uD658\r\n if (!this.config.enabled) {\r\n return key;\r\n }\r\n \r\n const messages = this.messages.get(this.currentLanguage);\r\n if (!messages) {\r\n this.log('warn', 'No messages loaded for current language:', this.currentLanguage);\r\n return key;\r\n }\r\n\r\n const message = this.getNestedValue(messages, key);\r\n if (message === undefined) {\r\n this.log('warn', 'Translation not found for key:', key);\r\n \r\n // \uD3F4\uBC31 \uC5B8\uC5B4\uC5D0\uC11C \uCC3E\uAE30\r\n const fallbackMessages = this.messages.get(this.config.fallbackLanguage);\r\n if (fallbackMessages && this.currentLanguage !== this.config.fallbackLanguage) {\r\n const fallbackMessage = this.getNestedValue(fallbackMessages, key);\r\n if (fallbackMessage !== undefined) {\r\n return this.interpolate(fallbackMessage, params);\r\n }\r\n }\r\n \r\n return key;\r\n }\r\n\r\n return this.interpolate(message, params);\r\n }\r\n\r\n /**\r\n * \uC911\uCCA9\uB41C \uAC1D\uCCB4\uC5D0\uC11C \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getNestedValue(obj, path) {\r\n return path.split('.').reduce((current, key) => {\r\n return current && current[key] !== undefined ? current[key] : undefined;\r\n }, obj);\r\n }\r\n\r\n /**\r\n * \uBB38\uC790\uC5F4 \uBCF4\uAC04 \uCC98\uB9AC\r\n */\r\n interpolate(message, params) {\r\n if (typeof message !== 'string') {\r\n return message;\r\n }\r\n\r\n return message.replace(/\\{(\\w+)\\}/g, (match, key) => {\r\n return params.hasOwnProperty(key) ? params[key] : match;\r\n });\r\n }\r\n\r\n /**\r\n * \uBCF5\uC218\uD615 \uCC98\uB9AC\r\n */\r\n plural(key, count, params = {}) {\r\n const pluralKey = count === 1 ? `${key}.singular` : `${key}.plural`;\r\n return this.t(pluralKey, { ...params, count });\r\n }\r\n\r\n /**\r\n * \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC5B8\uC5B4 \uBAA9\uB85D\r\n */\r\n getAvailableLanguages() {\r\n return ['ko', 'en']; // \uCD94\uD6C4 \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\uD558\uB3C4\uB85D \uBCC0\uACBD \uAC00\uB2A5\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D\r\n */\r\n on(event, callback) {\r\n if (this.listeners[event]) {\r\n this.listeners[event].push(callback);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4 \uBCC0\uACBD \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n */\r\n off(event, callback) {\r\n if (this.listeners[event]) {\r\n const index = this.listeners[event].indexOf(callback);\r\n if (index > -1) {\r\n this.listeners[event].splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n */\r\n emit(event, data) {\r\n if (this.listeners[event]) {\r\n this.listeners[event].forEach(callback => {\r\n try {\r\n callback(data);\r\n } catch (error) {\r\n this.log('error', 'Error in event listener:', error);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC5B8\uC5B4\uC758 \uBAA8\uB4E0 \uBA54\uC2DC\uC9C0 \uBC18\uD658\r\n */\r\n getMessages() {\r\n return this.messages.get(this.currentLanguage) || {};\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uBCC4 \uB0A0\uC9DC \uD3EC\uB9F7\uD305\r\n */\r\n formatDate(date, options = {}) {\r\n const locale = this.currentLanguage === 'ko' ? 'ko-KR' : 'en-US';\r\n return new Intl.DateTimeFormat(locale, options).format(new Date(date));\r\n }\r\n\r\n /**\r\n * \uC5B8\uC5B4\uBCC4 \uC22B\uC790 \uD3EC\uB9F7\uD305\r\n */\r\n formatNumber(number, options = {}) {\r\n const locale = this.currentLanguage === 'ko' ? 'ko-KR' : 'en-US';\r\n return new Intl.NumberFormat(locale, options).format(number);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'I18nManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * i18n \uD65C\uC131\uD654 \uC5EC\uBD80 \uD655\uC778\r\n */\r\n isEnabled() {\r\n return this.config.enabled;\r\n }\r\n \r\n /**\r\n * \uCD08\uAE30 \uB85C\uB529\uC774 \uC644\uB8CC\uB418\uC5C8\uB294\uC9C0 \uD655\uC778\r\n */\r\n async isReady() {\r\n if (!this.config.enabled) {\r\n return true;\r\n }\r\n \r\n try {\r\n await this.initPromise;\r\n return true;\r\n } catch (error) {\r\n this.log('error', 'I18n initialization failed:', error);\r\n // \uC2E4\uD328\uD574\uB3C4 \uB77C\uC6B0\uD130\uAC00 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D true \uBC18\uD658\r\n this.log('info', 'I18n system ready with fallback behavior');\r\n return true;\r\n }\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uCD08\uAE30\uD654 (\uBC84\uC804 \uBCC0\uACBD \uC2DC \uC0AC\uC6A9)\r\n */\r\n clearCache() {\r\n try {\r\n const keys = Object.keys(localStorage);\r\n const cacheKeys = keys.filter(key => key.startsWith(this.config.dataCacheKey));\r\n \r\n cacheKeys.forEach(key => {\r\n localStorage.removeItem(key);\r\n });\r\n \r\n this.log('debug', 'Cache cleared, removed', cacheKeys.length, 'items');\r\n } catch (error) {\r\n this.log('warn', 'Failed to clear cache:', error);\r\n }\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uC0C1\uD0DC \uD655\uC778\r\n */\r\n getCacheInfo() {\r\n const info = {\r\n enabled: this.config.enableDataCache,\r\n version: this.config.cacheVersion,\r\n languages: {}\r\n };\r\n \r\n try {\r\n const keys = Object.keys(localStorage);\r\n const cacheKeys = keys.filter(key => key.startsWith(this.config.dataCacheKey));\r\n \r\n cacheKeys.forEach(key => {\r\n const match = key.match(new RegExp(`${this.config.dataCacheKey}_(\\w+)_(.+)`));\r\n if (match) {\r\n const [, language, version] = match;\r\n const cachedItem = JSON.parse(localStorage.getItem(key));\r\n \r\n info.languages[language] = {\r\n version,\r\n timestamp: cachedItem.timestamp,\r\n age: Date.now() - cachedItem.timestamp\r\n };\r\n }\r\n });\r\n } catch (error) {\r\n this.log('warn', 'Failed to get cache info:', error);\r\n }\r\n \r\n return info;\r\n }\r\n \r\n /**\r\n * \uC2DC\uC2A4\uD15C \uCD08\uAE30\uD654 (\uD604\uC7AC \uC5B8\uC5B4\uC758 \uBA54\uC2DC\uC9C0 \uB85C\uB4DC)\r\n */\r\n async initialize() {\r\n if (!this.config.enabled) {\r\n this.log('info', 'I18n system is disabled, skipping initialization');\r\n return true;\r\n }\r\n \r\n try {\r\n // \uCD08\uAE30 \uC124\uC815\uC774 \uC644\uB8CC\uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30\r\n await this.initPromise;\r\n this.log('info', 'I18n system fully initialized');\r\n return true;\r\n } catch (error) {\r\n this.log('error', 'Failed to initialize I18n system:', error);\r\n // \uC2E4\uD328\uD574\uB3C4 \uC2DC\uC2A4\uD15C\uC740 \uACC4\uC18D \uC791\uB3D9\uD558\uB3C4\uB85D true \uBC18\uD658\r\n this.log('info', 'I18n system will continue with fallback behavior');\r\n return true;\r\n }\r\n }\r\n}", "/**\r\n * ViewLogic Authentication Management System\r\n * \uC778\uC99D \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class AuthManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enabled: options.authEnabled || false,\r\n loginRoute: options.loginRoute || 'login',\r\n protectedRoutes: options.protectedRoutes || [],\r\n protectedPrefixes: options.protectedPrefixes || [],\r\n publicRoutes: options.publicRoutes || ['login', 'register', 'home'],\r\n checkAuthFunction: options.checkAuthFunction || null,\r\n redirectAfterLogin: options.redirectAfterLogin || 'home',\r\n // \uCFE0\uD0A4/\uC2A4\uD1A0\uB9AC\uC9C0 \uC124\uC815\r\n authCookieName: options.authCookieName || 'authToken',\r\n authFallbackCookieNames: options.authFallbackCookieNames || ['accessToken', 'token', 'jwt'],\r\n authStorage: options.authStorage || 'cookie',\r\n authCookieOptions: options.authCookieOptions || {},\r\n authSkipValidation: options.authSkipValidation || false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC218 \uC758\uC874\uC131)\r\n this.router = router;\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108\uB4E4\r\n this.eventListeners = new Map();\r\n \r\n this.log('info', 'AuthManager initialized', { enabled: this.config.enabled });\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'AuthManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD2B8 \uC778\uC99D \uD655\uC778\r\n */\r\n async checkAuthentication(routeName) {\r\n // \uC778\uC99D \uC2DC\uC2A4\uD15C\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0\r\n if (!this.config.enabled) {\r\n return { allowed: true, reason: 'auth_disabled' };\r\n }\r\n\r\n this.log('debug', `\uD83D\uDD10 Checking authentication for route: ${routeName}`);\r\n\r\n // \uACF5\uAC1C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n if (this.isPublicRoute(routeName)) {\r\n return { allowed: true, reason: 'public_route' };\r\n }\r\n\r\n // \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n const isProtected = this.isProtectedRoute(routeName);\r\n if (!isProtected) {\r\n return { allowed: true, reason: 'not_protected' };\r\n }\r\n\r\n // \uC0AC\uC6A9\uC790 \uC815\uC758 \uC778\uC99D \uCCB4\uD06C \uD568\uC218\uAC00 \uC788\uB294 \uACBD\uC6B0\r\n if (typeof this.config.checkAuthFunction === 'function') {\r\n try {\r\n const isAuthenticated = await this.config.checkAuthFunction(routeName);\r\n return {\r\n allowed: isAuthenticated, \r\n reason: isAuthenticated ? 'custom_auth_success' : 'custom_auth_failed',\r\n routeName\r\n };\r\n } catch (error) {\r\n this.log('error', 'Custom auth function failed:', error);\r\n return { allowed: false, reason: 'custom_auth_error', error };\r\n }\r\n }\r\n\r\n // \uAE30\uBCF8 \uC778\uC99D \uD655\uC778\r\n const isAuthenticated = this.isUserAuthenticated();\r\n return {\r\n allowed: isAuthenticated, \r\n reason: isAuthenticated ? 'authenticated' : 'not_authenticated',\r\n routeName\r\n };\r\n }\r\n\r\n /**\r\n * \uC0AC\uC6A9\uC790 \uC778\uC99D \uC0C1\uD0DC \uD655\uC778\r\n */\r\n isUserAuthenticated() {\r\n this.log('debug', '\uD83D\uDD0D Checking user authentication status');\r\n\r\n // 1. localStorage \uD655\uC778\r\n const token = localStorage.getItem('authToken') || localStorage.getItem('accessToken');\r\n if (token) {\r\n try {\r\n if (token.includes('.')) {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('debug', 'localStorage token expired, removing...');\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n return false;\r\n }\r\n }\r\n this.log('debug', '\u2705 Valid token found in localStorage');\r\n return true;\r\n } catch (error) {\r\n this.log('warn', 'Invalid token in localStorage:', error);\r\n }\r\n }\r\n\r\n // 2. sessionStorage \uD655\uC778\r\n const sessionToken = sessionStorage.getItem('authToken') || sessionStorage.getItem('accessToken');\r\n if (sessionToken) {\r\n this.log('debug', '\u2705 Token found in sessionStorage');\r\n return true;\r\n }\r\n\r\n // 3. \uCFE0\uD0A4 \uD655\uC778\r\n const authCookie = this.getAuthCookie();\r\n if (authCookie) {\r\n try {\r\n if (authCookie.includes('.')) {\r\n const payload = JSON.parse(atob(authCookie.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('debug', 'Cookie token expired, removing...');\r\n this.removeAuthCookie();\r\n return false;\r\n }\r\n }\r\n this.log('debug', '\u2705 Valid token found in cookies');\r\n return true;\r\n } catch (error) {\r\n this.log('warn', 'Cookie token validation failed:', error);\r\n }\r\n }\r\n\r\n // 4. \uC804\uC5ED \uBCC0\uC218 \uD655\uC778 (\uB808\uAC70\uC2DC \uC9C0\uC6D0)\r\n if (window.user || window.isAuthenticated) {\r\n this.log('debug', '\u2705 Global authentication variable found');\r\n return true;\r\n }\r\n\r\n this.log('debug', '\u274C No valid authentication found');\r\n return false;\r\n }\r\n\r\n /**\r\n * \uACF5\uAC1C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n */\r\n isPublicRoute(routeName) {\r\n return this.config.publicRoutes.includes(routeName);\r\n }\r\n\r\n /**\r\n * \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n */\r\n isProtectedRoute(routeName) {\r\n // \uD2B9\uC815 \uB77C\uC6B0\uD2B8\uAC00 \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8 \uBAA9\uB85D\uC5D0 \uC788\uB294\uC9C0 \uD655\uC778\r\n if (this.config.protectedRoutes.includes(routeName)) {\r\n return true;\r\n }\r\n\r\n // prefix\uB85C \uBCF4\uD638\uB41C \uB77C\uC6B0\uD2B8\uC778\uC9C0 \uD655\uC778\r\n for (const prefix of this.config.protectedPrefixes) {\r\n if (routeName.startsWith(prefix)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uAC00\uC838\uC624\uAE30\r\n */\r\n getAuthCookie() {\r\n // \uC8FC \uCFE0\uD0A4 \uC774\uB984 \uD655\uC778\r\n const primaryCookie = this.getCookieValue(this.config.authCookieName);\r\n if (primaryCookie) {\r\n return primaryCookie;\r\n }\r\n\r\n // \uB300\uCCB4 \uCFE0\uD0A4 \uC774\uB984\uB4E4 \uD655\uC778\r\n for (const cookieName of this.config.authFallbackCookieNames) {\r\n const cookieValue = this.getCookieValue(cookieName);\r\n if (cookieValue) {\r\n this.log('debug', `Found auth token in fallback cookie: ${cookieName}`);\r\n return cookieValue;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * \uCFE0\uD0A4 \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getCookieValue(name) {\r\n const value = `; ${document.cookie}`;\r\n const parts = value.split(`; ${name}=`);\r\n if (parts.length === 2) {\r\n return decodeURIComponent(parts.pop().split(';').shift());\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uC81C\uAC70\r\n */\r\n removeAuthCookie() {\r\n const cookiesToRemove = [this.config.authCookieName, ...this.config.authFallbackCookieNames];\r\n \r\n cookiesToRemove.forEach(cookieName => {\r\n // \uD604\uC7AC \uACBD\uB85C\uC640 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0\uC11C \uBAA8\uB450 \uC81C\uAC70\r\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\r\n document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${window.location.pathname};`;\r\n });\r\n \r\n this.log('debug', 'Auth cookies removed');\r\n }\r\n\r\n /**\r\n * \uC561\uC138\uC2A4 \uD1A0\uD070 \uAC00\uC838\uC624\uAE30\r\n */\r\n getAccessToken() {\r\n // localStorage \uD655\uC778\r\n let token = localStorage.getItem('authToken') || localStorage.getItem('accessToken');\r\n if (token) return token;\r\n\r\n // sessionStorage \uD655\uC778\r\n token = sessionStorage.getItem('authToken') || sessionStorage.getItem('accessToken');\r\n if (token) return token;\r\n\r\n // \uCFE0\uD0A4 \uD655\uC778\r\n token = this.getAuthCookie();\r\n if (token) return token;\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * \uC561\uC138\uC2A4 \uD1A0\uD070 \uC124\uC815\r\n */\r\n setAccessToken(token, options = {}) {\r\n if (!token) {\r\n this.log('warn', 'Empty token provided');\r\n return false;\r\n }\r\n\r\n const {\r\n storage = this.config.authStorage,\r\n cookieOptions = this.config.authCookieOptions,\r\n skipValidation = this.config.authSkipValidation\r\n } = options;\r\n\r\n try {\r\n // JWT \uD1A0\uD070 \uAC80\uC99D (\uC635\uC158)\r\n if (!skipValidation && token.includes('.')) {\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp && Date.now() >= payload.exp * 1000) {\r\n this.log('warn', '\u274C Token is expired');\r\n return false;\r\n }\r\n this.log('debug', '\u2705 JWT token validated');\r\n } catch (error) {\r\n this.log('warn', '\u26A0\uFE0F JWT validation failed, but proceeding:', error.message);\r\n }\r\n }\r\n\r\n // \uC2A4\uD1A0\uB9AC\uC9C0\uBCC4 \uC800\uC7A5\r\n switch (storage) {\r\n case 'localStorage':\r\n localStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to localStorage');\r\n break;\r\n\r\n case 'sessionStorage':\r\n sessionStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to sessionStorage');\r\n break;\r\n\r\n case 'cookie':\r\n this.setAuthCookie(token, cookieOptions);\r\n break;\r\n\r\n default:\r\n // \uAE30\uBCF8\uAC12: localStorage\r\n localStorage.setItem('authToken', token);\r\n this.log('debug', 'Token saved to localStorage (default)');\r\n }\r\n\r\n this.emitAuthEvent('token_set', { \r\n storage,\r\n tokenLength: token.length,\r\n hasExpiration: token.includes('.')\r\n });\r\n\r\n return true;\r\n\r\n } catch (error) {\r\n this.log('Failed to set token:', error);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uCFE0\uD0A4 \uC124\uC815\r\n */\r\n setAuthCookie(token, options = {}) {\r\n const {\r\n cookieName = this.config.authCookieName,\r\n secure = window.location.protocol === 'https:',\r\n sameSite = 'Strict',\r\n path = '/',\r\n domain = null\r\n } = options;\r\n\r\n let cookieString = `${cookieName}=${encodeURIComponent(token)}; path=${path}`;\r\n\r\n if (secure) {\r\n cookieString += '; Secure';\r\n }\r\n\r\n if (sameSite) {\r\n cookieString += `; SameSite=${sameSite}`;\r\n }\r\n\r\n if (domain) {\r\n cookieString += `; Domain=${domain}`;\r\n }\r\n\r\n // JWT\uC5D0\uC11C \uB9CC\uB8CC \uC2DC\uAC04 \uCD94\uCD9C\r\n try {\r\n if (token.includes('.')) {\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1]));\r\n if (payload.exp) {\r\n const expireDate = new Date(payload.exp * 1000);\r\n cookieString += `; Expires=${expireDate.toUTCString()}`;\r\n }\r\n } catch (error) {\r\n this.log('Could not extract expiration from JWT token');\r\n }\r\n }\r\n } catch (error) {\r\n this.log('Token processing error:', error);\r\n }\r\n\r\n document.cookie = cookieString;\r\n this.log(`Auth cookie set: ${cookieName}`);\r\n }\r\n\r\n /**\r\n * \uD1A0\uD070 \uC81C\uAC70\r\n */\r\n removeAccessToken(storage = 'all') {\r\n switch (storage) {\r\n case 'localStorage':\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n break;\r\n\r\n case 'sessionStorage':\r\n sessionStorage.removeItem('authToken');\r\n sessionStorage.removeItem('accessToken');\r\n break;\r\n\r\n case 'cookie':\r\n this.removeAuthCookie();\r\n break;\r\n\r\n case 'all':\r\n default:\r\n localStorage.removeItem('authToken');\r\n localStorage.removeItem('accessToken');\r\n sessionStorage.removeItem('authToken');\r\n sessionStorage.removeItem('accessToken');\r\n this.removeAuthCookie();\r\n break;\r\n }\r\n\r\n this.emitAuthEvent('token_removed', { storage });\r\n this.log(`Token removed from: ${storage}`);\r\n }\r\n\r\n /**\r\n * \uB85C\uADF8\uC778 \uC131\uACF5 \uCC98\uB9AC\r\n */\r\n handleLoginSuccess(targetRoute = null) {\r\n const redirectRoute = targetRoute || this.config.redirectAfterLogin;\r\n \r\n this.log(`\uD83C\uDF89 Login success, redirecting to: ${redirectRoute}`);\r\n \r\n this.emitAuthEvent('login_success', { targetRoute: redirectRoute });\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC788\uC73C\uBA74 \uC9C1\uC811 \uB124\uBE44\uAC8C\uC774\uC158\r\n if (this.router && typeof this.router.navigateTo === 'function') {\r\n this.router.navigateTo(redirectRoute);\r\n }\r\n \r\n return redirectRoute;\r\n }\r\n\r\n /**\r\n * \uB85C\uADF8\uC544\uC6C3 \uCC98\uB9AC\r\n */\r\n handleLogout() {\r\n this.log('\uD83D\uDC4B Logging out user');\r\n \r\n // \uBAA8\uB4E0 \uC800\uC7A5\uC18C\uC5D0\uC11C \uD1A0\uD070 \uC81C\uAC70\r\n this.removeAccessToken();\r\n \r\n // \uC804\uC5ED \uBCC0\uC218 \uC815\uB9AC\r\n if (window.user) window.user = null;\r\n if (window.isAuthenticated) window.isAuthenticated = false;\r\n \r\n this.emitAuthEvent('logout', {});\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4\uAC00 \uC788\uC73C\uBA74 \uC9C1\uC811 \uB124\uBE44\uAC8C\uC774\uC158\r\n if (this.router && typeof this.router.navigateTo === 'function') {\r\n this.router.navigateTo(this.config.loginRoute);\r\n }\r\n \r\n return this.config.loginRoute;\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n */\r\n emitAuthEvent(eventType, data) {\r\n const event = new CustomEvent('router:auth', {\r\n detail: {\r\n type: eventType,\r\n timestamp: Date.now(),\r\n ...data\r\n }\r\n });\r\n \r\n document.dispatchEvent(event);\r\n \r\n // \uB0B4\uBD80 \uB9AC\uC2A4\uB108\uB4E4\uC5D0\uAC8C\uB3C4 \uC54C\uB9BC\r\n if (this.eventListeners.has(eventType)) {\r\n this.eventListeners.get(eventType).forEach(listener => {\r\n try {\r\n listener(data);\r\n } catch (error) {\r\n this.log('Event listener error:', error);\r\n }\r\n });\r\n }\r\n \r\n this.log(`\uD83D\uDD14 Auth event emitted: ${eventType}`, data);\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D\r\n */\r\n on(eventType, listener) {\r\n if (!this.eventListeners.has(eventType)) {\r\n this.eventListeners.set(eventType, []);\r\n }\r\n this.eventListeners.get(eventType).push(listener);\r\n }\r\n\r\n /**\r\n * \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n */\r\n off(eventType, listener) {\r\n if (this.eventListeners.has(eventType)) {\r\n const listeners = this.eventListeners.get(eventType);\r\n const index = listeners.indexOf(listener);\r\n if (index > -1) {\r\n listeners.splice(index, 1);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * \uC778\uC99D \uC0C1\uD0DC \uD1B5\uACC4\r\n */\r\n getAuthStats() {\r\n return {\r\n enabled: this.config.enabled,\r\n isAuthenticated: this.isUserAuthenticated(),\r\n hasToken: !!this.getAccessToken(),\r\n protectedRoutesCount: this.config.protectedRoutes.length,\r\n protectedPrefixesCount: this.config.protectedPrefixes.length,\r\n publicRoutesCount: this.config.publicRoutes.length,\r\n storage: this.config.authStorage,\r\n loginRoute: this.config.loginRoute\r\n };\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.eventListeners.clear();\r\n this.log('debug', 'AuthManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Cache Management System\r\n * \uCE90\uC2DC \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class CacheManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n cacheMode: options.cacheMode || 'memory', // 'memory' \uB610\uB294 'lru'\r\n cacheTTL: options.cacheTTL || 300000, // 5\uBD84 (\uBC00\uB9AC\uCD08)\r\n maxCacheSize: options.maxCacheSize || 50, // LRU \uCE90\uC2DC \uCD5C\uB300 \uD06C\uAE30\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870 (\uD544\uC694\uC2DC \uB77C\uC6B0\uD130 \uC0C1\uD0DC \uD655\uC778\uC6A9)\r\n this.router = router;\r\n \r\n // \uCE90\uC2DC \uC800\uC7A5\uC18C\uB4E4\r\n this.cache = new Map();\r\n this.cacheTimestamps = new Map();\r\n this.lruOrder = []; // LRU \uC21C\uC11C \uCD94\uC801\r\n \r\n this.log('info', 'CacheManager initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'CacheManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC\uC5D0 \uAC12 \uC800\uC7A5\r\n */\r\n setCache(key, value) {\r\n const now = Date.now();\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n // LRU \uCE90\uC2DC \uAD00\uB9AC\r\n if (this.cache.size >= this.config.maxCacheSize && !this.cache.has(key)) {\r\n const oldestKey = this.lruOrder.shift();\r\n if (oldestKey) {\r\n this.cache.delete(oldestKey);\r\n this.cacheTimestamps.delete(oldestKey);\r\n this.log('debug', `\uD83D\uDDD1\uFE0F LRU evicted cache key: ${oldestKey}`);\r\n }\r\n }\r\n \r\n // \uAE30\uC874 \uD0A4\uAC00 \uC788\uC73C\uBA74 LRU \uC21C\uC11C\uC5D0\uC11C \uC81C\uAC70\r\n const existingIndex = this.lruOrder.indexOf(key);\r\n if (existingIndex > -1) {\r\n this.lruOrder.splice(existingIndex, 1);\r\n }\r\n \r\n // \uCD5C\uC2E0 \uC21C\uC11C\uB85C \uCD94\uAC00\r\n this.lruOrder.push(key);\r\n }\r\n \r\n this.cache.set(key, value);\r\n this.cacheTimestamps.set(key, now);\r\n \r\n this.log('debug', `\uD83D\uDCBE Cached: ${key} (size: ${this.cache.size})`);\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC\uC5D0\uC11C \uAC12 \uAC00\uC838\uC624\uAE30\r\n */\r\n getFromCache(key) {\r\n const now = Date.now();\r\n const timestamp = this.cacheTimestamps.get(key);\r\n \r\n // TTL \uCCB4\uD06C\r\n if (timestamp && (now - timestamp) > this.config.cacheTTL) {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n \r\n this.log('debug', `\u23F0 Cache expired and removed: ${key}`);\r\n return null;\r\n }\r\n \r\n const value = this.cache.get(key);\r\n \r\n if (value && this.config.cacheMode === 'lru') {\r\n // LRU \uC21C\uC11C \uC5C5\uB370\uC774\uD2B8\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n this.lruOrder.push(key);\r\n }\r\n }\r\n \r\n if (value) {\r\n this.log('debug', `\uD83C\uDFAF Cache hit: ${key}`);\r\n } else {\r\n this.log('debug', `\u274C Cache miss: ${key}`);\r\n }\r\n \r\n return value;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC\uC5D0 \uD0A4\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n */\r\n hasCache(key) {\r\n return this.cache.has(key) && this.getFromCache(key) !== null;\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uD0A4 \uD328\uD134\uC758 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n invalidateByPattern(pattern) {\r\n const keysToDelete = [];\r\n \r\n for (const key of this.cache.keys()) {\r\n if (key.includes(pattern) || key.startsWith(pattern)) {\r\n keysToDelete.push(key);\r\n }\r\n }\r\n \r\n keysToDelete.forEach(key => {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n });\r\n \r\n this.log('debug', `\uD83E\uDDF9 Invalidated ${keysToDelete.length} cache entries matching: ${pattern}`);\r\n return keysToDelete.length;\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uCEF4\uD3EC\uB10C\uD2B8 \uCE90\uC2DC \uBB34\uD6A8\uD654\r\n */\r\n invalidateComponentCache(routeName) {\r\n const patterns = [\r\n `component_${routeName}`,\r\n `script_${routeName}`,\r\n `template_${routeName}`,\r\n `style_${routeName}`,\r\n `layout_${routeName}`\r\n ];\r\n \r\n let totalInvalidated = 0;\r\n patterns.forEach(pattern => {\r\n totalInvalidated += this.invalidateByPattern(pattern);\r\n });\r\n \r\n this.log(`\uD83D\uDD04 Invalidated component cache for route: ${routeName} (${totalInvalidated} entries)`);\r\n return totalInvalidated;\r\n }\r\n \r\n /**\r\n * \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n clearComponentCache() {\r\n const componentPatterns = ['component_', 'script_', 'template_', 'style_', 'layout_'];\r\n let totalCleared = 0;\r\n \r\n componentPatterns.forEach(pattern => {\r\n totalCleared += this.invalidateByPattern(pattern);\r\n });\r\n \r\n this.log(`\uD83E\uDDFD Cleared all component caches (${totalCleared} entries)`);\r\n return totalCleared;\r\n }\r\n \r\n /**\r\n * \uC804\uCCB4 \uCE90\uC2DC \uC0AD\uC81C\r\n */\r\n clearCache() {\r\n const size = this.cache.size;\r\n this.cache.clear();\r\n this.cacheTimestamps.clear();\r\n this.lruOrder = [];\r\n \r\n this.log(`\uD83D\uDD25 Cleared all cache (${size} entries)`);\r\n return size;\r\n }\r\n \r\n /**\r\n * \uB9CC\uB8CC\uB41C \uCE90\uC2DC \uD56D\uBAA9\uB4E4 \uC815\uB9AC\r\n */\r\n cleanExpiredCache() {\r\n const now = Date.now();\r\n const expiredKeys = [];\r\n \r\n for (const [key, timestamp] of this.cacheTimestamps.entries()) {\r\n if ((now - timestamp) > this.config.cacheTTL) {\r\n expiredKeys.push(key);\r\n }\r\n }\r\n \r\n expiredKeys.forEach(key => {\r\n this.cache.delete(key);\r\n this.cacheTimestamps.delete(key);\r\n \r\n if (this.config.cacheMode === 'lru') {\r\n const index = this.lruOrder.indexOf(key);\r\n if (index > -1) {\r\n this.lruOrder.splice(index, 1);\r\n }\r\n }\r\n });\r\n \r\n if (expiredKeys.length > 0) {\r\n this.log(`\u23F1\uFE0F Cleaned ${expiredKeys.length} expired cache entries`);\r\n }\r\n \r\n return expiredKeys.length;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uD1B5\uACC4 \uC815\uBCF4\r\n */\r\n getCacheStats() {\r\n return {\r\n size: this.cache.size,\r\n maxSize: this.config.maxCacheSize,\r\n mode: this.config.cacheMode,\r\n ttl: this.config.cacheTTL,\r\n memoryUsage: this.getMemoryUsage(),\r\n hitRatio: this.getHitRatio(),\r\n categories: this.getCategorizedStats()\r\n };\r\n }\r\n \r\n /**\r\n * \uBA54\uBAA8\uB9AC \uC0AC\uC6A9\uB7C9 \uCD94\uC815\r\n */\r\n getMemoryUsage() {\r\n let estimatedBytes = 0;\r\n \r\n for (const [key, value] of this.cache.entries()) {\r\n // \uD0A4 \uD06C\uAE30\r\n estimatedBytes += key.length * 2; // UTF-16\r\n \r\n // \uAC12 \uD06C\uAE30 \uCD94\uC815\r\n if (typeof value === 'string') {\r\n estimatedBytes += value.length * 2;\r\n } else if (typeof value === 'object' && value !== null) {\r\n estimatedBytes += JSON.stringify(value).length * 2;\r\n } else {\r\n estimatedBytes += 8; // \uB300\uB7B5\uC801\uC778 \uD06C\uAE30\r\n }\r\n }\r\n \r\n return {\r\n bytes: estimatedBytes,\r\n kb: Math.round(estimatedBytes / 1024 * 100) / 100,\r\n mb: Math.round(estimatedBytes / (1024 * 1024) * 100) / 100\r\n };\r\n }\r\n \r\n /**\r\n * \uD788\uD2B8 \uBE44\uC728 \uACC4\uC0B0 (\uAC04\uB2E8\uD55C \uCD94\uC815)\r\n */\r\n getHitRatio() {\r\n // \uC2E4\uC81C \uD788\uD2B8/\uBBF8\uC2A4 \uCD94\uC801\uC744 \uC704\uD574\uC11C\uB294 \uBCC4\uB3C4\uC758 \uCE74\uC6B4\uD130\uAC00 \uD544\uC694\r\n // \uD604\uC7AC\uB294 \uCE90\uC2DC \uD06C\uAE30 \uAE30\uBC18 \uCD94\uC815\uCE58 \uBC18\uD658\r\n const ratio = this.cache.size > 0 ? Math.min(this.cache.size / this.config.maxCacheSize, 1) : 0;\r\n return Math.round(ratio * 100);\r\n }\r\n \r\n /**\r\n * \uCE74\uD14C\uACE0\uB9AC\uBCC4 \uCE90\uC2DC \uD1B5\uACC4\r\n */\r\n getCategorizedStats() {\r\n const categories = {\r\n components: 0,\r\n scripts: 0,\r\n templates: 0,\r\n styles: 0,\r\n layouts: 0,\r\n others: 0\r\n };\r\n \r\n for (const key of this.cache.keys()) {\r\n if (key.startsWith('component_')) categories.components++;\r\n else if (key.startsWith('script_')) categories.scripts++;\r\n else if (key.startsWith('template_')) categories.templates++;\r\n else if (key.startsWith('style_')) categories.styles++;\r\n else if (key.startsWith('layout_')) categories.layouts++;\r\n else categories.others++;\r\n }\r\n \r\n return categories;\r\n }\r\n \r\n /**\r\n * \uCE90\uC2DC \uD0A4 \uBAA9\uB85D \uBC18\uD658\r\n */\r\n getCacheKeys() {\r\n return Array.from(this.cache.keys());\r\n }\r\n \r\n /**\r\n * \uD2B9\uC815 \uD328\uD134\uC758 \uCE90\uC2DC \uD0A4\uB4E4 \uBC18\uD658\r\n */\r\n getCacheKeysByPattern(pattern) {\r\n return this.getCacheKeys().filter(key => \r\n key.includes(pattern) || key.startsWith(pattern)\r\n );\r\n }\r\n \r\n /**\r\n * \uC790\uB3D9 \uC815\uB9AC \uC2DC\uC791 (\uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C \uB9CC\uB8CC\uB41C \uCE90\uC2DC \uC815\uB9AC)\r\n */\r\n startAutoCleanup(interval = 60000) { // \uAE30\uBCF8 1\uBD84 \uAC04\uACA9\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n }\r\n \r\n this.cleanupInterval = setInterval(() => {\r\n this.cleanExpiredCache();\r\n }, interval);\r\n \r\n this.log(`\uD83E\uDD16 Auto cleanup started (interval: ${interval}ms)`);\r\n }\r\n \r\n /**\r\n * \uC790\uB3D9 \uC815\uB9AC \uC911\uC9C0\r\n */\r\n stopAutoCleanup() {\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n this.log('debug', '\uD83D\uDED1 Auto cleanup stopped');\r\n }\r\n }\r\n \r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.stopAutoCleanup();\r\n this.clearCache();\r\n this.log('debug', 'CacheManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Query Management System\r\n * URL \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class QueryManager {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enableParameterValidation: options.enableParameterValidation !== false,\r\n logSecurityWarnings: options.logSecurityWarnings !== false,\r\n maxParameterLength: options.maxParameterLength || 1000,\r\n maxArraySize: options.maxArraySize || 100,\r\n maxParameterCount: options.maxParameterCount || 50,\r\n allowedKeyPattern: options.allowedKeyPattern || /^[a-zA-Z0-9_\\-]+$/,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n \r\n // \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC0C1\uD0DC\r\n this.currentQueryParams = {};\r\n \r\n // \uD604\uC7AC \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC0C1\uD0DC (navigateTo\uB85C \uC804\uB2EC\uB41C params)\r\n this.currentRouteParams = {};\r\n \r\n this.log('info', 'QueryManager initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'QueryManager', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uD30C\uB77C\uBBF8\uD130 \uAC12 sanitize (XSS, SQL Injection \uBC29\uC5B4)\r\n */\r\n sanitizeParameter(value) {\r\n if (typeof value !== 'string') return value;\r\n \r\n // XSS \uBC29\uC5B4: HTML \uD0DC\uADF8\uC640 \uC2A4\uD06C\uB9BD\uD2B8 \uC81C\uAC70\r\n let sanitized = value\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '') // script \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '') // iframe \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<object\\b[^<]*(?:(?!<\\/object>)<[^<]*)*<\\/object>/gi, '') // object \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<embed\\b[^<]*(?:(?!<\\/embed>)<[^<]*)*<\\/embed>/gi, '') // embed \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<link\\b[^<]*>/gi, '') // link \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/<meta\\b[^<]*>/gi, '') // meta \uD0DC\uADF8 \uC81C\uAC70\r\n .replace(/javascript:/gi, '') // javascript: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/vbscript:/gi, '') // vbscript: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/data:/gi, '') // data: \uD504\uB85C\uD1A0\uCF5C \uC81C\uAC70\r\n .replace(/on\\w+\\s*=/gi, '') // \uC774\uBCA4\uD2B8 \uD578\uB4E4\uB7EC \uC81C\uAC70 (onclick, onload \uB4F1)\r\n .replace(/expression\\s*\\(/gi, '') // CSS expression \uC81C\uAC70\r\n .replace(/url\\s*\\(/gi, ''); // CSS url() \uC81C\uAC70\r\n \r\n // SQL Injection \uBC29\uC5B4: \uC704\uD5D8\uD55C SQL \uD0A4\uC6CC\uB4DC \uD544\uD130\uB9C1\r\n const sqlPatterns = [\r\n /(\\b(union|select|insert|update|delete|drop|create|alter|exec|execute|sp_|xp_)\\b)/gi,\r\n /(;|\\||&|\\*|%|<|>)/g, // \uC704\uD5D8\uD55C \uD2B9\uC218\uBB38\uC790\r\n /(--|\\/\\*|\\*\\/)/g, // SQL \uC8FC\uC11D\r\n /(\\bor\\b.*\\b=\\b|\\band\\b.*\\b=\\b)/gi, // OR/AND \uC870\uAC74\uBB38\r\n /('.*'|\".*\")/g, // \uB530\uC634\uD45C\uB85C \uB458\uB7EC\uC2F8\uC778 \uBB38\uC790\uC5F4\r\n /(\\\\\\w+)/g // \uBC31\uC2AC\uB798\uC2DC \uC774\uC2A4\uCF00\uC774\uD504\r\n ];\r\n \r\n for (const pattern of sqlPatterns) {\r\n sanitized = sanitized.replace(pattern, '');\r\n }\r\n \r\n // \uCD94\uAC00 \uBCF4\uC548: \uC5F0\uC18D\uB41C \uD2B9\uC218\uBB38\uC790 \uC81C\uAC70\r\n sanitized = sanitized.replace(/[<>'\"&]{2,}/g, '');\r\n \r\n // \uAE38\uC774 \uC81C\uD55C (DoS \uBC29\uC5B4)\r\n if (sanitized.length > this.config.maxParameterLength) {\r\n sanitized = sanitized.substring(0, this.config.maxParameterLength);\r\n }\r\n \r\n return sanitized.trim();\r\n }\r\n\r\n /**\r\n * \uD30C\uB77C\uBBF8\uD130 \uC720\uD6A8\uC131 \uAC80\uC99D\r\n */\r\n validateParameter(key, value) {\r\n // \uBCF4\uC548 \uAC80\uC99D\uC774 \uBE44\uD65C\uC131\uD654\uB41C \uACBD\uC6B0 \uD1B5\uACFC\r\n if (!this.config.enableParameterValidation) {\r\n return true;\r\n }\r\n \r\n // \uD30C\uB77C\uBBF8\uD130 \uD0A4 \uAC80\uC99D\r\n if (typeof key !== 'string' || key.length === 0) {\r\n return false;\r\n }\r\n \r\n // \uD0A4 \uC774\uB984 \uC81C\uD55C\r\n if (!this.config.allowedKeyPattern.test(key)) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Invalid parameter key format: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uD0A4 \uAE38\uC774 \uC81C\uD55C\r\n if (key.length > 50) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter key too long: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uAC12 \uD0C0\uC785 \uAC80\uC99D\r\n if (value !== null && value !== undefined) {\r\n if (typeof value === 'string') {\r\n // \uBB38\uC790\uC5F4 \uAE38\uC774 \uC81C\uD55C\r\n if (value.length > this.config.maxParameterLength) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter value too long for key: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uC704\uD5D8\uD55C \uD328\uD134 \uAC10\uC9C0\r\n const dangerousPatterns = [\r\n /<script|<iframe|<object|<embed/gi,\r\n /javascript:|vbscript:|data:/gi,\r\n /union.*select|insert.*into|delete.*from/gi,\r\n /\\.\\.\\//g, // \uACBD\uB85C \uD0D0\uC0C9 \uACF5\uACA9\r\n /[<>'\"&]{3,}/g // \uC5F0\uC18D\uB41C \uD2B9\uC218\uBB38\uC790\r\n ];\r\n \r\n for (const pattern of dangerousPatterns) {\r\n if (pattern.test(value)) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Dangerous pattern detected in parameter ${key}:`, value);\r\n }\r\n return false;\r\n }\r\n }\r\n } else if (Array.isArray(value)) {\r\n // \uBC30\uC5F4 \uAE38\uC774 \uC81C\uD55C\r\n if (value.length > this.config.maxArraySize) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Parameter array too large for key: ${key}`);\r\n }\r\n return false;\r\n }\r\n \r\n // \uBC30\uC5F4 \uAC01 \uC694\uC18C \uAC80\uC99D\r\n for (const item of value) {\r\n if (!this.validateParameter(`${key}[]`, item)) {\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n \r\n return true;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC\uC2A4\uD2B8\uB9C1 \uD30C\uC2F1\r\n */\r\n parseQueryString(queryString) {\r\n const params = {};\r\n if (!queryString) return params;\r\n \r\n const pairs = queryString.split('&');\r\n for (const pair of pairs) {\r\n try {\r\n const [rawKey, rawValue] = pair.split('=');\r\n if (!rawKey) continue;\r\n \r\n let key, value;\r\n try {\r\n key = decodeURIComponent(rawKey);\r\n value = rawValue ? decodeURIComponent(rawValue) : '';\r\n } catch (e) {\r\n this.log('warn', 'Failed to decode URI component:', pair);\r\n continue;\r\n }\r\n \r\n // \uBCF4\uC548 \uAC80\uC99D\r\n if (!this.validateParameter(key, value)) {\r\n this.log('warn', `Parameter rejected by security filter: ${key}`);\r\n continue;\r\n }\r\n \r\n // \uAC12 sanitize\r\n const sanitizedValue = this.sanitizeParameter(value);\r\n \r\n // \uBC30\uC5F4 \uD615\uD0DC\uC758 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC (\uC608: tags[]=a&tags[]=b)\r\n if (key.endsWith('[]')) {\r\n const arrayKey = key.slice(0, -2);\r\n \r\n // \uBC30\uC5F4 \uD0A4\uB3C4 \uAC80\uC99D\r\n if (!this.validateParameter(arrayKey, [])) {\r\n continue;\r\n }\r\n \r\n if (!params[arrayKey]) params[arrayKey] = [];\r\n \r\n // \uBC30\uC5F4 \uD06C\uAE30 \uC81C\uD55C\r\n if (params[arrayKey].length < this.config.maxArraySize) {\r\n params[arrayKey].push(sanitizedValue);\r\n } else {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Array parameter ${arrayKey} size limit exceeded`);\r\n }\r\n }\r\n } else {\r\n params[key] = sanitizedValue;\r\n }\r\n } catch (error) {\r\n this.log('error', 'Error parsing query parameter:', pair, error);\r\n }\r\n }\r\n \r\n // \uC804\uCCB4 \uD30C\uB77C\uBBF8\uD130 \uAC1C\uC218 \uC81C\uD55C\r\n const paramCount = Object.keys(params).length;\r\n if (paramCount > this.config.maxParameterCount) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Too many parameters (${paramCount}). Limiting to first ${this.config.maxParameterCount}.`);\r\n }\r\n const limitedParams = {};\r\n let count = 0;\r\n for (const [key, value] of Object.entries(params)) {\r\n if (count >= this.config.maxParameterCount) break;\r\n limitedParams[key] = value;\r\n count++;\r\n }\r\n return limitedParams;\r\n }\r\n \r\n return params;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC\uC2A4\uD2B8\uB9C1 \uC0DD\uC131\r\n */\r\n buildQueryString(params) {\r\n if (!params || Object.keys(params).length === 0) return '';\r\n \r\n const pairs = [];\r\n for (const [key, value] of Object.entries(params)) {\r\n if (Array.isArray(value)) {\r\n // \uBC30\uC5F4 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC\r\n for (const item of value) {\r\n pairs.push(`${encodeURIComponent(key)}[]=${encodeURIComponent(item)}`);\r\n }\r\n } else if (value !== undefined && value !== null) {\r\n pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);\r\n }\r\n }\r\n return pairs.join('&');\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uBCC0\uACBD \uAC10\uC9C0\r\n */\r\n hasQueryParamsChanged(newParams) {\r\n if (!this.currentQueryParams && !newParams) return false;\r\n if (!this.currentQueryParams || !newParams) return true;\r\n \r\n const oldKeys = Object.keys(this.currentQueryParams);\r\n const newKeys = Object.keys(newParams);\r\n \r\n if (oldKeys.length !== newKeys.length) return true;\r\n \r\n for (const key of oldKeys) {\r\n if (JSON.stringify(this.currentQueryParams[key]) !== JSON.stringify(newParams[key])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC804\uCCB4 \uAC00\uC838\uC624\uAE30\r\n */\r\n getQueryParams() {\r\n return { ...this.currentQueryParams };\r\n }\r\n\r\n /**\r\n * \uD2B9\uC815 \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uAC00\uC838\uC624\uAE30\r\n */\r\n getQueryParam(key, defaultValue = undefined) {\r\n const value = this.currentQueryParams ? this.currentQueryParams[key] : undefined;\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC124\uC815\r\n */\r\n setQueryParams(params, replace = false) {\r\n if (!params || typeof params !== 'object') {\r\n console.warn('Invalid parameters object provided to setQueryParams');\r\n return;\r\n }\r\n \r\n const currentParams = replace ? {} : { ...this.currentQueryParams };\r\n const sanitizedParams = {};\r\n \r\n // \uD30C\uB77C\uBBF8\uD130 \uAC80\uC99D \uBC0F sanitize\r\n for (const [key, value] of Object.entries(params)) {\r\n // \uD0A4\uC640 \uAC12 \uAC80\uC99D\r\n if (!this.validateParameter(key, value)) {\r\n console.warn(`Parameter ${key} rejected by security filter`);\r\n continue;\r\n }\r\n \r\n // \uAC12 \uCC98\uB9AC\r\n if (value !== undefined && value !== null) {\r\n if (Array.isArray(value)) {\r\n sanitizedParams[key] = value.map(item => this.sanitizeParameter(item));\r\n } else {\r\n sanitizedParams[key] = this.sanitizeParameter(value);\r\n }\r\n }\r\n }\r\n \r\n // \uD604\uC7AC \uD30C\uB77C\uBBF8\uD130 \uC5C5\uB370\uC774\uD2B8\r\n Object.assign(currentParams, sanitizedParams);\r\n \r\n // undefined\uB098 null \uAC12 \uC81C\uAC70\r\n for (const [key, value] of Object.entries(currentParams)) {\r\n if (value === undefined || value === null || value === '') {\r\n delete currentParams[key];\r\n }\r\n }\r\n \r\n // \uCD5C\uB300 \uD30C\uB77C\uBBF8\uD130 \uAC1C\uC218 \uD655\uC778\r\n const paramCount = Object.keys(currentParams).length;\r\n if (paramCount > this.config.maxParameterCount) {\r\n if (this.config.logSecurityWarnings) {\r\n console.warn(`Too many parameters after update (${paramCount}). Some parameters may be dropped.`);\r\n }\r\n }\r\n \r\n this.currentQueryParams = currentParams;\r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC81C\uAC70\r\n */\r\n removeQueryParams(keys) {\r\n if (!keys) return;\r\n \r\n const keysToRemove = Array.isArray(keys) ? keys : [keys];\r\n for (const key of keysToRemove) {\r\n delete this.currentQueryParams[key];\r\n }\r\n \r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uCD08\uAE30\uD654\r\n */\r\n clearQueryParams() {\r\n this.currentQueryParams = {};\r\n this.updateURL();\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC124\uC815 (\uB77C\uC6B0\uD130\uC5D0\uC11C \uD638\uCD9C)\r\n */\r\n setCurrentQueryParams(params) {\r\n this.currentQueryParams = params || {};\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC124\uC815 (navigateTo\uC5D0\uC11C \uD638\uCD9C)\r\n */\r\n setCurrentRouteParams(params) {\r\n this.currentRouteParams = params || {};\r\n this.log('debug', 'Route params set:', this.currentRouteParams);\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uBC18\uD658 (\uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n */\r\n getAllParams() {\r\n return {\r\n ...this.currentRouteParams,\r\n ...this.currentQueryParams\r\n };\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uD2B9\uC815 \uD0A4 \uAC12 \uBC18\uD658\r\n */\r\n getParam(key, defaultValue = undefined) {\r\n // \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130\uAC00 \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uBCF4\uB2E4 \uC6B0\uC120\uC21C\uC704 \uB192\uC74C\r\n const value = this.currentQueryParams[key] !== undefined ? \r\n this.currentQueryParams[key] : \r\n this.currentRouteParams[key];\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uB9CC \uBC18\uD658\r\n */\r\n getRouteParams() {\r\n return { ...this.currentRouteParams };\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uD2B9\uC815 \uD0A4 \uAC12 \uBC18\uD658\r\n */\r\n getRouteParam(key, defaultValue = undefined) {\r\n const value = this.currentRouteParams[key];\r\n return value !== undefined ? value : defaultValue;\r\n }\r\n\r\n /**\r\n * URL \uC5C5\uB370\uC774\uD2B8 (\uB77C\uC6B0\uD130\uC758 updateURL \uBA54\uC18C\uB4DC \uD638\uCD9C)\r\n */\r\n updateURL() {\r\n if (this.router && typeof this.router.updateURL === 'function') {\r\n const route = this.router.currentHash || 'home';\r\n this.router.updateURL(route, this.currentQueryParams);\r\n }\r\n }\r\n\r\n /**\r\n * \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uD1B5\uACC4\r\n */\r\n getStats() {\r\n return {\r\n currentParams: Object.keys(this.currentQueryParams).length,\r\n maxAllowed: this.config.maxParameterCount,\r\n validationEnabled: this.config.enableParameterValidation,\r\n currentQueryString: this.buildQueryString(this.currentQueryParams)\r\n };\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.currentQueryParams = {};\r\n this.currentRouteParams = {};\r\n this.router = null;\r\n this.log('debug', 'QueryManager destroyed');\r\n }\r\n}", "/**\r\n * ViewLogic Route Loading System\r\n * \uB77C\uC6B0\uD2B8 \uB85C\uB529 \uBC0F \uCEF4\uD3EC\uB10C\uD2B8 \uAD00\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class RouteLoader {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n srcPath: options.srcPath || router.config.srcPath || '/src', // \uC18C\uC2A4 \uD30C\uC77C \uACBD\uB85C\r\n routesPath: options.routesPath || router.config.routesPath || '/routes', // \uD504\uB85C\uB355\uC158 \uB77C\uC6B0\uD2B8 \uACBD\uB85C\r\n environment: options.environment || 'development',\r\n useLayout: options.useLayout !== false,\r\n defaultLayout: options.defaultLayout || 'default',\r\n useComponents: options.useComponents !== false,\r\n debug: options.debug || false\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n this.log('debug', 'RouteLoader initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uC2A4\uD06C\uB9BD\uD2B8 \uD30C\uC77C \uB85C\uB4DC\r\n */\r\n async loadScript(routeName) {\r\n let script;\r\n try {\r\n if (this.config.environment === 'production') {\r\n // \uD504\uB85C\uB355\uC158 \uBAA8\uB4DC: routes \uD3F4\uB354\uC5D0\uC11C \uBE4C\uB4DC\uB41C JS \uB85C\uB4DC (\uC808\uB300 \uACBD\uB85C)\r\n const importPath = `${this.config.routesPath}/${routeName}.js`;\r\n this.log('debug', `Loading production route: ${importPath}`);\r\n const module = await import(importPath);\r\n script = module.default;\r\n } else {\r\n // \uAC1C\uBC1C \uBAA8\uB4DC: srcPath \uC0AC\uC6A9\uD558\uC5EC \uC18C\uC2A4 \uD30C\uC77C \uACBD\uB85C \uAD6C\uC131\r\n const importPath = `${this.config.srcPath}/logic/${routeName}.js`;\r\n this.log('debug', `Loading development route: ${importPath}`);\r\n const module = await import(importPath);\r\n script = module.default;\r\n }\r\n \r\n if (!script) {\r\n throw new Error(`Route '${routeName}' not found - no default export`);\r\n }\r\n \r\n } catch (error) {\r\n // import \uC5D0\uB7EC\uB97C 404\uB85C \uBD84\uB958\r\n if (error.message.includes('Failed to resolve') || \r\n error.message.includes('Failed to fetch') ||\r\n error.message.includes('not found') ||\r\n error.name === 'TypeError') {\r\n throw new Error(`Route '${routeName}' not found - 404`);\r\n }\r\n // \uB2E4\uB978 \uC5D0\uB7EC\uB294 \uADF8\uB300\uB85C \uC804\uD30C\r\n throw error;\r\n }\r\n \r\n return script;\r\n }\r\n\r\n /**\r\n * \uD15C\uD50C\uB9BF \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC \uAE30\uBCF8\uAC12 \uBC18\uD658)\r\n */\r\n async loadTemplate(routeName) {\r\n try {\r\n const templatePath = `${this.config.srcPath}/views/${routeName}.html`;\r\n const response = await fetch(templatePath);\r\n if (!response.ok) throw new Error(`Template not found: ${response.status}`);\r\n const template = await response.text();\r\n this.log('debug', `Template '${routeName}' loaded successfully`);\r\n return template;\r\n } catch (error) {\r\n this.log('warn', `Template '${routeName}' not found, using default:`, error.message);\r\n // \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uBC18\uD658\r\n return this.generateDefaultTemplate(routeName);\r\n }\r\n }\r\n\r\n /**\r\n * \uC2A4\uD0C0\uC77C \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC \uBE48 \uBB38\uC790\uC5F4 \uBC18\uD658)\r\n */\r\n async loadStyle(routeName) {\r\n try {\r\n const stylePath = `${this.config.srcPath}/styles/${routeName}.css`;\r\n const response = await fetch(stylePath);\r\n if (!response.ok) throw new Error(`Style not found: ${response.status}`);\r\n const style = await response.text();\r\n this.log('debug', `Style '${routeName}' loaded successfully`);\r\n return style;\r\n } catch (error) {\r\n this.log('debug', `Style '${routeName}' not found, no styles applied:`, error.message);\r\n // \uC2A4\uD0C0\uC77C\uC774 \uC5C6\uC73C\uBA74 \uBE48 \uBB38\uC790\uC5F4 \uBC18\uD658\r\n return '';\r\n }\r\n }\r\n\r\n /**\r\n * \uB808\uC774\uC544\uC6C3 \uD30C\uC77C \uB85C\uB4DC (\uC2E4\uD328\uC2DC null \uBC18\uD658)\r\n */\r\n async loadLayout(layoutName) {\r\n try {\r\n const layoutPath = `${this.config.srcPath}/layouts/${layoutName}.html`;\r\n const response = await fetch(layoutPath);\r\n if (!response.ok) throw new Error(`Layout not found: ${response.status}`);\r\n const layout = await response.text();\r\n \r\n this.log('debug', `Layout '${layoutName}' loaded successfully`);\r\n return layout;\r\n } catch (error) {\r\n this.log('debug', `Layout '${layoutName}' not found, no layout applied:`, error.message);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * \uB808\uC774\uC544\uC6C3\uACFC \uD15C\uD50C\uB9BF \uBCD1\uD569\r\n */\r\n mergeLayoutWithTemplate(routeName, layout, template) {\r\n let result;\r\n // \uB808\uC774\uC544\uC6C3\uC5D0\uC11C <slot name=\"content\"> \uBD80\uBD84\uC744 \uD15C\uD50C\uB9BF\uC73C\uB85C \uAD50\uCCB4\r\n if (layout.includes('{{ content }}')) {\r\n result = layout.replace(\r\n /{{ content }}/s,\r\n template\r\n );\r\n }\r\n // slot\uC774 \uC5C6\uC73C\uBA74 main-content \uD074\uB798\uC2A4 \uB0B4\uC6A9 \uAD50\uCCB4\r\n else if (layout.includes('class=\"main-content\"')) {\r\n this.log('debug', 'Using main-content replacement');\r\n result = layout.replace(\r\n /(<div class=\"container\">).*?(<\\/div>\\s*<\\/main>)/s,\r\n `$1${template}$2`\r\n );\r\n }\r\n // \uB9C8\uC9C0\uB9C9 \uB300\uC548: \uC804\uCCB4 \uB808\uC774\uC544\uC6C3\uC744 \uD15C\uD50C\uB9BF\uC73C\uB85C \uAC10\uC2F8\uAE30\r\n else {\r\n this.log('debug', 'Wrapping template with layout');\r\n result = `${layout}\\n${template}`;\r\n }\r\n \r\n return result;\r\n }\r\n\r\n\r\n /**\r\n * Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n */\r\n async createVueComponent(routeName) {\r\n // \uCE90\uC2DC\uB41C Vue \uCEF4\uD3EC\uB10C\uD2B8\uAC00 \uC788\uB294\uC9C0 \uD655\uC778\r\n const cacheKey = `component_${routeName}`;\r\n const cached = this.router.cacheManager?.getFromCache(cacheKey);\r\n if (cached) {\r\n return cached;\r\n }\r\n \r\n const script = await this.loadScript(routeName);\r\n const router = this.router;\r\n const isProduction = this.config.environment === 'production';\r\n \r\n // \uD658\uACBD\uBCC4 \uB9AC\uC18C\uC2A4 \uB85C\uB529\r\n let template, style = '', layout = null;\r\n \r\n if (isProduction) {\r\n // \uD504\uB85C\uB355\uC158: \uC2A4\uD06C\uB9BD\uD2B8\uC5D0 \uC788\uB294 \uD15C\uD50C\uB9BF \uC0AC\uC6A9 \uB610\uB294 \uAE30\uBCF8\uAC12\r\n template = script.template || this.generateDefaultTemplate(routeName);\r\n } else {\r\n // \uAC1C\uBC1C: \uAC1C\uBCC4 \uD30C\uC77C\uB4E4 \uB85C\uB4DC\r\n template = await this.loadTemplate(routeName);\r\n style = await this.loadStyle(routeName);\r\n layout = this.config.useLayout && script.layout !== null ? \r\n await this.loadLayout(script.layout || this.config.defaultLayout) : null;\r\n \r\n // \uB808\uC774\uC544\uC6C3\uACFC \uD15C\uD50C\uB9BF \uBCD1\uD569\r\n if (layout) {\r\n template = this.mergeLayoutWithTemplate(routeName, layout, template);\r\n }\r\n }\r\n \r\n // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 (\uC2E4\uD328\uD574\uB3C4 \uB77C\uC6B0\uD130\uB294 \uACC4\uC18D \uC791\uB3D9)\r\n let loadedComponents = {};\r\n if (this.config.useComponents && router.componentLoader) {\r\n try {\r\n loadedComponents = await router.componentLoader.loadAllComponents();\r\n this.log('debug', `Components loaded successfully for route: ${routeName}`);\r\n } catch (error) {\r\n this.log('warn', `Component loading failed for route '${routeName}', continuing without components:`, error.message);\r\n loadedComponents = {}; // \uBE48 \uAC1D\uCCB4\uB85C \uD3F4\uBC31\r\n }\r\n }\r\n\r\n // \uB2E8\uC77C \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n const component = {\r\n ...script,\r\n name: script.name || this.toPascalCase(routeName),\r\n template,\r\n components: loadedComponents,\r\n data() {\r\n const originalData = script.data ? script.data() : {};\r\n const commonData = {\r\n ...originalData,\r\n currentRoute: routeName,\r\n $query: router.queryManager?.getQueryParams() || {},\r\n $lang: (() => {\r\n try {\r\n return router.i18nManager?.getCurrentLanguage() || router.config.i18nDefaultLanguage || router.config.defaultLanguage || 'ko';\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', 'Failed to get current language:', error);\r\n return router.config.defaultLanguage || 'ko';\r\n }\r\n })(),\r\n $dataLoading: false\r\n };\r\n \r\n return commonData;\r\n },\r\n computed: {\r\n ...(script.computed || {}),\r\n // \uD558\uC704 \uD638\uD658\uC131\uC744 \uC704\uD574 params\uB294 \uC720\uC9C0\uD558\uB418 getAllParams \uC0AC\uC6A9\r\n params() {\r\n return router.queryManager?.getAllParams() || {};\r\n }\r\n },\r\n async mounted() {\r\n if (script.mounted) {\r\n await script.mounted.call(this);\r\n }\r\n if (script.dataURL) {\r\n if (typeof script.dataURL === 'string') {\r\n // \uAE30\uC874 \uB2E8\uC77C API \uBC29\uC2DD (\uD558\uC704 \uD638\uD658\uC131)\r\n await this.$fetchData();\r\n } else if (typeof script.dataURL === 'object') {\r\n // \uC0C8\uB85C\uC6B4 \uB2E4\uC911 API \uBC29\uC2DD\r\n await this.$fetchMultipleData();\r\n }\r\n }\r\n \r\n // \uD83C\uDD95 \uC790\uB3D9 \uD3FC \uBC14\uC778\uB529\r\n await this.$nextTick(); // DOM\uC774 \uC644\uC804\uD788 \uB80C\uB354\uB9C1\uB41C \uD6C4\r\n this.$bindAutoForms();\r\n },\r\n methods: {\r\n ...script.methods,\r\n // \uB77C\uC6B0\uD305 \uAD00\uB828\r\n navigateTo: (route, params) => router.navigateTo(route, params),\r\n getCurrentRoute: () => router.getCurrentRoute(),\r\n \r\n // \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC (\uB77C\uC6B0\uD305 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n getParams: () => router.queryManager?.getAllParams() || {},\r\n getParam: (key, defaultValue) => router.queryManager?.getParam(key, defaultValue),\r\n \r\n // i18n \uAD00\uB828 (resilient - i18n \uC2E4\uD328\uD574\uB3C4 key \uBC18\uD658)\r\n $t: (key, params) => {\r\n try {\r\n return router.i18nManager?.t(key, params) || key;\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', 'i18n translation failed, returning key:', error);\r\n return key;\r\n }\r\n },\r\n\r\n // \uC778\uC99D \uAD00\uB828\r\n $isAuthenticated: () => router.authManager?.isUserAuthenticated() || false,\r\n $logout: () => router.authManager ? router.navigateTo(router.authManager.handleLogout()) : null,\r\n $loginSuccess: (target) => router.authManager ? router.navigateTo(router.authManager.handleLoginSuccess(target)) : null,\r\n $checkAuth: (route) => router.authManager ? router.authManager.checkAuthentication(route) : Promise.resolve({ allowed: true, reason: 'auth_disabled' }),\r\n $getToken: () => router.authManager?.getAccessToken() || null,\r\n $setToken: (token, options) => router.authManager?.setAccessToken(token, options) || false,\r\n $removeToken: (storage) => router.authManager?.removeAccessToken(storage) || null,\r\n $getAuthCookie: () => router.authManager?.getAuthCookie() || null,\r\n $getCookie: (name) => router.authManager?.getCookieValue(name) || null,\r\n \r\n // \uB370\uC774\uD130 fetch (\uB2E8\uC77C API \uB610\uB294 \uD2B9\uC815 API)\r\n async $fetchData(apiName) {\r\n if (!script.dataURL) return;\r\n \r\n this.$dataLoading = true;\r\n try {\r\n if (typeof script.dataURL === 'string') {\r\n // \uAE30\uC874 \uB2E8\uC77C API \uBC29\uC2DD\r\n const data = await router.routeLoader.fetchComponentData(script.dataURL);\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Data fetched for ${routeName}:`, data);\r\n Object.assign(this, data);\r\n this.$emit('data-loaded', data);\r\n } else if (typeof script.dataURL === 'object' && apiName) {\r\n // \uD2B9\uC815 API\uB9CC \uC0C8\uB85C\uACE0\uCE68\r\n const url = script.dataURL[apiName];\r\n if (url) {\r\n const data = await router.routeLoader.fetchComponentData(url);\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Data fetched for ${routeName}.${apiName}:`, data);\r\n this[apiName] = data;\r\n this.$emit('data-loaded', { [apiName]: data });\r\n }\r\n } else {\r\n // \uB2E4\uC911 API - \uC804\uCCB4 \uC0C8\uB85C\uACE0\uCE68\r\n await this.$fetchMultipleData();\r\n }\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch data for ${routeName}:`, error);\r\n this.$emit('data-error', error);\r\n } finally {\r\n this.$dataLoading = false;\r\n }\r\n },\r\n\r\n // \uB2E4\uC911 API \uB370\uC774\uD130 fetch\r\n async $fetchMultipleData() {\r\n if (!script.dataURL || typeof script.dataURL !== 'object') return;\r\n \r\n const dataURLs = script.dataURL;\r\n this.$dataLoading = true;\r\n \r\n try {\r\n // \uBCD1\uB82C\uB85C \uBAA8\uB4E0 API \uD638\uCD9C\r\n const promises = Object.entries(dataURLs).map(async ([key, url]) => {\r\n try {\r\n const data = await router.routeLoader.fetchComponentData(url);\r\n return { key, data, success: true };\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch ${key} for ${routeName}:`, error);\r\n return { key, error, success: false };\r\n }\r\n });\r\n \r\n const results = await Promise.all(promises);\r\n const successfulResults = {};\r\n const errors = {};\r\n \r\n // \uACB0\uACFC \uCC98\uB9AC\r\n results.forEach(({ key, data, error, success }) => {\r\n if (success) {\r\n this[key] = data;\r\n successfulResults[key] = data;\r\n } else {\r\n errors[key] = error;\r\n }\r\n });\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Multiple data fetched for ${routeName}:`, successfulResults);\r\n \r\n // \uC774\uBCA4\uD2B8 \uBC1C\uC0DD\r\n if (Object.keys(successfulResults).length > 0) {\r\n this.$emit('data-loaded', successfulResults);\r\n }\r\n if (Object.keys(errors).length > 0) {\r\n this.$emit('data-error', errors);\r\n }\r\n \r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Failed to fetch multiple data for ${routeName}:`, error);\r\n this.$emit('data-error', error);\r\n } finally {\r\n this.$dataLoading = false;\r\n }\r\n },\r\n\r\n // \uC804\uCCB4 \uB370\uC774\uD130 \uC0C8\uB85C\uACE0\uCE68 (\uBA85\uC2DC\uC801 \uBA54\uC11C\uB4DC)\r\n async $fetchAllData() {\r\n if (typeof script.dataURL === 'string') {\r\n await this.$fetchData();\r\n } else if (typeof script.dataURL === 'object') {\r\n await this.$fetchMultipleData();\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uC790\uB3D9 \uD3FC \uBC14\uC778\uB529 \uBA54\uC11C\uB4DC\r\n $bindAutoForms() {\r\n const forms = document.querySelectorAll('form.auto-form, form[action]');\r\n \r\n forms.forEach(form => {\r\n // \uAE30\uC874 \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70 (\uC911\uBCF5 \uBC29\uC9C0)\r\n form.removeEventListener('submit', form._boundSubmitHandler);\r\n \r\n // \uC0C8 \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uCD94\uAC00\r\n const boundHandler = (e) => this.$handleFormSubmit(e);\r\n form._boundSubmitHandler = boundHandler;\r\n form.addEventListener('submit', boundHandler);\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Form auto-bound: ${form.getAttribute('action')}`);\r\n });\r\n },\r\n\r\n // \uD83C\uDD95 \uD3FC \uC11C\uBE0C\uBC0B \uD578\uB4E4\uB7EC\r\n async $handleFormSubmit(event) {\r\n event.preventDefault();\r\n \r\n const form = event.target;\r\n let action = form.getAttribute('action');\r\n const method = form.getAttribute('method') || 'POST';\r\n \r\n // \uD578\uB4E4\uB7EC \uD568\uC218\uB4E4 \uAC00\uC838\uC624\uAE30\r\n const successHandler = form.getAttribute('data-success-handler');\r\n const errorHandler = form.getAttribute('data-error-handler'); \r\n const loadingHandler = form.getAttribute('data-loading-handler');\r\n const redirectTo = form.getAttribute('data-redirect');\r\n\r\n try {\r\n // \uB85C\uB529 \uC2DC\uC791\r\n if (loadingHandler && this[loadingHandler]) {\r\n this[loadingHandler](true, form);\r\n }\r\n\r\n // \uD83C\uDD95 \uC561\uC158 URL\uC5D0 \uAC00\uBCC0 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC (\uAC04\uB2E8\uD55C \uD15C\uD50C\uB9BF \uCE58\uD658)\r\n action = this.$processActionParams(action);\r\n\r\n // \uD074\uB77C\uC774\uC5B8\uD2B8 \uC0AC\uC774\uB4DC \uAC80\uC99D\r\n if (!this.$validateForm(form)) {\r\n return;\r\n }\r\n\r\n // FormData \uC0DD\uC131\r\n const formData = new FormData(form);\r\n const data = Object.fromEntries(formData.entries());\r\n\r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Form submitting to: ${action}`, data);\r\n\r\n // API \uD638\uCD9C\r\n const response = await this.$submitFormData(action, method, data, form);\r\n \r\n // \uC131\uACF5 \uD578\uB4E4\uB7EC \uD638\uCD9C\r\n if (successHandler && this[successHandler]) {\r\n this[successHandler](response, form);\r\n }\r\n\r\n // \uC790\uB3D9 \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n if (redirectTo) {\r\n setTimeout(() => {\r\n this.navigateTo(redirectTo);\r\n }, 1000); // 1\uCD08 \uD6C4 \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n }\r\n\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Form submission error:`, error);\r\n \r\n // \uC5D0\uB7EC \uD578\uB4E4\uB7EC \uD638\uCD9C\r\n if (errorHandler && this[errorHandler]) {\r\n this[errorHandler](error, form);\r\n } else {\r\n console.error('Form submission error:', error);\r\n }\r\n } finally {\r\n // \uB85C\uB529 \uC885\uB8CC\r\n if (loadingHandler && this[loadingHandler]) {\r\n this[loadingHandler](false, form);\r\n }\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uC561\uC158 \uD30C\uB77C\uBBF8\uD130 \uCC98\uB9AC \uBA54\uC11C\uB4DC (\uAC04\uB2E8\uD55C \uD15C\uD50C\uB9BF \uCE58\uD658)\r\n $processActionParams(actionTemplate) {\r\n let processedAction = actionTemplate;\r\n \r\n // {paramName} \uD328\uD134 \uCC3E\uAE30\r\n const paramMatches = actionTemplate.match(/\\{([^}]+)\\}/g);\r\n \r\n if (paramMatches) {\r\n paramMatches.forEach(match => {\r\n const paramName = match.slice(1, -1); // {id} -> id\r\n \r\n try {\r\n // \uCEF4\uD3EC\uB10C\uD2B8\uC758 data\uB098 computed, methods\uC5D0\uC11C \uAC12 \uCC3E\uAE30\r\n let paramValue = null;\r\n \r\n // 1. \uBA3C\uC800 getParam\uC73C\uB85C \uB77C\uC6B0\uD2B8 \uD30C\uB77C\uBBF8\uD130\uC5D0\uC11C \uCC3E\uAE30\r\n paramValue = this.getParam(paramName);\r\n \r\n // 2. \uCEF4\uD3EC\uB10C\uD2B8 data\uC5D0\uC11C \uCC3E\uAE30\r\n if (paramValue === null || paramValue === undefined) {\r\n paramValue = this[paramName];\r\n }\r\n \r\n // 3. computed \uC18D\uC131\uC5D0\uC11C \uCC3E\uAE30\r\n if (paramValue === null || paramValue === undefined) {\r\n if (this.$options.computed && this.$options.computed[paramName]) {\r\n paramValue = this[paramName];\r\n }\r\n }\r\n \r\n if (paramValue !== null && paramValue !== undefined) {\r\n // \uD15C\uD50C\uB9BF \uB300\uCCB4: {id} -> \uC2E4\uC81C\uAC12\r\n processedAction = processedAction.replace(\r\n match, \r\n encodeURIComponent(paramValue)\r\n );\r\n \r\n if (router.errorHandler) router.errorHandler.debug('RouteLoader', `Parameter resolved: ${paramName} = ${paramValue}`);\r\n } else {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Parameter '${paramName}' not found in component data, computed, or route params`);\r\n // \uD30C\uB77C\uBBF8\uD130\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC73C\uBA74 \uC6D0\uBCF8 \uADF8\uB300\uB85C \uC720\uC9C0\r\n }\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Error processing parameter '${paramName}':`, error);\r\n // \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD574\uB3C4 \uC6D0\uBCF8 \uADF8\uB300\uB85C \uC720\uC9C0\r\n }\r\n });\r\n }\r\n \r\n return processedAction;\r\n },\r\n\r\n\r\n // \uD83C\uDD95 \uD3FC \uB370\uC774\uD130 \uC11C\uBE0C\uBC0B\r\n async $submitFormData(action, method, data, form) {\r\n // \uD30C\uC77C \uC5C5\uB85C\uB4DC \uCCB4\uD06C\r\n const hasFile = Array.from(form.elements).some(el => el.type === 'file' && el.files.length > 0);\r\n \r\n const headers = {\r\n 'Accept': 'application/json',\r\n // \uC778\uC99D \uD1A0\uD070 \uC790\uB3D9 \uCD94\uAC00\r\n ...(this.$getToken() && {\r\n 'Authorization': `Bearer ${this.$getToken()}`\r\n })\r\n };\r\n\r\n let body;\r\n if (hasFile) {\r\n // \uD30C\uC77C\uC774 \uC788\uC73C\uBA74 FormData \uADF8\uB300\uB85C \uC804\uC1A1\r\n body = new FormData(form);\r\n // Content-Type\uC744 \uC124\uC815\uD558\uC9C0 \uC54A\uC74C (\uBE0C\uB77C\uC6B0\uC800\uAC00 \uC790\uB3D9\uC73C\uB85C multipart/form-data\uB85C \uC124\uC815)\r\n } else {\r\n // JSON\uC73C\uB85C \uC804\uC1A1\r\n headers['Content-Type'] = 'application/json';\r\n body = JSON.stringify(data);\r\n }\r\n\r\n const response = await fetch(action, {\r\n method: method.toUpperCase(),\r\n headers,\r\n body\r\n });\r\n\r\n if (!response.ok) {\r\n let error;\r\n try {\r\n error = await response.json();\r\n } catch (e) {\r\n error = { message: `HTTP ${response.status}: ${response.statusText}` };\r\n }\r\n throw new Error(error.message || `HTTP ${response.status}`);\r\n }\r\n\r\n try {\r\n return await response.json();\r\n } catch (e) {\r\n // \uC751\uB2F5\uC774 JSON\uC774 \uC544\uB2CC \uACBD\uC6B0 (\uC608: 204 No Content)\r\n return { success: true };\r\n }\r\n },\r\n\r\n // \uD83C\uDD95 \uD074\uB77C\uC774\uC5B8\uD2B8 \uC0AC\uC774\uB4DC \uD3FC \uAC80\uC99D\r\n $validateForm(form) {\r\n let isValid = true;\r\n const inputs = form.querySelectorAll('input, textarea, select');\r\n\r\n inputs.forEach(input => {\r\n // \uAE30\uBCF8 HTML5 \uAC80\uC99D\r\n if (!input.checkValidity()) {\r\n isValid = false;\r\n input.classList.add('error');\r\n return;\r\n }\r\n\r\n // \uCEE4\uC2A4\uD140 \uAC80\uC99D \uD568\uC218 \uD655\uC778\r\n const validationFunction = input.getAttribute('data-validation');\r\n if (validationFunction) {\r\n const isInputValid = this.$validateInput(input, validationFunction);\r\n if (!isInputValid) {\r\n isValid = false;\r\n input.classList.add('error');\r\n } else {\r\n input.classList.remove('error');\r\n }\r\n } else {\r\n input.classList.remove('error');\r\n }\r\n });\r\n\r\n return isValid;\r\n },\r\n\r\n // \uD83C\uDD95 \uAC1C\uBCC4 \uC785\uB825 \uAC80\uC99D\r\n $validateInput(input, validationFunction) {\r\n const value = input.value;\r\n \r\n // \uCEE4\uC2A4\uD140 \uAC80\uC99D \uD568\uC218 \uD638\uCD9C\r\n if (typeof this[validationFunction] === 'function') {\r\n try {\r\n return this[validationFunction](value, input);\r\n } catch (error) {\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Validation function '${validationFunction}' error:`, error);\r\n return false;\r\n }\r\n }\r\n \r\n // \uD568\uC218\uAC00 \uC5C6\uC73C\uBA74 true \uBC18\uD658\r\n if (router.errorHandler) router.errorHandler.warn('RouteLoader', `Validation function '${validationFunction}' not found`);\r\n return true;\r\n }\r\n },\r\n _routeName: routeName\r\n };\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB9CC \uC2A4\uD0C0\uC77C \uBA54\uD0C0\uB370\uC774\uD130 \uC800\uC7A5 (\uB80C\uB354\uB9C1 \uC2DC \uC8FC\uC785\uC6A9)\r\n if (!isProduction && style) {\r\n component._style = style;\r\n }\r\n \r\n // \uCE90\uC2DC\uC5D0 \uC800\uC7A5\r\n this.router.cacheManager?.setCache(cacheKey, component);\r\n \r\n return component;\r\n }\r\n\r\n /**\r\n * \uBB38\uC790\uC5F4\uC744 PascalCase\uB85C \uBCC0\uD658\r\n */\r\n toPascalCase(str) {\r\n return str\r\n .split(/[-_\\s]+/) // \uD558\uC774\uD508, \uC5B8\uB354\uC2A4\uCF54\uC5B4, \uACF5\uBC31\uC73C\uB85C \uBD84\uB9AC\r\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join('');\r\n }\r\n\r\n /**\r\n * \uAE30\uBCF8 \uD15C\uD50C\uB9BF \uC0DD\uC131\r\n */\r\n generateDefaultTemplate(routeName) {\r\n return `<div class=\"route-${routeName}\"><h1>Route: ${routeName}</h1></div>`;\r\n }\r\n\r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uB370\uC774\uD130 \uAC00\uC838\uC624\uAE30\r\n */\r\n async fetchComponentData(dataURL) {\r\n try {\r\n // \uD604\uC7AC \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130\uB97C URL\uC5D0 \uCD94\uAC00\r\n const queryString = this.router.queryManager?.buildQueryString(this.router.queryManager?.getQueryParams()) || '';\r\n const fullURL = queryString ? `${dataURL}?${queryString}` : dataURL;\r\n \r\n this.log('debug', `Fetching data from: ${fullURL}`);\r\n \r\n const response = await fetch(fullURL, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n });\r\n \r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n \r\n const data = await response.json();\r\n \r\n // \uB370\uC774\uD130 \uC720\uD6A8\uC131 \uAC80\uC0AC\r\n if (typeof data !== 'object' || data === null) {\r\n throw new Error('Invalid data format: expected object');\r\n }\r\n \r\n return data;\r\n \r\n } catch (error) {\r\n this.log('error', 'Failed to fetch component data:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * \uCE90\uC2DC \uBB34\uD6A8\uD654\r\n */\r\n invalidateCache(routeName) {\r\n if (this.router.cacheManager) {\r\n this.router.cacheManager.invalidateComponentCache(routeName);\r\n }\r\n this.log('debug', `Cache invalidated for route: ${routeName}`);\r\n }\r\n\r\n /**\r\n * \uD1B5\uACC4 \uC815\uBCF4 \uBC18\uD658\r\n */\r\n getStats() {\r\n return {\r\n environment: this.config.environment,\r\n srcPath: this.config.srcPath,\r\n routesPath: this.config.routesPath,\r\n useLayout: this.config.useLayout,\r\n useComponents: this.config.useComponents\r\n };\r\n }\r\n\r\n /**\r\n * \uD398\uC774\uC9C0 \uC81C\uBAA9 \uC0DD\uC131\r\n */\r\n generatePageTitle(routeName) {\r\n return this.toPascalCase(routeName).replace(/([A-Z])/g, ' $1').trim();\r\n }\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'RouteLoader', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.log('debug', 'RouteLoader destroyed');\r\n this.router = null;\r\n }\r\n}", "/**\r\n * ViewLogic Error Handling System\r\n * \uB77C\uC6B0\uD2B8 \uBC0F \uC2DC\uC2A4\uD15C \uC5D0\uB7EC \uCC98\uB9AC \uC2DC\uC2A4\uD15C\r\n */\r\nexport class ErrorHandler {\r\n constructor(router, options = {}) {\r\n this.config = {\r\n enableErrorReporting: options.enableErrorReporting !== false,\r\n debug: options.debug || false,\r\n logLevel: options.logLevel || (options.debug ? 'debug' : 'info'),\r\n environment: options.environment || 'development'\r\n };\r\n \r\n // \uB77C\uC6B0\uD130 \uC778\uC2A4\uD134\uC2A4 \uCC38\uC870\r\n this.router = router;\r\n \r\n // \uB85C\uADF8 \uB808\uBCA8 \uB9E4\uD551\r\n this.logLevels = {\r\n error: 0,\r\n warn: 1, \r\n info: 2,\r\n debug: 3\r\n };\r\n \r\n this.log('info', 'ErrorHandler', 'ErrorHandler initialized with config:', this.config);\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD2B8 \uC5D0\uB7EC \uCC98\uB9AC\r\n */\r\n async handleRouteError(routeName, error) {\r\n let errorCode = 500;\r\n let errorMessage = '\uD398\uC774\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.';\r\n \r\n this.debug('ErrorHandler', '\uC5D0\uB7EC \uC0C1\uC138:', error.message, error.name);\r\n \r\n // \uC5D0\uB7EC \uD0C0\uC785 \uBD84\uC11D (\uB354 \uC815\uD655\uD55C 404 \uAC10\uC9C0)\r\n if (error.message.includes('not found') || \r\n error.message.includes('404') ||\r\n error.message.includes('Failed to resolve') ||\r\n error.message.includes('Failed to fetch') ||\r\n (error.name === 'TypeError' && error.message.includes('resolve'))) {\r\n errorCode = 404;\r\n errorMessage = `'${routeName}' \uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`;\r\n } else if (error.message.includes('network') && !error.message.includes('not found')) {\r\n errorCode = 503;\r\n errorMessage = '\uB124\uD2B8\uC6CC\uD06C \uC5F0\uACB0\uC744 \uD655\uC778\uD574 \uC8FC\uC138\uC694.';\r\n } else if (error.message.includes('permission') || error.message.includes('403')) {\r\n errorCode = 403;\r\n errorMessage = '\uD398\uC774\uC9C0\uC5D0 \uC811\uADFC\uD560 \uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.';\r\n }\r\n \r\n this.debug('ErrorHandler', `\uC5D0\uB7EC \uCF54\uB4DC \uACB0\uC815: ${errorCode} (\uB77C\uC6B0\uD2B8: ${routeName})`);\r\n \r\n // \uC5D0\uB7EC \uB9AC\uD3EC\uD305\r\n if (this.config.enableErrorReporting) {\r\n this.reportError(routeName, error, errorCode);\r\n }\r\n \r\n try {\r\n // 404 \uD398\uC774\uC9C0 \uC804\uC6A9 \uCC98\uB9AC\r\n if (errorCode === 404) {\r\n await this.load404Page();\r\n } else {\r\n // \uC77C\uBC18 \uC5D0\uB7EC \uD398\uC774\uC9C0\r\n await this.loadErrorPage(errorCode, errorMessage);\r\n }\r\n } catch (fallbackError) {\r\n this.error('ErrorHandler', '\uC5D0\uB7EC \uD398\uC774\uC9C0 \uB85C\uB529 \uC2E4\uD328:', fallbackError);\r\n // \uBAA8\uB4E0 \uC5D0\uB7EC \uD398\uC774\uC9C0\uAC00 \uC2E4\uD328\uD588\uC744 \uB54C \uCD5C\uD6C4\uC758 \uD3F4\uBC31 \uD398\uC774\uC9C0 \uD45C\uC2DC\r\n this.showFallbackErrorPage(errorCode, errorMessage);\r\n }\r\n }\r\n\r\n /**\r\n * 404 \uD398\uC774\uC9C0 \uB85C\uB529\r\n */\r\n async load404Page() {\r\n try {\r\n this.info('ErrorHandler', 'Loading 404 page...');\r\n const component = await this.createVueComponent('404');\r\n await this.renderComponentWithTransition(component, '404');\r\n this.info('ErrorHandler', '404 page loaded successfully');\r\n } catch (error) {\r\n this.error('ErrorHandler', '404 page loading failed:', error);\r\n // 404 \uD398\uC774\uC9C0\uB3C4 \uC5C6\uC73C\uBA74 \uAC04\uB2E8\uD55C \uC5D0\uB7EC \uBA54\uC2DC\uC9C0 \uD45C\uC2DC\r\n this.showFallbackErrorPage('404', '\uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.');\r\n }\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uD398\uC774\uC9C0 \uB85C\uB529\r\n */\r\n async loadErrorPage(errorCode, errorMessage) {\r\n try {\r\n this.info('ErrorHandler', `Loading error page for ${errorCode}...`);\r\n \r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n const errorComponent = await this.createErrorComponent(errorCode, errorMessage);\r\n await this.renderComponentWithTransition(errorComponent, 'error');\r\n this.info('ErrorHandler', `Error page ${errorCode} loaded successfully`);\r\n } catch (error) {\r\n this.error('ErrorHandler', `Error page ${errorCode} loading failed:`, error);\r\n // \uC5D0\uB7EC \uD398\uC774\uC9C0\uB3C4 \uB85C\uB529 \uC2E4\uD328\uD558\uBA74 \uD3F4\uBC31 \uD45C\uC2DC\r\n this.showFallbackErrorPage(errorCode, errorMessage);\r\n }\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131\r\n */\r\n async createErrorComponent(errorCode, errorMessage) {\r\n try {\r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uB3D9\uC801\uC73C\uB85C \uB85C\uB4DC\r\n const component = await this.createVueComponent('error');\r\n \r\n // \uC5D0\uB7EC \uC815\uBCF4\uB97C props\uB85C \uC804\uB2EC\r\n const errorComponent = {\r\n ...component,\r\n data() {\r\n const originalData = component.data ? component.data() : {};\r\n return {\r\n ...originalData,\r\n errorCode,\r\n errorMessage,\r\n showRetry: true,\r\n showGoHome: true\r\n };\r\n }\r\n };\r\n \r\n return errorComponent;\r\n } catch (error) {\r\n // \uC5D0\uB7EC \uCEF4\uD3EC\uB10C\uD2B8\uB3C4 \uB85C\uB4DC\uD560 \uC218 \uC5C6\uB294 \uACBD\uC6B0 \uAC04\uB2E8\uD55C \uC5D0\uB7EC \uD45C\uC2DC\r\n this.error('ErrorHandler', 'Error component load failed:', error);\r\n throw new Error(`Cannot load error page: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * \uD3F4\uBC31 \uC5D0\uB7EC \uD398\uC774\uC9C0 \uD45C\uC2DC (\uBAA8\uB4E0 \uC5D0\uB7EC \uD398\uC774\uC9C0\uAC00 \uC2E4\uD328\uD588\uC744 \uB54C)\r\n */\r\n showFallbackErrorPage(errorCode, errorMessage) {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n const fallbackHTML = `\r\n <div class=\"fallback-error-page\" style=\"\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n min-height: 100vh;\r\n padding: 2rem;\r\n text-align: center;\r\n background: #f8f9fa;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n \">\r\n <div style=\"\r\n background: white;\r\n padding: 3rem;\r\n border-radius: 12px;\r\n box-shadow: 0 4px 20px rgba(0,0,0,0.1);\r\n max-width: 500px;\r\n \">\r\n <h1 style=\"\r\n font-size: 4rem;\r\n margin: 0;\r\n color: #dc3545;\r\n font-weight: 300;\r\n \">${errorCode}</h1>\r\n <h2 style=\"\r\n margin: 1rem 0;\r\n color: #495057;\r\n font-weight: 400;\r\n \">${errorMessage}</h2>\r\n <p style=\"\r\n color: #6c757d;\r\n margin-bottom: 2rem;\r\n line-height: 1.5;\r\n \">\uC694\uCCAD\uD558\uC2E0 \uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.</p>\r\n <button onclick=\"window.location.hash = '#/'\" style=\"\r\n background: #007bff;\r\n color: white;\r\n border: none;\r\n padding: 12px 24px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n font-size: 1rem;\r\n transition: background 0.2s;\r\n \" onmouseover=\"this.style.background='#0056b3'\" onmouseout=\"this.style.background='#007bff'\">\r\n \uD648\uC73C\uB85C \uB3CC\uC544\uAC00\uAE30\r\n </button>\r\n </div>\r\n </div>\r\n `;\r\n\r\n // \uAE30\uC874 \uCEE8\uD14C\uC774\uB108\uB4E4 \uC815\uB9AC\r\n appElement.innerHTML = fallbackHTML;\r\n \r\n this.info('ErrorHandler', `Fallback error page displayed for ${errorCode}`);\r\n }\r\n\r\n /**\r\n * \uC5D0\uB7EC \uB9AC\uD3EC\uD305\r\n */\r\n reportError(routeName, error, errorCode) {\r\n const errorReport = {\r\n route: routeName,\r\n errorCode,\r\n errorMessage: error.message,\r\n stack: error.stack,\r\n url: window.location.href,\r\n userAgent: navigator.userAgent,\r\n timestamp: new Date().toISOString(),\r\n routerConfig: {\r\n environment: this.router.config.environment,\r\n mode: this.router.config.mode\r\n }\r\n };\r\n \r\n this.error('ErrorHandler', '\uB77C\uC6B0\uD130 \uC5D0\uB7EC \uB9AC\uD3EC\uD2B8:', errorReport);\r\n \r\n // \uCD94\uD6C4 \uC5D0\uB7EC \uCD94\uC801 \uC11C\uBE44\uC2A4\uB85C \uC804\uC1A1\uD560 \uC218 \uC788\uC74C\r\n // \uC608: analytics.track('router_error', errorReport);\r\n }\r\n\r\n /**\r\n * Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131 (RouteLoader \uC704\uC784)\r\n */\r\n async createVueComponent(routeName) {\r\n if (this.router.routeLoader) {\r\n return await this.router.routeLoader.createVueComponent(routeName);\r\n }\r\n throw new Error('RouteLoader not available');\r\n }\r\n\r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uB80C\uB354\uB9C1 (ViewManager \uC704\uC784)\r\n */\r\n async renderComponentWithTransition(component, routeName) {\r\n if (this.router.renderComponentWithTransition) {\r\n return await this.router.renderComponentWithTransition(component, routeName);\r\n }\r\n throw new Error('Render function not available');\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569 \uB85C\uAE45 \uC2DC\uC2A4\uD15C\r\n * @param {string} level - \uB85C\uADF8 \uB808\uBCA8 (error, warn, info, debug)\r\n * @param {string} component - \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 (\uC120\uD0DD\uC801)\r\n * @param {...any} args - \uB85C\uADF8 \uBA54\uC2DC\uC9C0\r\n */\r\n log(level, component, ...args) {\r\n // \uD558\uC704 \uD638\uD658\uC131: \uAE30\uC874 \uBC29\uC2DD\uB3C4 \uC9C0\uC6D0\r\n if (typeof level !== 'string' || !this.logLevels.hasOwnProperty(level)) {\r\n args = [component, ...args];\r\n component = level;\r\n level = this.config.debug ? 'debug' : 'info';\r\n }\r\n \r\n // \uB85C\uADF8 \uB808\uBCA8 \uD655\uC778\r\n const currentLevelValue = this.logLevels[this.config.logLevel] || this.logLevels.info;\r\n const messageLevelValue = this.logLevels[level] || this.logLevels.info;\r\n \r\n if (messageLevelValue > currentLevelValue) {\r\n return; // \uD604\uC7AC \uC124\uC815\uB41C \uB808\uBCA8\uBCF4\uB2E4 \uB192\uC73C\uBA74 \uCD9C\uB825 \uC548\uD568\r\n }\r\n \r\n // \uD504\uB85C\uB355\uC158 \uD658\uACBD\uC5D0\uC11C\uB294 error\uC640 warn\uB9CC \uCD9C\uB825\r\n if (this.config.environment === 'production' && messageLevelValue > this.logLevels.warn) {\r\n return;\r\n }\r\n \r\n const prefix = component ? `[${component}]` : '[ViewLogic]';\r\n const timestamp = new Date().toISOString().substring(11, 23); // HH:MM:SS.mmm\r\n \r\n switch (level) {\r\n case 'error':\r\n console.error(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'warn':\r\n console.warn(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'info':\r\n console.info(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n case 'debug':\r\n console.log(`${timestamp} ${prefix}`, ...args);\r\n break;\r\n default:\r\n console.log(`${timestamp} ${prefix}`, ...args);\r\n }\r\n }\r\n \r\n /**\r\n * \uC5D0\uB7EC \uB85C\uADF8 (\uD56D\uC0C1 \uCD9C\uB825)\r\n */\r\n error(component, ...args) {\r\n this.log('error', component, ...args);\r\n }\r\n \r\n /**\r\n * \uACBD\uACE0 \uB85C\uADF8\r\n */\r\n warn(component, ...args) {\r\n this.log('warn', component, ...args);\r\n }\r\n \r\n /**\r\n * \uC815\uBCF4 \uB85C\uADF8\r\n */\r\n info(component, ...args) {\r\n this.log('info', component, ...args);\r\n }\r\n \r\n /**\r\n * \uB514\uBC84\uADF8 \uB85C\uADF8\r\n */\r\n debug(component, ...args) {\r\n this.log('debug', component, ...args);\r\n }\r\n\r\n /**\r\n * \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n this.router = null;\r\n this.info('ErrorHandler', 'ErrorHandler destroyed');\r\n }\r\n}", "/**\r\n * ComponentLoader\r\n * \uB3D9\uC801\uC73C\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uB85C\uB4DC\uD558\uACE0 \uB4F1\uB85D\uD558\uB294 \uC2DC\uC2A4\uD15C\r\n */\r\nexport class ComponentLoader {\r\n constructor(router = null, options = {}) {\r\n\r\n this.config = {\r\n componentsPath: options.componentsPath || '/components', // srcPath \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C\r\n debug: options.debug || false,\r\n environment: options.environment || 'development',\r\n ...options\r\n };\r\n \r\n this.router = router;\r\n this.loadingPromises = new Map();\r\n this.unifiedComponents = null;\r\n }\r\n \r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.router?.errorHandler) {\r\n this.router.errorHandler.log(level, 'ComponentLoader', ...args);\r\n }\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uBE44\uB3D9\uAE30\uB85C \uB85C\uB4DC\r\n */\r\n async loadComponent(componentName) {\r\n if (!componentName || typeof componentName !== 'string') {\r\n throw new Error('Component name must be a non-empty string');\r\n }\r\n \r\n // \uC774\uBBF8 \uB85C\uB529 \uC911\uC778 \uACBD\uC6B0 \uAE30\uC874 Promise \uBC18\uD658\r\n if (this.loadingPromises.has(componentName)) {\r\n return this.loadingPromises.get(componentName);\r\n }\r\n \r\n const loadPromise = this._loadComponentFromFile(componentName);\r\n this.loadingPromises.set(componentName, loadPromise);\r\n \r\n try {\r\n const component = await loadPromise;\r\n return component;\r\n } catch (error) {\r\n throw error;\r\n } finally {\r\n this.loadingPromises.delete(componentName);\r\n }\r\n }\r\n \r\n /**\r\n * \uD30C\uC77C\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB4DC\r\n */\r\n async _loadComponentFromFile(componentName) {\r\n // srcPath + componentsPath\uB97C \uC870\uD569\uD558\uC5EC \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C \uC0DD\uC131\r\n const componentRelativePath = `${this.config.componentsPath}/${componentName}.js`;\r\n \r\n let componentPath;\r\n if (this.router && this.router.config.srcPath) {\r\n // srcPath\uB294 \uC774\uBBF8 \uC804\uCCB4 URL\uC774\uBBC0\uB85C \uC9C1\uC811 \uC870\uD569\r\n const srcPath = this.router.config.srcPath;\r\n if (srcPath.startsWith('http')) {\r\n // \uC774\uC911 \uC2AC\uB798\uC2DC \uBC29\uC9C0\r\n const cleanSrcPath = srcPath.endsWith('/') ? srcPath.slice(0, -1) : srcPath;\r\n const cleanComponentPath = componentRelativePath.startsWith('/') ? componentRelativePath : `/${componentRelativePath}`;\r\n componentPath = `${cleanSrcPath}${cleanComponentPath}`;\r\n } else {\r\n componentPath = this.router.resolvePath(`${srcPath}${componentRelativePath}`);\r\n }\r\n } else {\r\n // \uD3F4\uBC31: \uAE30\uBCF8 \uACBD\uB85C \uC0AC\uC6A9\r\n componentPath = this.router ? \r\n this.router.resolvePath(`/src${componentRelativePath}`) : \r\n `/src${componentRelativePath}`;\r\n }\r\n \r\n try {\r\n const module = await import(componentPath);\r\n const component = module.default;\r\n \r\n if (!component) {\r\n throw new Error(`Component '${componentName}' has no default export`);\r\n }\r\n \r\n if (!component.name) {\r\n component.name = componentName;\r\n }\r\n \r\n this.log('debug', `Component '${componentName}' loaded successfully`);\r\n return component;\r\n \r\n } catch (error) {\r\n this.log('error', `Failed to load component '${componentName}':`, error);\r\n throw new Error(`Component '${componentName}' not found: ${error.message}`);\r\n }\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uBAA8\uB4C8 \uD074\uB9AC\uC5B4\r\n */\r\n clearComponents() {\r\n this.loadingPromises.clear();\r\n this.unifiedComponents = null;\r\n this.log('debug', 'All components cleared');\r\n }\r\n \r\n /**\r\n * \uD658\uACBD\uC5D0 \uB530\uB978 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 (\uCE90\uC2F1 \uC9C0\uC6D0)\r\n */\r\n async loadAllComponents() {\r\n // \uC774\uBBF8 \uB85C\uB4DC\uB41C unifiedComponents\uAC00 \uC788\uC73C\uBA74 \uBC18\uD658\r\n if (this.unifiedComponents) {\r\n this.log('debug', 'Using existing unified components');\r\n return this.unifiedComponents;\r\n }\r\n \r\n // \uC6B4\uC601 \uBAA8\uB4DC: \uD1B5\uD569 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529 \uC2DC\uB3C4\r\n if (this.config.environment === 'production') {\r\n return await this._loadProductionComponents();\r\n }\r\n \r\n // \uAC1C\uBC1C \uBAA8\uB4DC: \uAC1C\uBCC4 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n return await this._loadDevelopmentComponents();\r\n }\r\n \r\n /**\r\n * \uC6B4\uC601 \uBAA8\uB4DC: \uD1B5\uD569 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n */\r\n async _loadProductionComponents() {\r\n try {\r\n const componentsPath = `${this.router?.config?.routesPath || '/routes'}/_components.js`;\r\n this.log('info', '[PRODUCTION] Loading unified components from:', componentsPath);\r\n \r\n const componentsModule = await import(componentsPath);\r\n \r\n if (typeof componentsModule.registerComponents === 'function') {\r\n this.unifiedComponents = componentsModule.components || {};\r\n this.log('info', `[PRODUCTION] Unified components loaded: ${Object.keys(this.unifiedComponents).length} components`);\r\n return this.unifiedComponents;\r\n } else {\r\n throw new Error('registerComponents function not found in components module');\r\n }\r\n } catch (error) {\r\n this.log('warn', '[PRODUCTION] Failed to load unified components:', error.message);\r\n this.unifiedComponents = {};\r\n return {};\r\n }\r\n }\r\n \r\n /**\r\n * \uAC1C\uBC1C \uBAA8\uB4DC: \uAC1C\uBCC4 \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB529\r\n */\r\n async _loadDevelopmentComponents() {\r\n const componentNames = this._getComponentNames();\r\n const components = {};\r\n \r\n this.log('info', `[DEVELOPMENT] Loading individual components: ${componentNames.join(', ')}`);\r\n \r\n for (const name of componentNames) {\r\n try {\r\n const component = await this.loadComponent(name);\r\n if (component) {\r\n components[name] = component;\r\n }\r\n } catch (loadError) {\r\n this.log('warn', `[DEVELOPMENT] Failed to load component ${name}:`, loadError.message);\r\n }\r\n }\r\n \r\n this.unifiedComponents = components;\r\n this.log('info', `[DEVELOPMENT] Individual components loaded: ${Object.keys(components).length} components`);\r\n return components;\r\n }\r\n \r\n /**\r\n * \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984 \uBAA9\uB85D \uAC00\uC838\uC624\uAE30\r\n */\r\n _getComponentNames() {\r\n if (Array.isArray(this.config.componentNames) && this.config.componentNames.length > 0) {\r\n return [...this.config.componentNames];\r\n }\r\n \r\n // \uD3F4\uBC31: \uAE30\uC874 \uD558\uB4DC\uCF54\uB529 \uBAA9\uB85D\r\n return [\r\n 'Button', 'Modal', 'Card', 'Toast', 'Input', 'Tabs',\r\n 'Checkbox', 'Alert', 'DynamicInclude', 'HtmlInclude'\r\n ];\r\n }\r\n \r\n /**\r\n * \uBA54\uBAA8\uB9AC \uC815\uB9AC\r\n */\r\n dispose() {\r\n this.clearComponents();\r\n this.log('debug', 'ComponentLoader disposed');\r\n this.router = null;\r\n }\r\n}", "// ViewLogic Router - ES6 Module\r\nimport { I18nManager } from './plugins/I18nManager.js';\r\nimport { AuthManager } from './plugins/AuthManager.js';\r\nimport { CacheManager } from './plugins/CacheManager.js';\r\nimport { QueryManager } from './plugins/QueryManager.js';\r\nimport { RouteLoader } from './core/RouteLoader.js';\r\nimport { ErrorHandler } from './core/ErrorHandler.js';\r\nimport { ComponentLoader } from './core/ComponentLoader.js';\r\n\r\nexport class ViewLogicRouter {\r\n constructor(options = {}) {\r\n // \uBC84\uC804 \uC815\uBCF4\r\n this.version = options.version || '1.0.0';\r\n \r\n // \uAE30\uBCF8 \uD658\uACBD\uC124\uC815 \uCD5C\uC801\uD654\r\n this.config = this._buildConfig(options);\r\n \r\n this.currentHash = '';\r\n this.currentVueApp = null;\r\n this.previousVueApp = null; // \uC774\uC804 Vue \uC571 (\uC804\uD658 \uD6A8\uACFC\uB97C \uC704\uD574 \uBCF4\uAD00)\r\n this.componentLoader = null; // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB354 \uC778\uC2A4\uD134\uC2A4\r\n\r\n // LoadingManager\uAC00 \uC5C6\uC744 \uB54C\uB97C \uC704\uD55C \uAE30\uBCF8 \uC804\uD658 \uC0C1\uD0DC\r\n this.transitionInProgress = false;\r\n \r\n // \uCD08\uAE30\uD654 \uC900\uBE44 \uC0C1\uD0DC\r\n this.isReady = false;\r\n this.readyPromise = null;\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uBC14\uC778\uB529 \uCD5C\uC801\uD654\r\n this._boundHandleRouteChange = this.handleRouteChange.bind(this);\r\n \r\n // \uBAA8\uB4E0 \uCD08\uAE30\uD654\uB97C \uD55C\uBC88\uC5D0 \uCC98\uB9AC\r\n this.readyPromise = this.initialize();\r\n }\r\n\r\n /**\r\n * \uC124\uC815 \uBE4C\uB4DC (\uBD84\uB9AC\uD558\uC5EC \uAC00\uB3C5\uC131 \uD5A5\uC0C1)\r\n */\r\n _buildConfig(options) {\r\n const currentOrigin = window.location.origin;\r\n \r\n const defaults = {\r\n basePath: '/', // \uC560\uD50C\uB9AC\uCF00\uC774\uC158 \uAE30\uBCF8 \uACBD\uB85C (\uC11C\uBE0C\uD3F4\uB354 \uBC30\uD3EC\uC6A9)\r\n srcPath: '/src', // \uC18C\uC2A4 \uD30C\uC77C \uACBD\uB85C\r\n mode: 'hash',\r\n cacheMode: 'memory',\r\n cacheTTL: 300000,\r\n maxCacheSize: 50,\r\n useLayout: true,\r\n defaultLayout: 'default',\r\n environment: 'development',\r\n routesPath: '/routes', // \uD504\uB85C\uB355\uC158 \uB77C\uC6B0\uD2B8 \uACBD\uB85C\r\n enableErrorReporting: true,\r\n useComponents: true,\r\n componentNames: ['Button', 'Modal', 'Card', 'Toast', 'Input', 'Tabs', 'Checkbox', 'Alert', 'DynamicInclude', 'HtmlInclude'],\r\n useI18n: false,\r\n defaultLanguage: 'ko',\r\n i18nPath: '/i18n', // \uB2E4\uAD6D\uC5B4 \uD30C\uC77C \uACBD\uB85C\r\n logLevel: 'info',\r\n authEnabled: false,\r\n loginRoute: 'login',\r\n protectedRoutes: [],\r\n protectedPrefixes: [],\r\n publicRoutes: ['login', 'register', 'home'],\r\n checkAuthFunction: null,\r\n redirectAfterLogin: 'home',\r\n authCookieName: 'authToken',\r\n authFallbackCookieNames: ['accessToken', 'token', 'jwt'],\r\n authStorage: 'cookie',\r\n authCookieOptions: {},\r\n authSkipValidation: false,\r\n enableParameterValidation: true,\r\n maxParameterLength: 1000,\r\n maxParameterCount: 50,\r\n maxArraySize: 100,\r\n allowedKeyPattern: /^[a-zA-Z0-9_-]+$/,\r\n logSecurityWarnings: true\r\n };\r\n \r\n const config = { ...defaults, ...options };\r\n \r\n // \uC808\uB300 \uACBD\uB85C\uB4E4\uC744 basePath \uAE30\uC900\uC73C\uB85C \uD574\uACB0\r\n config.srcPath = this.resolvePath(config.srcPath, config.basePath);\r\n config.routesPath = this.resolvePath(config.routesPath, config.basePath);\r\n config.i18nPath = this.resolvePath(config.i18nPath, config.basePath);\r\n \r\n return config;\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569 \uACBD\uB85C \uD574\uACB0 - \uC11C\uBE0C\uD3F4\uB354 \uBC30\uD3EC \uBC0F basePath \uC9C0\uC6D0\r\n */\r\n resolvePath(path, basePath = null) {\r\n const currentOrigin = window.location.origin;\r\n \r\n // HTTP URL\uC778 \uACBD\uC6B0 \uADF8\uB300\uB85C \uBC18\uD658\r\n if (path.startsWith('http')) {\r\n return path;\r\n }\r\n \r\n // \uC808\uB300 \uACBD\uB85C\uC778 \uACBD\uC6B0\r\n if (path.startsWith('/')) {\r\n // basePath \uC81C\uACF5\uB41C \uACBD\uC6B0 basePath\uC640 \uC870\uD569\r\n if (basePath && basePath !== '/') {\r\n // \uC774\uC911 \uC2AC\uB798\uC2DC \uBC29\uC9C0\r\n const cleanBasePath = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\r\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\r\n const fullPath = `${cleanBasePath}${cleanPath}`;\r\n const fullUrl = `${currentOrigin}${fullPath}`;\r\n return fullUrl.replace(/([^:])\\/{2,}/g, '$1/');\r\n }\r\n // \uC77C\uBC18\uC801\uC778 \uC808\uB300 \uACBD\uB85C\r\n return `${currentOrigin}${path}`;\r\n }\r\n \r\n // \uC0C1\uB300 \uACBD\uB85C\uC778 \uACBD\uC6B0 \uD604\uC7AC \uACBD\uB85C \uAE30\uC900\uC73C\uB85C \uD574\uACB0\r\n const currentPathname = window.location.pathname;\r\n const currentBase = currentPathname.endsWith('/') \r\n ? currentPathname \r\n : currentPathname.substring(0, currentPathname.lastIndexOf('/') + 1);\r\n \r\n // \uC0C1\uB300 \uACBD\uB85C \uC815\uADDC\uD654\r\n const resolvedPath = this.normalizePath(currentBase + path);\r\n \r\n const fullUrl = `${currentOrigin}${resolvedPath}`;\r\n \r\n // HTTP URL\uC758 \uC774\uC911 \uC2AC\uB798\uC2DC \uC81C\uAC70\r\n return fullUrl.replace(/([^:])\\/{2,}/g, '$1/');\r\n }\r\n\r\n /**\r\n * URL \uACBD\uB85C \uC815\uADDC\uD654 (\uC774\uC911 \uC2AC\uB798\uC2DC \uC81C\uAC70 \uBC0F ../, ./ \uCC98\uB9AC)\r\n */\r\n normalizePath(path) {\r\n // \uC774\uC911 \uC2AC\uB798\uC2DC \uC81C\uAC70\r\n path = path.replace(/\\/+/g, '/');\r\n const parts = path.split('/').filter(part => part !== '' && part !== '.');\r\n const stack = [];\r\n \r\n for (const part of parts) {\r\n if (part === '..') {\r\n if (stack.length > 0 && stack[stack.length - 1] !== '..') {\r\n stack.pop();\r\n } else if (!path.startsWith('/')) {\r\n stack.push(part);\r\n }\r\n } else {\r\n stack.push(part);\r\n }\r\n }\r\n \r\n const normalized = '/' + stack.join('/');\r\n return normalized === '/' ? '/' : normalized;\r\n }\r\n\r\n\r\n /**\r\n * \uB85C\uAE45 \uB798\uD37C \uBA54\uC11C\uB4DC\r\n */\r\n log(level, ...args) {\r\n if (this.errorHandler) {\r\n this.errorHandler.log(level, 'Router', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * \uD1B5\uD569 \uCD08\uAE30\uD654 - \uB9E4\uB2C8\uC800 \uC0DD\uC131 \u2192 \uBE44\uB3D9\uAE30 \uB85C\uB529 \u2192 \uB77C\uC6B0\uD130 \uC2DC\uC791\r\n */\r\n async initialize() {\r\n try {\r\n // 1. \uB9E4\uB2C8\uC800 \uCD08\uAE30\uD654 (\uB3D9\uAE30)\r\n // \uD56D\uC0C1 \uD544\uC694\uD55C \uB9E4\uB2C8\uC800\uB4E4\r\n this.cacheManager = new CacheManager(this, this.config);\r\n this.routeLoader = new RouteLoader(this, this.config);\r\n this.queryManager = new QueryManager(this, this.config);\r\n this.errorHandler = new ErrorHandler(this, this.config);\r\n \r\n // \uC870\uAC74\uBD80 \uB9E4\uB2C8\uC800\uB4E4\r\n if (this.config.useI18n) {\r\n try {\r\n this.i18nManager = new I18nManager(this, this.config);\r\n if (this.i18nManager.initPromise) {\r\n await this.i18nManager.initPromise;\r\n }\r\n this.log('info', 'I18nManager initialized successfully');\r\n } catch (i18nError) {\r\n this.log('warn', 'I18nManager initialization failed, continuing without i18n:', i18nError.message);\r\n this.i18nManager = null; // i18n \uB9E4\uB2C8\uC800 \uBE44\uD65C\uC131\uD654\r\n this.config.useI18n = false; // i18n \uBE44\uD65C\uC131\uD654\r\n }\r\n }\r\n \r\n if (this.config.authEnabled) {\r\n this.authManager = new AuthManager(this, this.config);\r\n }\r\n \r\n if (this.config.useComponents) {\r\n try {\r\n this.componentLoader = new ComponentLoader(this, {\r\n ...this.config,\r\n basePath: `${this.config.basePath}/components`,\r\n cache: true,\r\n componentNames: this.config.componentNames\r\n });\r\n await this.componentLoader.loadAllComponents();\r\n this.log('info', 'ComponentLoader initialized successfully');\r\n } catch (componentError) {\r\n this.log('warn', 'ComponentLoader initialization failed, continuing without components:', componentError.message);\r\n this.componentLoader = null; // \uCEF4\uD3EC\uB10C\uD2B8 \uB85C\uB354 \uBE44\uD65C\uC131\uD654\r\n }\r\n }\r\n \r\n // 2. \uB77C\uC6B0\uD130 \uC2DC\uC791\r\n this.isReady = true;\r\n this.init();\r\n \r\n } catch (error) {\r\n this.log('error', 'Router initialization failed:', error);\r\n // \uC2E4\uD328\uD574\uB3C4 \uB77C\uC6B0\uD130\uB294 \uC2DC\uC791 (graceful degradation)\r\n this.isReady = true;\r\n this.init();\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD130\uAC00 \uC900\uBE44\uB420 \uB54C\uAE4C\uC9C0 \uB300\uAE30\r\n */\r\n async waitForReady() {\r\n if (this.isReady) return true;\r\n if (this.readyPromise) {\r\n await this.readyPromise;\r\n }\r\n return this.isReady;\r\n }\r\n\r\n\r\n init() {\r\n const isHashMode = this.config.mode === 'hash';\r\n \r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uB4F1\uB85D (\uBA54\uBAA8\uB9AC \uCD5C\uC801\uD654)\r\n window.addEventListener(\r\n isHashMode ? 'hashchange' : 'popstate',\r\n this._boundHandleRouteChange\r\n );\r\n \r\n // DOM \uB85C\uB4DC \uCC98\uB9AC \uD1B5\uD569\r\n const initRoute = () => {\r\n if (isHashMode && !window.location.hash) {\r\n window.location.hash = '#/';\r\n } else if (!isHashMode && window.location.pathname === '/') {\r\n this.navigateTo('home');\r\n } else {\r\n this.handleRouteChange();\r\n }\r\n };\r\n \r\n if (document.readyState === 'loading') {\r\n document.addEventListener('DOMContentLoaded', initRoute);\r\n } else {\r\n // requestAnimationFrame\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n requestAnimationFrame(initRoute);\r\n }\r\n }\r\n\r\n handleRouteChange() {\r\n const { route, queryParams } = this._parseCurrentLocation();\r\n \r\n // Store current query parameters in QueryManager\r\n this.queryManager?.setCurrentQueryParams(queryParams);\r\n \r\n // \uBCC0\uACBD\uC0AC\uD56D\uC774 \uC788\uC744 \uB54C\uB9CC \uB85C\uB4DC (\uC131\uB2A5 \uCD5C\uC801\uD654)\r\n if (route !== this.currentHash || this.queryManager?.hasQueryParamsChanged(queryParams)) {\r\n this.currentHash = route;\r\n this.loadRoute(route);\r\n }\r\n }\r\n\r\n /**\r\n * \uD604\uC7AC \uC704\uCE58 \uD30C\uC2F1 (\uBD84\uB9AC\uD558\uC5EC \uAC00\uB3C5\uC131 \uD5A5\uC0C1)\r\n */\r\n _parseCurrentLocation() {\r\n if (this.config.mode === 'hash') {\r\n const hashPath = window.location.hash.slice(1) || '/';\r\n const [pathPart, queryPart] = hashPath.split('?');\r\n \r\n // \uACBD\uB85C \uD30C\uC2F1 \uCD5C\uC801\uD654\r\n let route = 'home';\r\n if (pathPart && pathPart !== '/') {\r\n route = pathPart.startsWith('/') ? pathPart.slice(1) : pathPart;\r\n }\r\n \r\n return {\r\n route: route || 'home',\r\n queryParams: this.queryManager?.parseQueryString(queryPart || window.location.search.slice(1)) || {}\r\n };\r\n } else {\r\n // History Mode - \uC11C\uBE0C\uD3F4\uB354 \uBC30\uD3EC \uC9C0\uC6D0\r\n const fullPath = window.location.pathname;\r\n const basePath = this.config.basePath || '/';\r\n \r\n // base path \uC81C\uAC70\uD558\uC5EC \uC2E4\uC81C route \uCD94\uCD9C\r\n let route = fullPath;\r\n if (basePath !== '/' && fullPath.startsWith(basePath)) {\r\n route = fullPath.slice(basePath.length);\r\n }\r\n \r\n // \uB9E8 \uC55E\uC758 / \uC81C\uAC70\r\n if (route.startsWith('/')) {\r\n route = route.slice(1);\r\n }\r\n \r\n return {\r\n route: route || 'home',\r\n queryParams: this.queryManager?.parseQueryString(window.location.search.slice(1)) || {}\r\n };\r\n }\r\n }\r\n\r\n async loadRoute(routeName) {\r\n // \uC804\uD658\uC774 \uC9C4\uD589 \uC911\uC774\uBA74 \uBB34\uC2DC\r\n const inProgress = this.transitionInProgress;\r\n \r\n if (inProgress) {\r\n return;\r\n }\r\n\r\n try {\r\n this.transitionInProgress = true;\r\n \r\n // \uC778\uC99D \uCCB4\uD06C\r\n const authResult = this.authManager ? \r\n await this.authManager.checkAuthentication(routeName) :\r\n { allowed: true, reason: 'auth_disabled' };\r\n if (!authResult.allowed) {\r\n // \uC778\uC99D \uC2E4\uD328 \uC2DC \uB85C\uADF8\uC778 \uD398\uC774\uC9C0\uB85C \uB9AC\uB2E4\uC774\uB809\uD2B8\r\n if (this.authManager) {\r\n this.authManager.emitAuthEvent('auth_required', { \r\n originalRoute: routeName,\r\n loginRoute: this.config.loginRoute \r\n });\r\n \r\n // navigateTo\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC774\uC804 \uD398\uC774\uC9C0\uB85C \uB3CC\uC544\uAC00\uAE30 \uC9C0\uC6D0\r\n if (routeName !== this.config.loginRoute) {\r\n this.navigateTo(this.config.loginRoute, { redirect: routeName });\r\n } else {\r\n this.navigateTo(this.config.loginRoute);\r\n }\r\n }\r\n return;\r\n }\r\n \r\n const appElement = document.getElementById('app');\r\n if (!appElement) {\r\n throw new Error('App element not found');\r\n }\r\n\r\n // Vue \uCEF4\uD3EC\uB10C\uD2B8 \uC0DD\uC131 (\uBC31\uADF8\uB77C\uC6B4\uB4DC\uC5D0\uC11C)\r\n const component = await this.routeLoader.createVueComponent(routeName);\r\n \r\n // \uC0C8\uB85C\uC6B4 \uD398\uC774\uC9C0\uB97C \uC624\uBC84\uB808\uC774\uB85C \uB80C\uB354\uB9C1\r\n await this.renderComponentWithTransition(component, routeName);\r\n \r\n // \uB85C\uB529 \uC644\uB8CC\r\n \r\n } catch (error) {\r\n this.log('error', `Route loading failed [${routeName}]:`, error.message);\r\n \r\n \r\n // \uC5D0\uB7EC \uD0C0\uC785\uC5D0 \uB530\uB978 \uCC98\uB9AC\r\n if (this.errorHandler) {\r\n await this.errorHandler.handleRouteError(routeName, error);\r\n } else {\r\n console.error('[Router] No error handler available');\r\n }\r\n } finally {\r\n // \uBAA8\uB4E0 \uCC98\uB9AC\uAC00 \uC644\uB8CC\uB41C \uD6C4 \uC804\uD658 \uC0C1\uD0DC \uB9AC\uC14B\r\n this.transitionInProgress = false;\r\n }\r\n }\r\n\r\n async renderComponentWithTransition(vueComponent, routeName) {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n // \uC0C8\uB85C\uC6B4 \uD398\uC774\uC9C0 \uCEE8\uD14C\uC774\uB108 \uC0DD\uC131\r\n const newPageContainer = document.createElement('div');\r\n newPageContainer.className = 'page-container page-entered';\r\n newPageContainer.id = `page-${routeName}-${Date.now()}`;\r\n \r\n // \uAE30\uC874 \uCEE8\uD14C\uC774\uB108\uAC00 \uC788\uB2E4\uBA74 \uC989\uC2DC \uC228\uAE30\uAE30\r\n const existingContainers = appElement.querySelectorAll('.page-container');\r\n existingContainers.forEach(container => {\r\n container.classList.remove('page-entered');\r\n container.classList.add('page-exiting');\r\n });\r\n\r\n // \uC0C8 \uCEE8\uD14C\uC774\uB108\uB97C \uC571\uC5D0 \uCD94\uAC00\r\n appElement.appendChild(newPageContainer);\r\n\r\n // \uAC1C\uBC1C \uBAA8\uB4DC\uC5D0\uC11C\uB9CC \uC2A4\uD0C0\uC77C \uC801\uC6A9 (\uD504\uB85C\uB355\uC158 \uBAA8\uB4DC\uB294 \uBE4C\uB4DC\uB41C JS\uC5D0\uC11C \uC790\uB3D9 \uCC98\uB9AC)\r\n if (this.config.environment === 'development' && vueComponent._style) {\r\n this.applyStyle(vueComponent._style, routeName);\r\n }\r\n \r\n // \uC0C8\uB85C\uC6B4 Vue \uC571\uC744 \uC0C8 \uCEE8\uD14C\uC774\uB108\uC5D0 \uB9C8\uC6B4\uD2B8\r\n const { createApp } = Vue;\r\n const newVueApp = createApp(vueComponent);\r\n \r\n // Vue 3 \uC804\uC5ED \uC18D\uC131 \uC124\uC815\r\n newVueApp.config.globalProperties.$router = {\r\n navigateTo: (route, params) => this.navigateTo(route, params),\r\n getCurrentRoute: () => this.getCurrentRoute(),\r\n \r\n // \uD1B5\uD569\uB41C \uD30C\uB77C\uBBF8\uD130 \uAD00\uB9AC (\uB77C\uC6B0\uD305 + \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130)\r\n getParams: () => this.queryManager?.getAllParams() || {},\r\n getParam: (key, defaultValue) => this.queryManager?.getParam(key, defaultValue),\r\n \r\n // \uCFFC\uB9AC \uD30C\uB77C\uBBF8\uD130 \uC804\uC6A9 \uBA54\uC11C\uB4DC (\uD558\uC704 \uD638\uD658\uC131)\r\n getQueryParams: () => this.queryManager?.getQueryParams() || {},\r\n getQueryParam: (key, defaultValue) => this.queryManager?.getQueryParam(key, defaultValue),\r\n setQueryParams: (params, replace) => this.queryManager?.setQueryParams(params, replace),\r\n removeQueryParams: (keys) => this.queryManager?.removeQueryParams(keys),\r\n \r\n // \uB77C\uC6B0\uD305 \uD30C\uB77C\uBBF8\uD130 \uC804\uC6A9 \uBA54\uC11C\uB4DC\r\n getRouteParams: () => this.queryManager?.getRouteParams() || {},\r\n getRouteParam: (key, defaultValue) => this.queryManager?.getRouteParam(key, defaultValue),\r\n \r\n currentRoute: this.currentHash,\r\n currentQuery: this.queryManager?.getQueryParams() || {}\r\n };\r\n\r\n // \uBAA8\uBC14\uC77C \uBA54\uB274 \uC804\uC5ED \uD568\uC218 \uCD94\uAC00\r\n\r\n newVueApp.mount(`#${newPageContainer.id}`);\r\n\r\n // requestAnimationFrame\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n requestAnimationFrame(() => {\r\n this.cleanupPreviousPages();\r\n this.transitionInProgress = false;\r\n });\r\n\r\n // \uC774\uC804 \uC571 \uC815\uB9AC \uC900\uBE44\r\n if (this.currentVueApp) {\r\n this.previousVueApp = this.currentVueApp;\r\n }\r\n \r\n this.currentVueApp = newVueApp;\r\n }\r\n\r\n cleanupPreviousPages() {\r\n const appElement = document.getElementById('app');\r\n if (!appElement) return;\r\n\r\n // \uBC30\uCE58 DOM \uC870\uC791\uC73C\uB85C \uC131\uB2A5 \uAC1C\uC120\r\n const fragment = document.createDocumentFragment();\r\n const exitingContainers = appElement.querySelectorAll('.page-container.page-exiting');\r\n \r\n // \uD55C\uBC88\uC5D0 \uC81C\uAC70\r\n exitingContainers.forEach(container => container.remove());\r\n\r\n // \uC774\uC804 Vue \uC571 \uC815\uB9AC\r\n if (this.previousVueApp) {\r\n try {\r\n this.previousVueApp.unmount();\r\n } catch (error) {\r\n // \uBB34\uC2DC (\uC774\uBBF8 \uC5B8\uB9C8\uC6B4\uD2B8\uB41C \uACBD\uC6B0)\r\n }\r\n this.previousVueApp = null;\r\n }\r\n\r\n // \uB85C\uB529 \uC5D8\uB9AC\uBA3C\uD2B8 \uC81C\uAC70\r\n \r\n appElement.querySelector('.loading')?.remove();\r\n }\r\n\r\n applyStyle(css, routeName) {\r\n // \uAE30\uC874 \uC2A4\uD0C0\uC77C \uC81C\uAC70\r\n const existing = document.querySelector(`style[data-route=\"${routeName}\"]`);\r\n if (existing) existing.remove();\r\n\r\n if (css) {\r\n const style = document.createElement('style');\r\n style.textContent = css;\r\n style.setAttribute('data-route', routeName);\r\n document.head.appendChild(style);\r\n }\r\n }\r\n\r\n\r\n navigateTo(routeName, params = null) {\r\n // If routeName is an object, treat it as {route, params}\r\n if (typeof routeName === 'object') {\r\n params = routeName.params || null;\r\n routeName = routeName.route;\r\n }\r\n \r\n // Clear current query params if navigating to a different route\r\n if (routeName !== this.currentHash && this.queryManager) {\r\n this.queryManager.clearQueryParams();\r\n }\r\n \r\n // Set route parameters\r\n if (this.queryManager) {\r\n this.queryManager.setCurrentRouteParams(params);\r\n }\r\n \r\n // Update URL with new route and params\r\n this.updateURL(routeName, params);\r\n }\r\n\r\n getCurrentRoute() {\r\n return this.currentHash;\r\n }\r\n\r\n\r\n updateURL(route, params = null) {\r\n const queryParams = params || this.queryManager?.getQueryParams() || {};\r\n const queryString = this.queryManager?.buildQueryString(queryParams) || '';\r\n \r\n // URL \uBE4C\uB4DC \uCD5C\uC801\uD654 - \uC11C\uBE0C\uD3F4\uB354 \uBC30\uD3EC \uC9C0\uC6D0\r\n const buildURL = (route, queryString, isHash = true) => {\r\n let base = route === 'home' ? '/' : `/${route}`;\r\n \r\n // History Mode\uC5D0\uC11C basePath \uACBD\uB85C \uCD94\uAC00\r\n if (!isHash && this.config.basePath && this.config.basePath !== '/') {\r\n base = `${this.config.basePath}${base}`;\r\n }\r\n \r\n const url = queryString ? `${base}?${queryString}` : base;\r\n return isHash ? `#${url}` : url;\r\n };\r\n \r\n if (this.config.mode === 'hash') {\r\n const newHash = buildURL(route, queryString);\r\n \r\n // \uB3D9\uC77C\uD55C URL\uC774\uBA74 \uC5C5\uB370\uC774\uD2B8\uD558\uC9C0 \uC54A\uC74C (\uC131\uB2A5 \uCD5C\uC801\uD654)\r\n if (window.location.hash !== newHash) {\r\n window.location.hash = newHash;\r\n }\r\n } else {\r\n const newPath = buildURL(route, queryString, false);\r\n \r\n // \uC11C\uBE0C\uD3F4\uB354 \uBC30\uD3EC\uB97C \uACE0\uB824\uD55C \uACBD\uB85C \uBE44\uAD50\r\n let expectedPath = route === 'home' ? '/' : `/${route}`;\r\n if (this.config.basePath && this.config.basePath !== '/') {\r\n expectedPath = `${this.config.basePath}${expectedPath}`;\r\n }\r\n \r\n const isSameRoute = window.location.pathname === expectedPath;\r\n \r\n if (isSameRoute) {\r\n window.history.replaceState({}, '', newPath);\r\n } else {\r\n window.history.pushState({}, '', newPath);\r\n }\r\n this.handleRouteChange();\r\n }\r\n }\r\n\r\n /**\r\n * \uB77C\uC6B0\uD130 \uC815\uB9AC (\uBA54\uBAA8\uB9AC \uB204\uC218 \uBC29\uC9C0)\r\n */\r\n destroy() {\r\n // \uC774\uBCA4\uD2B8 \uB9AC\uC2A4\uB108 \uC81C\uAC70\r\n window.removeEventListener(\r\n this.config.mode === 'hash' ? 'hashchange' : 'popstate',\r\n this._boundHandleRouteChange\r\n );\r\n \r\n // \uD604\uC7AC Vue \uC571 \uC5B8\uB9C8\uC6B4\uD2B8\r\n if (this.currentVueApp) {\r\n this.currentVueApp.unmount();\r\n this.currentVueApp = null;\r\n }\r\n \r\n // \uC774\uC804 Vue \uC571 \uC5B8\uB9C8\uC6B4\uD2B8\r\n if (this.previousVueApp) {\r\n this.previousVueApp.unmount();\r\n this.previousVueApp = null;\r\n }\r\n \r\n // \uB9E4\uB2C8\uC800 \uC815\uB9AC\r\n Object.values(this).forEach(manager => {\r\n if (manager && typeof manager.destroy === 'function') {\r\n manager.destroy();\r\n }\r\n });\r\n \r\n // \uCE90\uC2DC \uD074\uB9AC\uC5B4\r\n this.cacheManager?.clearAll();\r\n \r\n // DOM \uC815\uB9AC\r\n const appElement = document.getElementById('app');\r\n if (appElement) {\r\n appElement.innerHTML = '';\r\n }\r\n \r\n this.log('info', 'Router destroyed');\r\n }\r\n}\r\n// \uC804\uC5ED \uB77C\uC6B0\uD130\uB294 index.html\uC5D0\uC11C \uD658\uACBD\uC124\uC815\uACFC \uD568\uAED8 \uC0DD\uC131\uB428"],
|
|
5
|
+
"mappings": ";;;;;;;AAIO,IAAM,cAAN,MAAkB;AAAA,EACrB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,SAAS,QAAQ,YAAY,SAAY,QAAQ,UAAU;AAAA,MAC3D,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,kBAAkB,QAAQ,mBAAmB;AAAA,MAC7C,UAAU,QAAQ,YAAY;AAAA,MAC9B,cAAc,QAAQ,gBAAgB;AAAA,MACtC,cAAc,QAAQ,gBAAgB;AAAA,MACtC,iBAAiB,QAAQ,oBAAoB;AAAA,MAC7C,OAAO,QAAQ,SAAS;AAAA,IAC5B;AAGA,SAAK,SAAS;AAEd,SAAK,WAAW,oBAAI,IAAI;AACxB,SAAK,kBAAkB,KAAK,OAAO;AACnC,SAAK,YAAY;AACjB,SAAK,eAAe,oBAAI,IAAI;AAG5B,SAAK,YAAY;AAAA,MACb,iBAAiB,CAAC;AAAA,IACtB;AAGA,SAAK,cAAc,KAAK,KAAK;AAAA,EACjC;AAAA,EAEA,MAAM,OAAO;AAET,QAAI,CAAC,KAAK,OAAO,SAAS;AACtB,WAAK,IAAI,QAAQ,sBAAsB;AACvC;AAAA,IACJ;AAGA,SAAK,sBAAsB;AAG3B,QAAI,KAAK,OAAO,OAAO;AACnB,WAAK,OAAO,kBAAkB;AAC9B,WAAK,IAAI,SAAS,mCAAmC;AAAA,IACzD;AAGA,QAAI,CAAC,KAAK,SAAS,IAAI,KAAK,eAAe,GAAG;AAC1C,UAAI;AACA,cAAM,KAAK,aAAa,KAAK,eAAe;AAAA,MAChD,SAAS,OAAO;AACZ,aAAK,IAAI,SAAS,yCAAyC,KAAK;AAEhE,aAAK,SAAS,IAAI,KAAK,iBAAiB,CAAC,CAAC;AAC1C,aAAK,IAAI,QAAQ,wCAAwC;AAAA,MAC7D;AAAA,IACJ,OAAO;AACH,WAAK,IAAI,SAAS,qCAAqC,KAAK,eAAe;AAAA,IAC/E;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACpB,QAAI;AACA,YAAM,aAAa,aAAa,QAAQ,KAAK,OAAO,QAAQ;AAC5D,UAAI,cAAc,KAAK,gBAAgB,UAAU,GAAG;AAChD,aAAK,kBAAkB;AACvB,aAAK,IAAI,SAAS,+BAA+B,UAAU;AAAA,MAC/D;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,uCAAuC,KAAK;AAAA,IACjE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,MAAM;AAClB,WAAO,OAAO,SAAS,YAAY,aAAa,KAAK,IAAI;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAY,UAAU;AACxB,QAAI,CAAC,KAAK,gBAAgB,QAAQ,GAAG;AACjC,WAAK,IAAI,QAAQ,0BAA0B,QAAQ;AACnD,aAAO;AAAA,IACX;AAEA,QAAI,KAAK,oBAAoB,UAAU;AACnC,WAAK,IAAI,SAAS,4BAA4B,QAAQ;AACtD,aAAO;AAAA,IACX;AAEA,UAAM,cAAc,KAAK;AACzB,SAAK,kBAAkB;AAEvB,QAAI;AAEA,YAAM,KAAK,aAAa,QAAQ;AAGhC,WAAK,oBAAoB,QAAQ;AAGjC,WAAK,KAAK,mBAAmB;AAAA,QACzB,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,KAAK,SAAS,IAAI,QAAQ;AAAA,MACxC,CAAC;AAED,WAAK,IAAI,QAAQ,iCAAiC,EAAE,MAAM,aAAa,IAAI,SAAS,CAAC;AACrF,aAAO;AAAA,IACX,SAAS,OAAO;AAEZ,WAAK,IAAI,SAAS,sEAAsE,KAAK;AAC7F,WAAK,SAAS,IAAI,UAAU,CAAC,CAAC;AAG9B,WAAK,oBAAoB,QAAQ;AAGjC,WAAK,KAAK,mBAAmB;AAAA,QACzB,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,CAAC;AAAA,QACX,OAAO;AAAA,MACX,CAAC;AAED,WAAK,IAAI,QAAQ,wCAAwC,EAAE,MAAM,aAAa,IAAI,SAAS,CAAC;AAC5F,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,UAAU;AAC1B,QAAI;AACA,mBAAa,QAAQ,KAAK,OAAO,UAAU,QAAQ;AACnD,WAAK,IAAI,SAAS,4BAA4B,QAAQ;AAAA,IAC1D,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,qCAAqC,KAAK;AAAA,IAC/D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,UAAU;AAEzB,QAAI,KAAK,SAAS,IAAI,QAAQ,GAAG;AAC7B,WAAK,IAAI,SAAS,gCAAgC,QAAQ;AAC1D,aAAO,KAAK,SAAS,IAAI,QAAQ;AAAA,IACrC;AAGA,QAAI,KAAK,aAAa,IAAI,QAAQ,GAAG;AACjC,WAAK,IAAI,SAAS,qCAAqC,QAAQ;AAC/D,aAAO,MAAM,KAAK,aAAa,IAAI,QAAQ;AAAA,IAC/C;AAEA,UAAM,cAAc,KAAK,sBAAsB,QAAQ;AACvD,SAAK,aAAa,IAAI,UAAU,WAAW;AAE3C,QAAI;AACA,YAAM,WAAW,MAAM;AACvB,WAAK,SAAS,IAAI,UAAU,QAAQ;AACpC,WAAK,aAAa,OAAO,QAAQ;AACjC,WAAK,IAAI,SAAS,qCAAqC,QAAQ;AAC/D,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,aAAa,OAAO,QAAQ;AAEjC,WAAK,IAAI,SAAS,sDAAsD,UAAU,KAAK;AACvF,YAAM,gBAAgB,CAAC;AACvB,WAAK,SAAS,IAAI,UAAU,aAAa;AACzC,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBAAsB,UAAU;AAElC,QAAI,KAAK,OAAO,iBAAiB;AAC7B,YAAM,aAAa,KAAK,iBAAiB,QAAQ;AACjD,UAAI,YAAY;AACZ,aAAK,IAAI,SAAS,+BAA+B,QAAQ;AACzD,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,QAAI;AAEA,YAAM,WAAW,GAAG,KAAK,OAAO,OAAO,QAAQ,IAAI,QAAQ;AAC3D,YAAM,WAAW,MAAM,MAAM,QAAQ;AACrC,UAAI,CAAC,SAAS,IAAI;AACd,cAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,EAAE;AAAA,MAC5D;AACA,YAAM,WAAW,MAAM,SAAS,KAAK;AAGrC,UAAI,KAAK,OAAO,iBAAiB;AAC7B,aAAK,gBAAgB,UAAU,QAAQ;AAAA,MAC3C;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,qCAAqC,UAAU,KAAK;AAGtE,UAAI,aAAa,KAAK,OAAO,kBAAkB;AAC3C,aAAK,IAAI,QAAQ,6BAA6B,KAAK,OAAO,gBAAgB;AAC1E,YAAI;AACA,iBAAO,MAAM,KAAK,sBAAsB,KAAK,OAAO,gBAAgB;AAAA,QACxE,SAAS,eAAe;AACpB,eAAK,IAAI,SAAS,kCAAkC,aAAa;AAEjE,iBAAO,CAAC;AAAA,QACZ;AAAA,MACJ;AAGA,WAAK,IAAI,QAAQ,uCAAuC,QAAQ,wBAAwB;AACxF,aAAO,CAAC;AAAA,IACZ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,UAAU;AACvB,QAAI;AACA,YAAM,WAAW,GAAG,KAAK,OAAO,YAAY,IAAI,QAAQ,IAAI,KAAK,OAAO,YAAY;AACpF,YAAM,aAAa,aAAa,QAAQ,QAAQ;AAEhD,UAAI,YAAY;AACZ,cAAM,EAAE,MAAM,WAAW,QAAQ,IAAI,KAAK,MAAM,UAAU;AAG1D,YAAI,YAAY,KAAK,OAAO,cAAc;AACtC,eAAK,IAAI,SAAS,qCAAqC,QAAQ;AAC/D,uBAAa,WAAW,QAAQ;AAChC,iBAAO;AAAA,QACX;AAGA,cAAM,MAAM,KAAK,IAAI;AACrB,cAAM,SAAS,KAAK,KAAK,KAAK;AAE9B,YAAI,MAAM,YAAY,QAAQ;AAC1B,eAAK,IAAI,SAAS,4BAA4B,QAAQ;AACtD,uBAAa,WAAW,QAAQ;AAChC,iBAAO;AAAA,QACX;AAEA,eAAO;AAAA,MACX;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,8BAA8B,KAAK;AAAA,IACxD;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,UAAU,MAAM;AAC5B,QAAI;AACA,YAAM,WAAW,GAAG,KAAK,OAAO,YAAY,IAAI,QAAQ,IAAI,KAAK,OAAO,YAAY;AACpF,YAAM,YAAY;AAAA,QACd;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,SAAS,KAAK,OAAO;AAAA,MACzB;AAEA,mBAAa,QAAQ,UAAU,KAAK,UAAU,SAAS,CAAC;AACxD,WAAK,IAAI,SAAS,wBAAwB,QAAQ;AAAA,IACtD,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,4BAA4B,KAAK;AAAA,IACtD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,EAAE,KAAK,SAAS,CAAC,GAAG;AAEhB,QAAI,CAAC,KAAK,OAAO,SAAS;AACtB,aAAO;AAAA,IACX;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,KAAK,eAAe;AACvD,QAAI,CAAC,UAAU;AACX,WAAK,IAAI,QAAQ,4CAA4C,KAAK,eAAe;AACjF,aAAO;AAAA,IACX;AAEA,UAAM,UAAU,KAAK,eAAe,UAAU,GAAG;AACjD,QAAI,YAAY,QAAW;AACvB,WAAK,IAAI,QAAQ,kCAAkC,GAAG;AAGtD,YAAM,mBAAmB,KAAK,SAAS,IAAI,KAAK,OAAO,gBAAgB;AACvE,UAAI,oBAAoB,KAAK,oBAAoB,KAAK,OAAO,kBAAkB;AAC3E,cAAM,kBAAkB,KAAK,eAAe,kBAAkB,GAAG;AACjE,YAAI,oBAAoB,QAAW;AAC/B,iBAAO,KAAK,YAAY,iBAAiB,MAAM;AAAA,QACnD;AAAA,MACJ;AAEA,aAAO;AAAA,IACX;AAEA,WAAO,KAAK,YAAY,SAAS,MAAM;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,KAAK,MAAM;AACtB,WAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,SAAS,QAAQ;AAC5C,aAAO,WAAW,QAAQ,GAAG,MAAM,SAAY,QAAQ,GAAG,IAAI;AAAA,IAClE,GAAG,GAAG;AAAA,EACV;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,SAAS,QAAQ;AACzB,QAAI,OAAO,YAAY,UAAU;AAC7B,aAAO;AAAA,IACX;AAEA,WAAO,QAAQ,QAAQ,cAAc,CAAC,OAAO,QAAQ;AACjD,aAAO,OAAO,eAAe,GAAG,IAAI,OAAO,GAAG,IAAI;AAAA,IACtD,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAK,OAAO,SAAS,CAAC,GAAG;AAC5B,UAAM,YAAY,UAAU,IAAI,GAAG,GAAG,cAAc,GAAG,GAAG;AAC1D,WAAO,KAAK,EAAE,WAAW,EAAE,GAAG,QAAQ,MAAM,CAAC;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACpB,WAAO,CAAC,MAAM,IAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,GAAG,OAAO,UAAU;AAChB,QAAI,KAAK,UAAU,KAAK,GAAG;AACvB,WAAK,UAAU,KAAK,EAAE,KAAK,QAAQ;AAAA,IACvC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAO,UAAU;AACjB,QAAI,KAAK,UAAU,KAAK,GAAG;AACvB,YAAM,QAAQ,KAAK,UAAU,KAAK,EAAE,QAAQ,QAAQ;AACpD,UAAI,QAAQ,IAAI;AACZ,aAAK,UAAU,KAAK,EAAE,OAAO,OAAO,CAAC;AAAA,MACzC;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,OAAO,MAAM;AACd,QAAI,KAAK,UAAU,KAAK,GAAG;AACvB,WAAK,UAAU,KAAK,EAAE,QAAQ,cAAY;AACtC,YAAI;AACA,mBAAS,IAAI;AAAA,QACjB,SAAS,OAAO;AACZ,eAAK,IAAI,SAAS,4BAA4B,KAAK;AAAA,QACvD;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACV,WAAO,KAAK,SAAS,IAAI,KAAK,eAAe,KAAK,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,MAAM,UAAU,CAAC,GAAG;AAC3B,UAAM,SAAS,KAAK,oBAAoB,OAAO,UAAU;AACzD,WAAO,IAAI,KAAK,eAAe,QAAQ,OAAO,EAAE,OAAO,IAAI,KAAK,IAAI,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,QAAQ,UAAU,CAAC,GAAG;AAC/B,UAAM,SAAS,KAAK,oBAAoB,OAAO,UAAU;AACzD,WAAO,IAAI,KAAK,aAAa,QAAQ,OAAO,EAAE,OAAO,MAAM;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,eAAe,GAAG,IAAI;AAAA,IAC9D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACR,WAAO,KAAK,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACZ,QAAI,CAAC,KAAK,OAAO,SAAS;AACtB,aAAO;AAAA,IACX;AAEA,QAAI;AACA,YAAM,KAAK;AACX,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,+BAA+B,KAAK;AAEtD,WAAK,IAAI,QAAQ,0CAA0C;AAC3D,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AACT,QAAI;AACA,YAAM,OAAO,OAAO,KAAK,YAAY;AACrC,YAAM,YAAY,KAAK,OAAO,SAAO,IAAI,WAAW,KAAK,OAAO,YAAY,CAAC;AAE7E,gBAAU,QAAQ,SAAO;AACrB,qBAAa,WAAW,GAAG;AAAA,MAC/B,CAAC;AAED,WAAK,IAAI,SAAS,0BAA0B,UAAU,QAAQ,OAAO;AAAA,IACzE,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,0BAA0B,KAAK;AAAA,IACpD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,UAAM,OAAO;AAAA,MACT,SAAS,KAAK,OAAO;AAAA,MACrB,SAAS,KAAK,OAAO;AAAA,MACrB,WAAW,CAAC;AAAA,IAChB;AAEA,QAAI;AACA,YAAM,OAAO,OAAO,KAAK,YAAY;AACrC,YAAM,YAAY,KAAK,OAAO,SAAO,IAAI,WAAW,KAAK,OAAO,YAAY,CAAC;AAE7E,gBAAU,QAAQ,SAAO;AACrB,cAAM,QAAQ,IAAI,MAAM,IAAI,OAAO,GAAG,KAAK,OAAO,YAAY,YAAa,CAAC;AAC5E,YAAI,OAAO;AACP,gBAAM,CAAC,EAAE,UAAU,OAAO,IAAI;AAC9B,gBAAM,aAAa,KAAK,MAAM,aAAa,QAAQ,GAAG,CAAC;AAEvD,eAAK,UAAU,QAAQ,IAAI;AAAA,YACvB;AAAA,YACA,WAAW,WAAW;AAAA,YACtB,KAAK,KAAK,IAAI,IAAI,WAAW;AAAA,UACjC;AAAA,QACJ;AAAA,MACJ,CAAC;AAAA,IACL,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,6BAA6B,KAAK;AAAA,IACvD;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa;AACf,QAAI,CAAC,KAAK,OAAO,SAAS;AACtB,WAAK,IAAI,QAAQ,kDAAkD;AACnE,aAAO;AAAA,IACX;AAEA,QAAI;AAEA,YAAM,KAAK;AACX,WAAK,IAAI,QAAQ,+BAA+B;AAChD,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,qCAAqC,KAAK;AAE5D,WAAK,IAAI,QAAQ,kDAAkD;AACnE,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;;;ACvhBO,IAAM,cAAN,MAAkB;AAAA,EACrB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,SAAS,QAAQ,eAAe;AAAA,MAChC,YAAY,QAAQ,cAAc;AAAA,MAClC,iBAAiB,QAAQ,mBAAmB,CAAC;AAAA,MAC7C,mBAAmB,QAAQ,qBAAqB,CAAC;AAAA,MACjD,cAAc,QAAQ,gBAAgB,CAAC,SAAS,YAAY,MAAM;AAAA,MAClE,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,oBAAoB,QAAQ,sBAAsB;AAAA;AAAA,MAElD,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,yBAAyB,QAAQ,2BAA2B,CAAC,eAAe,SAAS,KAAK;AAAA,MAC1F,aAAa,QAAQ,eAAe;AAAA,MACpC,mBAAmB,QAAQ,qBAAqB,CAAC;AAAA,MACjD,oBAAoB,QAAQ,sBAAsB;AAAA,MAClD,OAAO,QAAQ,SAAS;AAAA,IAC5B;AAGA,SAAK,SAAS;AAGd,SAAK,iBAAiB,oBAAI,IAAI;AAE9B,SAAK,IAAI,QAAQ,2BAA2B,EAAE,SAAS,KAAK,OAAO,QAAQ,CAAC;AAAA,EAChF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,eAAe,GAAG,IAAI;AAAA,IAC9D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB,WAAW;AAEjC,QAAI,CAAC,KAAK,OAAO,SAAS;AACtB,aAAO,EAAE,SAAS,MAAM,QAAQ,gBAAgB;AAAA,IACpD;AAEA,SAAK,IAAI,SAAS,gDAAyC,SAAS,EAAE;AAGtE,QAAI,KAAK,cAAc,SAAS,GAAG;AAC/B,aAAO,EAAE,SAAS,MAAM,QAAQ,eAAe;AAAA,IACnD;AAGA,UAAM,cAAc,KAAK,iBAAiB,SAAS;AACnD,QAAI,CAAC,aAAa;AACd,aAAO,EAAE,SAAS,MAAM,QAAQ,gBAAgB;AAAA,IACpD;AAGA,QAAI,OAAO,KAAK,OAAO,sBAAsB,YAAY;AACrD,UAAI;AACA,cAAMA,mBAAkB,MAAM,KAAK,OAAO,kBAAkB,SAAS;AACrE,eAAO;AAAA,UACH,SAASA;AAAA,UACT,QAAQA,mBAAkB,wBAAwB;AAAA,UAClD;AAAA,QACJ;AAAA,MACJ,SAAS,OAAO;AACZ,aAAK,IAAI,SAAS,gCAAgC,KAAK;AACvD,eAAO,EAAE,SAAS,OAAO,QAAQ,qBAAqB,MAAM;AAAA,MAChE;AAAA,IACJ;AAGA,UAAM,kBAAkB,KAAK,oBAAoB;AACjD,WAAO;AAAA,MACH,SAAS;AAAA,MACT,QAAQ,kBAAkB,kBAAkB;AAAA,MAC5C;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB;AAClB,SAAK,IAAI,SAAS,+CAAwC;AAG1D,UAAM,QAAQ,aAAa,QAAQ,WAAW,KAAK,aAAa,QAAQ,aAAa;AACrF,QAAI,OAAO;AACP,UAAI;AACA,YAAI,MAAM,SAAS,GAAG,GAAG;AACrB,gBAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACpD,cAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,QAAQ,MAAM,KAAM;AACjD,iBAAK,IAAI,SAAS,yCAAyC;AAC3D,yBAAa,WAAW,WAAW;AACnC,yBAAa,WAAW,aAAa;AACrC,mBAAO;AAAA,UACX;AAAA,QACJ;AACA,aAAK,IAAI,SAAS,0CAAqC;AACvD,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,aAAK,IAAI,QAAQ,kCAAkC,KAAK;AAAA,MAC5D;AAAA,IACJ;AAGA,UAAM,eAAe,eAAe,QAAQ,WAAW,KAAK,eAAe,QAAQ,aAAa;AAChG,QAAI,cAAc;AACd,WAAK,IAAI,SAAS,sCAAiC;AACnD,aAAO;AAAA,IACX;AAGA,UAAM,aAAa,KAAK,cAAc;AACtC,QAAI,YAAY;AACZ,UAAI;AACA,YAAI,WAAW,SAAS,GAAG,GAAG;AAC1B,gBAAM,UAAU,KAAK,MAAM,KAAK,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACzD,cAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,QAAQ,MAAM,KAAM;AACjD,iBAAK,IAAI,SAAS,mCAAmC;AACrD,iBAAK,iBAAiB;AACtB,mBAAO;AAAA,UACX;AAAA,QACJ;AACA,aAAK,IAAI,SAAS,qCAAgC;AAClD,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,aAAK,IAAI,QAAQ,mCAAmC,KAAK;AAAA,MAC7D;AAAA,IACJ;AAGA,QAAI,OAAO,QAAQ,OAAO,iBAAiB;AACvC,WAAK,IAAI,SAAS,6CAAwC;AAC1D,aAAO;AAAA,IACX;AAEA,SAAK,IAAI,SAAS,sCAAiC;AACnD,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,WAAW;AACrB,WAAO,KAAK,OAAO,aAAa,SAAS,SAAS;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,WAAW;AAExB,QAAI,KAAK,OAAO,gBAAgB,SAAS,SAAS,GAAG;AACjD,aAAO;AAAA,IACX;AAGA,eAAW,UAAU,KAAK,OAAO,mBAAmB;AAChD,UAAI,UAAU,WAAW,MAAM,GAAG;AAC9B,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AAEZ,UAAM,gBAAgB,KAAK,eAAe,KAAK,OAAO,cAAc;AACpE,QAAI,eAAe;AACf,aAAO;AAAA,IACX;AAGA,eAAW,cAAc,KAAK,OAAO,yBAAyB;AAC1D,YAAM,cAAc,KAAK,eAAe,UAAU;AAClD,UAAI,aAAa;AACb,aAAK,IAAI,SAAS,wCAAwC,UAAU,EAAE;AACtE,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,MAAM;AACjB,UAAM,QAAQ,KAAK,SAAS,MAAM;AAClC,UAAM,QAAQ,MAAM,MAAM,KAAK,IAAI,GAAG;AACtC,QAAI,MAAM,WAAW,GAAG;AACpB,aAAO,mBAAmB,MAAM,IAAI,EAAE,MAAM,GAAG,EAAE,MAAM,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB;AACf,UAAM,kBAAkB,CAAC,KAAK,OAAO,gBAAgB,GAAG,KAAK,OAAO,uBAAuB;AAE3F,oBAAgB,QAAQ,gBAAc;AAElC,eAAS,SAAS,GAAG,UAAU;AAC/B,eAAS,SAAS,GAAG,UAAU,kDAAkD,OAAO,SAAS,QAAQ;AAAA,IAC7G,CAAC;AAED,SAAK,IAAI,SAAS,sBAAsB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB;AAEb,QAAI,QAAQ,aAAa,QAAQ,WAAW,KAAK,aAAa,QAAQ,aAAa;AACnF,QAAI,MAAO,QAAO;AAGlB,YAAQ,eAAe,QAAQ,WAAW,KAAK,eAAe,QAAQ,aAAa;AACnF,QAAI,MAAO,QAAO;AAGlB,YAAQ,KAAK,cAAc;AAC3B,QAAI,MAAO,QAAO;AAElB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,OAAO,UAAU,CAAC,GAAG;AAChC,QAAI,CAAC,OAAO;AACR,WAAK,IAAI,QAAQ,sBAAsB;AACvC,aAAO;AAAA,IACX;AAEA,UAAM;AAAA,MACF,UAAU,KAAK,OAAO;AAAA,MACtB,gBAAgB,KAAK,OAAO;AAAA,MAC5B,iBAAiB,KAAK,OAAO;AAAA,IACjC,IAAI;AAEJ,QAAI;AAEA,UAAI,CAAC,kBAAkB,MAAM,SAAS,GAAG,GAAG;AACxC,YAAI;AACA,gBAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACpD,cAAI,QAAQ,OAAO,KAAK,IAAI,KAAK,QAAQ,MAAM,KAAM;AACjD,iBAAK,IAAI,QAAQ,yBAAoB;AACrC,mBAAO;AAAA,UACX;AACA,eAAK,IAAI,SAAS,4BAAuB;AAAA,QAC7C,SAAS,OAAO;AACZ,eAAK,IAAI,QAAQ,uDAA6C,MAAM,OAAO;AAAA,QAC/E;AAAA,MACJ;AAGA,cAAQ,SAAS;AAAA,QACb,KAAK;AACD,uBAAa,QAAQ,aAAa,KAAK;AACvC,eAAK,IAAI,SAAS,6BAA6B;AAC/C;AAAA,QAEJ,KAAK;AACD,yBAAe,QAAQ,aAAa,KAAK;AACzC,eAAK,IAAI,SAAS,+BAA+B;AACjD;AAAA,QAEJ,KAAK;AACD,eAAK,cAAc,OAAO,aAAa;AACvC;AAAA,QAEJ;AAEI,uBAAa,QAAQ,aAAa,KAAK;AACvC,eAAK,IAAI,SAAS,uCAAuC;AAAA,MACjE;AAEA,WAAK,cAAc,aAAa;AAAA,QAC5B;AAAA,QACA,aAAa,MAAM;AAAA,QACnB,eAAe,MAAM,SAAS,GAAG;AAAA,MACrC,CAAC;AAED,aAAO;AAAA,IAEX,SAAS,OAAO;AACZ,WAAK,IAAI,wBAAwB,KAAK;AACtC,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,OAAO,UAAU,CAAC,GAAG;AAC/B,UAAM;AAAA,MACF,aAAa,KAAK,OAAO;AAAA,MACzB,SAAS,OAAO,SAAS,aAAa;AAAA,MACtC,WAAW;AAAA,MACX,OAAO;AAAA,MACP,SAAS;AAAA,IACb,IAAI;AAEJ,QAAI,eAAe,GAAG,UAAU,IAAI,mBAAmB,KAAK,CAAC,UAAU,IAAI;AAE3E,QAAI,QAAQ;AACR,sBAAgB;AAAA,IACpB;AAEA,QAAI,UAAU;AACV,sBAAgB,cAAc,QAAQ;AAAA,IAC1C;AAEA,QAAI,QAAQ;AACR,sBAAgB,YAAY,MAAM;AAAA,IACtC;AAGA,QAAI;AACA,UAAI,MAAM,SAAS,GAAG,GAAG;AACrB,YAAI;AACA,gBAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACpD,cAAI,QAAQ,KAAK;AACb,kBAAM,aAAa,IAAI,KAAK,QAAQ,MAAM,GAAI;AAC9C,4BAAgB,aAAa,WAAW,YAAY,CAAC;AAAA,UACzD;AAAA,QACJ,SAAS,OAAO;AACZ,eAAK,IAAI,6CAA6C;AAAA,QAC1D;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,2BAA2B,KAAK;AAAA,IAC7C;AAEA,aAAS,SAAS;AAClB,SAAK,IAAI,oBAAoB,UAAU,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,UAAU,OAAO;AAC/B,YAAQ,SAAS;AAAA,MACb,KAAK;AACD,qBAAa,WAAW,WAAW;AACnC,qBAAa,WAAW,aAAa;AACrC;AAAA,MAEJ,KAAK;AACD,uBAAe,WAAW,WAAW;AACrC,uBAAe,WAAW,aAAa;AACvC;AAAA,MAEJ,KAAK;AACD,aAAK,iBAAiB;AACtB;AAAA,MAEJ,KAAK;AAAA,MACL;AACI,qBAAa,WAAW,WAAW;AACnC,qBAAa,WAAW,aAAa;AACrC,uBAAe,WAAW,WAAW;AACrC,uBAAe,WAAW,aAAa;AACvC,aAAK,iBAAiB;AACtB;AAAA,IACR;AAEA,SAAK,cAAc,iBAAiB,EAAE,QAAQ,CAAC;AAC/C,SAAK,IAAI,uBAAuB,OAAO,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,cAAc,MAAM;AACnC,UAAM,gBAAgB,eAAe,KAAK,OAAO;AAEjD,SAAK,IAAI,4CAAqC,aAAa,EAAE;AAE7D,SAAK,cAAc,iBAAiB,EAAE,aAAa,cAAc,CAAC;AAGlE,QAAI,KAAK,UAAU,OAAO,KAAK,OAAO,eAAe,YAAY;AAC7D,WAAK,OAAO,WAAW,aAAa;AAAA,IACxC;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,SAAK,IAAI,4BAAqB;AAG9B,SAAK,kBAAkB;AAGvB,QAAI,OAAO,KAAM,QAAO,OAAO;AAC/B,QAAI,OAAO,gBAAiB,QAAO,kBAAkB;AAErD,SAAK,cAAc,UAAU,CAAC,CAAC;AAG/B,QAAI,KAAK,UAAU,OAAO,KAAK,OAAO,eAAe,YAAY;AAC7D,WAAK,OAAO,WAAW,KAAK,OAAO,UAAU;AAAA,IACjD;AAEA,WAAO,KAAK,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,WAAW,MAAM;AAC3B,UAAM,QAAQ,IAAI,YAAY,eAAe;AAAA,MACzC,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,WAAW,KAAK,IAAI;AAAA,QACpB,GAAG;AAAA,MACP;AAAA,IACJ,CAAC;AAED,aAAS,cAAc,KAAK;AAG5B,QAAI,KAAK,eAAe,IAAI,SAAS,GAAG;AACpC,WAAK,eAAe,IAAI,SAAS,EAAE,QAAQ,cAAY;AACnD,YAAI;AACA,mBAAS,IAAI;AAAA,QACjB,SAAS,OAAO;AACZ,eAAK,IAAI,yBAAyB,KAAK;AAAA,QAC3C;AAAA,MACJ,CAAC;AAAA,IACL;AAEA,SAAK,IAAI,iCAA0B,SAAS,IAAI,IAAI;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,GAAG,WAAW,UAAU;AACpB,QAAI,CAAC,KAAK,eAAe,IAAI,SAAS,GAAG;AACrC,WAAK,eAAe,IAAI,WAAW,CAAC,CAAC;AAAA,IACzC;AACA,SAAK,eAAe,IAAI,SAAS,EAAE,KAAK,QAAQ;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAW,UAAU;AACrB,QAAI,KAAK,eAAe,IAAI,SAAS,GAAG;AACpC,YAAM,YAAY,KAAK,eAAe,IAAI,SAAS;AACnD,YAAM,QAAQ,UAAU,QAAQ,QAAQ;AACxC,UAAI,QAAQ,IAAI;AACZ,kBAAU,OAAO,OAAO,CAAC;AAAA,MAC7B;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,WAAO;AAAA,MACH,SAAS,KAAK,OAAO;AAAA,MACrB,iBAAiB,KAAK,oBAAoB;AAAA,MAC1C,UAAU,CAAC,CAAC,KAAK,eAAe;AAAA,MAChC,sBAAsB,KAAK,OAAO,gBAAgB;AAAA,MAClD,wBAAwB,KAAK,OAAO,kBAAkB;AAAA,MACtD,mBAAmB,KAAK,OAAO,aAAa;AAAA,MAC5C,SAAS,KAAK,OAAO;AAAA,MACrB,YAAY,KAAK,OAAO;AAAA,IAC5B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,eAAe,MAAM;AAC1B,SAAK,IAAI,SAAS,uBAAuB;AAAA,EAC7C;AACJ;;;ACpfO,IAAM,eAAN,MAAmB;AAAA,EACtB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,WAAW,QAAQ,aAAa;AAAA;AAAA,MAChC,UAAU,QAAQ,YAAY;AAAA;AAAA,MAC9B,cAAc,QAAQ,gBAAgB;AAAA;AAAA,MACtC,OAAO,QAAQ,SAAS;AAAA,IAC5B;AAGA,SAAK,SAAS;AAGd,SAAK,QAAQ,oBAAI,IAAI;AACrB,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,SAAK,WAAW,CAAC;AAEjB,SAAK,IAAI,QAAQ,yCAAyC,KAAK,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,gBAAgB,GAAG,IAAI;AAAA,IAC/D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAK,OAAO;AACjB,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,KAAK,OAAO,cAAc,OAAO;AAEjC,UAAI,KAAK,MAAM,QAAQ,KAAK,OAAO,gBAAgB,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG;AACrE,cAAM,YAAY,KAAK,SAAS,MAAM;AACtC,YAAI,WAAW;AACX,eAAK,MAAM,OAAO,SAAS;AAC3B,eAAK,gBAAgB,OAAO,SAAS;AACrC,eAAK,IAAI,SAAS,0CAA8B,SAAS,EAAE;AAAA,QAC/D;AAAA,MACJ;AAGA,YAAM,gBAAgB,KAAK,SAAS,QAAQ,GAAG;AAC/C,UAAI,gBAAgB,IAAI;AACpB,aAAK,SAAS,OAAO,eAAe,CAAC;AAAA,MACzC;AAGA,WAAK,SAAS,KAAK,GAAG;AAAA,IAC1B;AAEA,SAAK,MAAM,IAAI,KAAK,KAAK;AACzB,SAAK,gBAAgB,IAAI,KAAK,GAAG;AAEjC,SAAK,IAAI,SAAS,qBAAc,GAAG,WAAW,KAAK,MAAM,IAAI,GAAG;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAK;AACd,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,YAAY,KAAK,gBAAgB,IAAI,GAAG;AAG9C,QAAI,aAAc,MAAM,YAAa,KAAK,OAAO,UAAU;AACvD,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,gBAAgB,OAAO,GAAG;AAE/B,UAAI,KAAK,OAAO,cAAc,OAAO;AACjC,cAAM,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACvC,YAAI,QAAQ,IAAI;AACZ,eAAK,SAAS,OAAO,OAAO,CAAC;AAAA,QACjC;AAAA,MACJ;AAEA,WAAK,IAAI,SAAS,qCAAgC,GAAG,EAAE;AACvD,aAAO;AAAA,IACX;AAEA,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAEhC,QAAI,SAAS,KAAK,OAAO,cAAc,OAAO;AAE1C,YAAM,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACvC,UAAI,QAAQ,IAAI;AACZ,aAAK,SAAS,OAAO,OAAO,CAAC;AAC7B,aAAK,SAAS,KAAK,GAAG;AAAA,MAC1B;AAAA,IACJ;AAEA,QAAI,OAAO;AACP,WAAK,IAAI,SAAS,wBAAiB,GAAG,EAAE;AAAA,IAC5C,OAAO;AACH,WAAK,IAAI,SAAS,sBAAiB,GAAG,EAAE;AAAA,IAC5C;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAK;AACV,WAAO,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,aAAa,GAAG,MAAM;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB,SAAS;AACzB,UAAM,eAAe,CAAC;AAEtB,eAAW,OAAO,KAAK,MAAM,KAAK,GAAG;AACjC,UAAI,IAAI,SAAS,OAAO,KAAK,IAAI,WAAW,OAAO,GAAG;AAClD,qBAAa,KAAK,GAAG;AAAA,MACzB;AAAA,IACJ;AAEA,iBAAa,QAAQ,SAAO;AACxB,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,gBAAgB,OAAO,GAAG;AAE/B,UAAI,KAAK,OAAO,cAAc,OAAO;AACjC,cAAM,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACvC,YAAI,QAAQ,IAAI;AACZ,eAAK,SAAS,OAAO,OAAO,CAAC;AAAA,QACjC;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,SAAK,IAAI,SAAS,yBAAkB,aAAa,MAAM,4BAA4B,OAAO,EAAE;AAC5F,WAAO,aAAa;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,WAAW;AAChC,UAAM,WAAW;AAAA,MACb,aAAa,SAAS;AAAA,MACtB,UAAU,SAAS;AAAA,MACnB,YAAY,SAAS;AAAA,MACrB,SAAS,SAAS;AAAA,MAClB,UAAU,SAAS;AAAA,IACvB;AAEA,QAAI,mBAAmB;AACvB,aAAS,QAAQ,aAAW;AACxB,0BAAoB,KAAK,oBAAoB,OAAO;AAAA,IACxD,CAAC;AAED,SAAK,IAAI,oDAA6C,SAAS,KAAK,gBAAgB,WAAW;AAC/F,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB;AAClB,UAAM,oBAAoB,CAAC,cAAc,WAAW,aAAa,UAAU,SAAS;AACpF,QAAI,eAAe;AAEnB,sBAAkB,QAAQ,aAAW;AACjC,sBAAgB,KAAK,oBAAoB,OAAO;AAAA,IACpD,CAAC;AAED,SAAK,IAAI,2CAAoC,YAAY,WAAW;AACpE,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AACT,UAAM,OAAO,KAAK,MAAM;AACxB,SAAK,MAAM,MAAM;AACjB,SAAK,gBAAgB,MAAM;AAC3B,SAAK,WAAW,CAAC;AAEjB,SAAK,IAAI,gCAAyB,IAAI,WAAW;AACjD,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB;AAChB,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,cAAc,CAAC;AAErB,eAAW,CAAC,KAAK,SAAS,KAAK,KAAK,gBAAgB,QAAQ,GAAG;AAC3D,UAAK,MAAM,YAAa,KAAK,OAAO,UAAU;AAC1C,oBAAY,KAAK,GAAG;AAAA,MACxB;AAAA,IACJ;AAEA,gBAAY,QAAQ,SAAO;AACvB,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,gBAAgB,OAAO,GAAG;AAE/B,UAAI,KAAK,OAAO,cAAc,OAAO;AACjC,cAAM,QAAQ,KAAK,SAAS,QAAQ,GAAG;AACvC,YAAI,QAAQ,IAAI;AACZ,eAAK,SAAS,OAAO,OAAO,CAAC;AAAA,QACjC;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,QAAI,YAAY,SAAS,GAAG;AACxB,WAAK,IAAI,wBAAc,YAAY,MAAM,wBAAwB;AAAA,IACrE;AAEA,WAAO,YAAY;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB;AACZ,WAAO;AAAA,MACH,MAAM,KAAK,MAAM;AAAA,MACjB,SAAS,KAAK,OAAO;AAAA,MACrB,MAAM,KAAK,OAAO;AAAA,MAClB,KAAK,KAAK,OAAO;AAAA,MACjB,aAAa,KAAK,eAAe;AAAA,MACjC,UAAU,KAAK,YAAY;AAAA,MAC3B,YAAY,KAAK,oBAAoB;AAAA,IACzC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB;AACb,QAAI,iBAAiB;AAErB,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG;AAE7C,wBAAkB,IAAI,SAAS;AAG/B,UAAI,OAAO,UAAU,UAAU;AAC3B,0BAAkB,MAAM,SAAS;AAAA,MACrC,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACpD,0BAAkB,KAAK,UAAU,KAAK,EAAE,SAAS;AAAA,MACrD,OAAO;AACH,0BAAkB;AAAA,MACtB;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,OAAO;AAAA,MACP,IAAI,KAAK,MAAM,iBAAiB,OAAO,GAAG,IAAI;AAAA,MAC9C,IAAI,KAAK,MAAM,kBAAkB,OAAO,QAAQ,GAAG,IAAI;AAAA,IAC3D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AAGV,UAAM,QAAQ,KAAK,MAAM,OAAO,IAAI,KAAK,IAAI,KAAK,MAAM,OAAO,KAAK,OAAO,cAAc,CAAC,IAAI;AAC9F,WAAO,KAAK,MAAM,QAAQ,GAAG;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB;AAClB,UAAM,aAAa;AAAA,MACf,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,IACZ;AAEA,eAAW,OAAO,KAAK,MAAM,KAAK,GAAG;AACjC,UAAI,IAAI,WAAW,YAAY,EAAG,YAAW;AAAA,eACpC,IAAI,WAAW,SAAS,EAAG,YAAW;AAAA,eACtC,IAAI,WAAW,WAAW,EAAG,YAAW;AAAA,eACxC,IAAI,WAAW,QAAQ,EAAG,YAAW;AAAA,eACrC,IAAI,WAAW,SAAS,EAAG,YAAW;AAAA,UAC1C,YAAW;AAAA,IACpB;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,WAAO,MAAM,KAAK,KAAK,MAAM,KAAK,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,SAAS;AAC3B,WAAO,KAAK,aAAa,EAAE;AAAA,MAAO,SAC9B,IAAI,SAAS,OAAO,KAAK,IAAI,WAAW,OAAO;AAAA,IACnD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,WAAW,KAAO;AAC/B,QAAI,KAAK,iBAAiB;AACtB,oBAAc,KAAK,eAAe;AAAA,IACtC;AAEA,SAAK,kBAAkB,YAAY,MAAM;AACrC,WAAK,kBAAkB;AAAA,IAC3B,GAAG,QAAQ;AAEX,SAAK,IAAI,6CAAsC,QAAQ,KAAK;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB;AACd,QAAI,KAAK,iBAAiB;AACtB,oBAAc,KAAK,eAAe;AAClC,WAAK,kBAAkB;AACvB,WAAK,IAAI,SAAS,gCAAyB;AAAA,IAC/C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,gBAAgB;AACrB,SAAK,WAAW;AAChB,SAAK,IAAI,SAAS,wBAAwB;AAAA,EAC9C;AACJ;;;AC5VO,IAAM,eAAN,MAAmB;AAAA,EACtB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,2BAA2B,QAAQ,8BAA8B;AAAA,MACjE,qBAAqB,QAAQ,wBAAwB;AAAA,MACrD,oBAAoB,QAAQ,sBAAsB;AAAA,MAClD,cAAc,QAAQ,gBAAgB;AAAA,MACtC,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,mBAAmB,QAAQ,qBAAqB;AAAA,MAChD,OAAO,QAAQ,SAAS;AAAA,IAC5B;AAGA,SAAK,SAAS;AAGd,SAAK,qBAAqB,CAAC;AAG3B,SAAK,qBAAqB,CAAC;AAE3B,SAAK,IAAI,QAAQ,yCAAyC,KAAK,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,gBAAgB,GAAG,IAAI;AAAA,IAC/D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,OAAO;AACrB,QAAI,OAAO,UAAU,SAAU,QAAO;AAGtC,QAAI,YAAY,MACX,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,uDAAuD,EAAE,EACjE,QAAQ,oDAAoD,EAAE,EAC9D,QAAQ,mBAAmB,EAAE,EAC7B,QAAQ,mBAAmB,EAAE,EAC7B,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,eAAe,EAAE,EACzB,QAAQ,WAAW,EAAE,EACrB,QAAQ,eAAe,EAAE,EACzB,QAAQ,qBAAqB,EAAE,EAC/B,QAAQ,cAAc,EAAE;AAG7B,UAAM,cAAc;AAAA,MAChB;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IACJ;AAEA,eAAW,WAAW,aAAa;AAC/B,kBAAY,UAAU,QAAQ,SAAS,EAAE;AAAA,IAC7C;AAGA,gBAAY,UAAU,QAAQ,gBAAgB,EAAE;AAGhD,QAAI,UAAU,SAAS,KAAK,OAAO,oBAAoB;AACnD,kBAAY,UAAU,UAAU,GAAG,KAAK,OAAO,kBAAkB;AAAA,IACrE;AAEA,WAAO,UAAU,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,KAAK,OAAO;AAE1B,QAAI,CAAC,KAAK,OAAO,2BAA2B;AACxC,aAAO;AAAA,IACX;AAGA,QAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,GAAG;AAC7C,aAAO;AAAA,IACX;AAGA,QAAI,CAAC,KAAK,OAAO,kBAAkB,KAAK,GAAG,GAAG;AAC1C,UAAI,KAAK,OAAO,qBAAqB;AACjC,gBAAQ,KAAK,iCAAiC,GAAG,EAAE;AAAA,MACvD;AACA,aAAO;AAAA,IACX;AAGA,QAAI,IAAI,SAAS,IAAI;AACjB,UAAI,KAAK,OAAO,qBAAqB;AACjC,gBAAQ,KAAK,2BAA2B,GAAG,EAAE;AAAA,MACjD;AACA,aAAO;AAAA,IACX;AAGA,QAAI,UAAU,QAAQ,UAAU,QAAW;AACvC,UAAI,OAAO,UAAU,UAAU;AAE3B,YAAI,MAAM,SAAS,KAAK,OAAO,oBAAoB;AAC/C,cAAI,KAAK,OAAO,qBAAqB;AACjC,oBAAQ,KAAK,qCAAqC,GAAG,EAAE;AAAA,UAC3D;AACA,iBAAO;AAAA,QACX;AAGA,cAAM,oBAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,QACJ;AAEA,mBAAW,WAAW,mBAAmB;AACrC,cAAI,QAAQ,KAAK,KAAK,GAAG;AACrB,gBAAI,KAAK,OAAO,qBAAqB;AACjC,sBAAQ,KAAK,2CAA2C,GAAG,KAAK,KAAK;AAAA,YACzE;AACA,mBAAO;AAAA,UACX;AAAA,QACJ;AAAA,MACJ,WAAW,MAAM,QAAQ,KAAK,GAAG;AAE7B,YAAI,MAAM,SAAS,KAAK,OAAO,cAAc;AACzC,cAAI,KAAK,OAAO,qBAAqB;AACjC,oBAAQ,KAAK,sCAAsC,GAAG,EAAE;AAAA,UAC5D;AACA,iBAAO;AAAA,QACX;AAGA,mBAAW,QAAQ,OAAO;AACtB,cAAI,CAAC,KAAK,kBAAkB,GAAG,GAAG,MAAM,IAAI,GAAG;AAC3C,mBAAO;AAAA,UACX;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,aAAa;AAC1B,UAAM,SAAS,CAAC;AAChB,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,QAAQ,YAAY,MAAM,GAAG;AACnC,eAAW,QAAQ,OAAO;AACtB,UAAI;AACA,cAAM,CAAC,QAAQ,QAAQ,IAAI,KAAK,MAAM,GAAG;AACzC,YAAI,CAAC,OAAQ;AAEb,YAAI,KAAK;AACT,YAAI;AACA,gBAAM,mBAAmB,MAAM;AAC/B,kBAAQ,WAAW,mBAAmB,QAAQ,IAAI;AAAA,QACtD,SAAS,GAAG;AACR,eAAK,IAAI,QAAQ,mCAAmC,IAAI;AACxD;AAAA,QACJ;AAGA,YAAI,CAAC,KAAK,kBAAkB,KAAK,KAAK,GAAG;AACrC,eAAK,IAAI,QAAQ,0CAA0C,GAAG,EAAE;AAChE;AAAA,QACJ;AAGA,cAAM,iBAAiB,KAAK,kBAAkB,KAAK;AAGnD,YAAI,IAAI,SAAS,IAAI,GAAG;AACpB,gBAAM,WAAW,IAAI,MAAM,GAAG,EAAE;AAGhC,cAAI,CAAC,KAAK,kBAAkB,UAAU,CAAC,CAAC,GAAG;AACvC;AAAA,UACJ;AAEA,cAAI,CAAC,OAAO,QAAQ,EAAG,QAAO,QAAQ,IAAI,CAAC;AAG3C,cAAI,OAAO,QAAQ,EAAE,SAAS,KAAK,OAAO,cAAc;AACpD,mBAAO,QAAQ,EAAE,KAAK,cAAc;AAAA,UACxC,OAAO;AACH,gBAAI,KAAK,OAAO,qBAAqB;AACjC,sBAAQ,KAAK,mBAAmB,QAAQ,sBAAsB;AAAA,YAClE;AAAA,UACJ;AAAA,QACJ,OAAO;AACH,iBAAO,GAAG,IAAI;AAAA,QAClB;AAAA,MACJ,SAAS,OAAO;AACZ,aAAK,IAAI,SAAS,kCAAkC,MAAM,KAAK;AAAA,MACnE;AAAA,IACJ;AAGA,UAAM,aAAa,OAAO,KAAK,MAAM,EAAE;AACvC,QAAI,aAAa,KAAK,OAAO,mBAAmB;AAC5C,UAAI,KAAK,OAAO,qBAAqB;AACjC,gBAAQ,KAAK,wBAAwB,UAAU,wBAAwB,KAAK,OAAO,iBAAiB,GAAG;AAAA,MAC3G;AACA,YAAM,gBAAgB,CAAC;AACvB,UAAI,QAAQ;AACZ,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,YAAI,SAAS,KAAK,OAAO,kBAAmB;AAC5C,sBAAc,GAAG,IAAI;AACrB;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAAQ;AACrB,QAAI,CAAC,UAAU,OAAO,KAAK,MAAM,EAAE,WAAW,EAAG,QAAO;AAExD,UAAM,QAAQ,CAAC;AACf,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,UAAI,MAAM,QAAQ,KAAK,GAAG;AAEtB,mBAAW,QAAQ,OAAO;AACtB,gBAAM,KAAK,GAAG,mBAAmB,GAAG,CAAC,MAAM,mBAAmB,IAAI,CAAC,EAAE;AAAA,QACzE;AAAA,MACJ,WAAW,UAAU,UAAa,UAAU,MAAM;AAC9C,cAAM,KAAK,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,KAAK,CAAC,EAAE;AAAA,MACxE;AAAA,IACJ;AACA,WAAO,MAAM,KAAK,GAAG;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,WAAW;AAC7B,QAAI,CAAC,KAAK,sBAAsB,CAAC,UAAW,QAAO;AACnD,QAAI,CAAC,KAAK,sBAAsB,CAAC,UAAW,QAAO;AAEnD,UAAM,UAAU,OAAO,KAAK,KAAK,kBAAkB;AACnD,UAAM,UAAU,OAAO,KAAK,SAAS;AAErC,QAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAE9C,eAAW,OAAO,SAAS;AACvB,UAAI,KAAK,UAAU,KAAK,mBAAmB,GAAG,CAAC,MAAM,KAAK,UAAU,UAAU,GAAG,CAAC,GAAG;AACjF,eAAO;AAAA,MACX;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB;AACb,WAAO,EAAE,GAAG,KAAK,mBAAmB;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAK,eAAe,QAAW;AACzC,UAAM,QAAQ,KAAK,qBAAqB,KAAK,mBAAmB,GAAG,IAAI;AACvE,WAAO,UAAU,SAAY,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,QAAQ,UAAU,OAAO;AACpC,QAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACvC,cAAQ,KAAK,sDAAsD;AACnE;AAAA,IACJ;AAEA,UAAM,gBAAgB,UAAU,CAAC,IAAI,EAAE,GAAG,KAAK,mBAAmB;AAClE,UAAM,kBAAkB,CAAC;AAGzB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AAE/C,UAAI,CAAC,KAAK,kBAAkB,KAAK,KAAK,GAAG;AACrC,gBAAQ,KAAK,aAAa,GAAG,8BAA8B;AAC3D;AAAA,MACJ;AAGA,UAAI,UAAU,UAAa,UAAU,MAAM;AACvC,YAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,0BAAgB,GAAG,IAAI,MAAM,IAAI,UAAQ,KAAK,kBAAkB,IAAI,CAAC;AAAA,QACzE,OAAO;AACH,0BAAgB,GAAG,IAAI,KAAK,kBAAkB,KAAK;AAAA,QACvD;AAAA,MACJ;AAAA,IACJ;AAGA,WAAO,OAAO,eAAe,eAAe;AAG5C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACtD,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACvD,eAAO,cAAc,GAAG;AAAA,MAC5B;AAAA,IACJ;AAGA,UAAM,aAAa,OAAO,KAAK,aAAa,EAAE;AAC9C,QAAI,aAAa,KAAK,OAAO,mBAAmB;AAC5C,UAAI,KAAK,OAAO,qBAAqB;AACjC,gBAAQ,KAAK,qCAAqC,UAAU,oCAAoC;AAAA,MACpG;AAAA,IACJ;AAEA,SAAK,qBAAqB;AAC1B,SAAK,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,MAAM;AACpB,QAAI,CAAC,KAAM;AAEX,UAAM,eAAe,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AACvD,eAAW,OAAO,cAAc;AAC5B,aAAO,KAAK,mBAAmB,GAAG;AAAA,IACtC;AAEA,SAAK,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB;AACf,SAAK,qBAAqB,CAAC;AAC3B,SAAK,UAAU;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,QAAQ;AAC1B,SAAK,qBAAqB,UAAU,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,QAAQ;AAC1B,SAAK,qBAAqB,UAAU,CAAC;AACrC,SAAK,IAAI,SAAS,qBAAqB,KAAK,kBAAkB;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe;AACX,WAAO;AAAA,MACH,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACZ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,KAAK,eAAe,QAAW;AAEpC,UAAM,QAAQ,KAAK,mBAAmB,GAAG,MAAM,SAClC,KAAK,mBAAmB,GAAG,IAC3B,KAAK,mBAAmB,GAAG;AACxC,WAAO,UAAU,SAAY,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB;AACb,WAAO,EAAE,GAAG,KAAK,mBAAmB;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,KAAK,eAAe,QAAW;AACzC,UAAM,QAAQ,KAAK,mBAAmB,GAAG;AACzC,WAAO,UAAU,SAAY,QAAQ;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACR,QAAI,KAAK,UAAU,OAAO,KAAK,OAAO,cAAc,YAAY;AAC5D,YAAM,QAAQ,KAAK,OAAO,eAAe;AACzC,WAAK,OAAO,UAAU,OAAO,KAAK,kBAAkB;AAAA,IACxD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACP,WAAO;AAAA,MACH,eAAe,OAAO,KAAK,KAAK,kBAAkB,EAAE;AAAA,MACpD,YAAY,KAAK,OAAO;AAAA,MACxB,mBAAmB,KAAK,OAAO;AAAA,MAC/B,oBAAoB,KAAK,iBAAiB,KAAK,kBAAkB;AAAA,IACrE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,qBAAqB,CAAC;AAC3B,SAAK,qBAAqB,CAAC;AAC3B,SAAK,SAAS;AACd,SAAK,IAAI,SAAS,wBAAwB;AAAA,EAC9C;AACJ;;;AC9bO,IAAM,cAAN,MAAkB;AAAA,EACrB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,SAAS,QAAQ,WAAW,OAAO,OAAO,WAAW;AAAA;AAAA,MACrD,YAAY,QAAQ,cAAc,OAAO,OAAO,cAAc;AAAA;AAAA,MAC9D,aAAa,QAAQ,eAAe;AAAA,MACpC,WAAW,QAAQ,cAAc;AAAA,MACjC,eAAe,QAAQ,iBAAiB;AAAA,MACxC,eAAe,QAAQ,kBAAkB;AAAA,MACzC,OAAO,QAAQ,SAAS;AAAA,IAC5B;AAGA,SAAK,SAAS;AACd,SAAK,IAAI,SAAS,wCAAwC,KAAK,MAAM;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,WAAW;AACxB,QAAI;AACJ,QAAI;AACA,UAAI,KAAK,OAAO,gBAAgB,cAAc;AAE1C,cAAM,aAAa,GAAG,KAAK,OAAO,UAAU,IAAI,SAAS;AACzD,aAAK,IAAI,SAAS,6BAA6B,UAAU,EAAE;AAC3D,cAAM,SAAS,MAAM,OAAO;AAC5B,iBAAS,OAAO;AAAA,MACpB,OAAO;AAEH,cAAM,aAAa,GAAG,KAAK,OAAO,OAAO,UAAU,SAAS;AAC5D,aAAK,IAAI,SAAS,8BAA8B,UAAU,EAAE;AAC5D,cAAM,SAAS,MAAM,OAAO;AAC5B,iBAAS,OAAO;AAAA,MACpB;AAEA,UAAI,CAAC,QAAQ;AACT,cAAM,IAAI,MAAM,UAAU,SAAS,iCAAiC;AAAA,MACxE;AAAA,IAEJ,SAAS,OAAO;AAEZ,UAAI,MAAM,QAAQ,SAAS,mBAAmB,KAC1C,MAAM,QAAQ,SAAS,iBAAiB,KACxC,MAAM,QAAQ,SAAS,WAAW,KAClC,MAAM,SAAS,aAAa;AAC5B,cAAM,IAAI,MAAM,UAAU,SAAS,mBAAmB;AAAA,MAC1D;AAEA,YAAM;AAAA,IACV;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,WAAW;AAC1B,QAAI;AACA,YAAM,eAAe,GAAG,KAAK,OAAO,OAAO,UAAU,SAAS;AAC9D,YAAM,WAAW,MAAM,MAAM,YAAY;AACzC,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,EAAE;AAC1E,YAAM,WAAW,MAAM,SAAS,KAAK;AACrC,WAAK,IAAI,SAAS,aAAa,SAAS,uBAAuB;AAC/D,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,aAAa,SAAS,+BAA+B,MAAM,OAAO;AAEnF,aAAO,KAAK,wBAAwB,SAAS;AAAA,IACjD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,WAAW;AACvB,QAAI;AACA,YAAM,YAAY,GAAG,KAAK,OAAO,OAAO,WAAW,SAAS;AAC5D,YAAM,WAAW,MAAM,MAAM,SAAS;AACtC,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,EAAE;AACvE,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,WAAK,IAAI,SAAS,UAAU,SAAS,uBAAuB;AAC5D,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,UAAU,SAAS,mCAAmC,MAAM,OAAO;AAErF,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,YAAY;AACzB,QAAI;AACA,YAAM,aAAa,GAAG,KAAK,OAAO,OAAO,YAAY,UAAU;AAC/D,YAAM,WAAW,MAAM,MAAM,UAAU;AACvC,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,qBAAqB,SAAS,MAAM,EAAE;AACxE,YAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,WAAK,IAAI,SAAS,WAAW,UAAU,uBAAuB;AAC9D,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,WAAW,UAAU,mCAAmC,MAAM,OAAO;AACvF,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB,WAAW,QAAQ,UAAU;AACjD,QAAI;AAEJ,QAAI,OAAO,SAAS,eAAe,GAAG;AAClC,eAAS,OAAO;AAAA,QACZ;AAAA,QACA;AAAA,MACJ;AAAA,IACJ,WAES,OAAO,SAAS,sBAAsB,GAAG;AAC9C,WAAK,IAAI,SAAS,gCAAgC;AAClD,eAAS,OAAO;AAAA,QACZ;AAAA,QACA,KAAK,QAAQ;AAAA,MACjB;AAAA,IACJ,OAEK;AACD,WAAK,IAAI,SAAS,+BAA+B;AACjD,eAAS,GAAG,MAAM;AAAA,EAAK,QAAQ;AAAA,IACnC;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBAAmB,WAAW;AAEhC,UAAM,WAAW,aAAa,SAAS;AACvC,UAAM,SAAS,KAAK,OAAO,cAAc,aAAa,QAAQ;AAC9D,QAAI,QAAQ;AACR,aAAO;AAAA,IACX;AAEA,UAAM,SAAS,MAAM,KAAK,WAAW,SAAS;AAC9C,UAAM,SAAS,KAAK;AACpB,UAAM,eAAe,KAAK,OAAO,gBAAgB;AAGjD,QAAI,UAAU,QAAQ,IAAI,SAAS;AAEnC,QAAI,cAAc;AAEd,iBAAW,OAAO,YAAY,KAAK,wBAAwB,SAAS;AAAA,IACxE,OAAO;AAEH,iBAAW,MAAM,KAAK,aAAa,SAAS;AAC5C,cAAQ,MAAM,KAAK,UAAU,SAAS;AACtC,eAAS,KAAK,OAAO,aAAa,OAAO,WAAW,OAChD,MAAM,KAAK,WAAW,OAAO,UAAU,KAAK,OAAO,aAAa,IAAI;AAGxE,UAAI,QAAQ;AACR,mBAAW,KAAK,wBAAwB,WAAW,QAAQ,QAAQ;AAAA,MACvE;AAAA,IACJ;AAGA,QAAI,mBAAmB,CAAC;AACxB,QAAI,KAAK,OAAO,iBAAiB,OAAO,iBAAiB;AACrD,UAAI;AACA,2BAAmB,MAAM,OAAO,gBAAgB,kBAAkB;AAClE,aAAK,IAAI,SAAS,6CAA6C,SAAS,EAAE;AAAA,MAC9E,SAAS,OAAO;AACZ,aAAK,IAAI,QAAQ,uCAAuC,SAAS,qCAAqC,MAAM,OAAO;AACnH,2BAAmB,CAAC;AAAA,MACxB;AAAA,IACJ;AAGA,UAAM,YAAY;AAAA,MACd,GAAG;AAAA,MACH,MAAM,OAAO,QAAQ,KAAK,aAAa,SAAS;AAAA,MAChD;AAAA,MACA,YAAY;AAAA,MACZ,OAAO;AACH,cAAM,eAAe,OAAO,OAAO,OAAO,KAAK,IAAI,CAAC;AACpD,cAAM,aAAa;AAAA,UACf,GAAG;AAAA,UACH,cAAc;AAAA,UACd,QAAQ,OAAO,cAAc,eAAe,KAAK,CAAC;AAAA,UAClD,QAAQ,MAAM;AACV,gBAAI;AACA,qBAAO,OAAO,aAAa,mBAAmB,KAAK,OAAO,OAAO,uBAAuB,OAAO,OAAO,mBAAmB;AAAA,YAC7H,SAAS,OAAO;AACZ,kBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,mCAAmC,KAAK;AACzG,qBAAO,OAAO,OAAO,mBAAmB;AAAA,YAC5C;AAAA,UACJ,GAAG;AAAA,UACH,cAAc;AAAA,QAClB;AAEA,eAAO;AAAA,MACX;AAAA,MACA,UAAU;AAAA,QACN,GAAI,OAAO,YAAY,CAAC;AAAA;AAAA,QAExB,SAAS;AACL,iBAAO,OAAO,cAAc,aAAa,KAAK,CAAC;AAAA,QACnD;AAAA,MACJ;AAAA,MACA,MAAM,UAAU;AACZ,YAAI,OAAO,SAAS;AAChB,gBAAM,OAAO,QAAQ,KAAK,IAAI;AAAA,QAClC;AACA,YAAI,OAAO,SAAS;AAChB,cAAI,OAAO,OAAO,YAAY,UAAU;AAEpC,kBAAM,KAAK,WAAW;AAAA,UAC1B,WAAW,OAAO,OAAO,YAAY,UAAU;AAE3C,kBAAM,KAAK,mBAAmB;AAAA,UAClC;AAAA,QACJ;AAGA,cAAM,KAAK,UAAU;AACrB,aAAK,eAAe;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,QACL,GAAG,OAAO;AAAA;AAAA,QAEV,YAAY,CAAC,OAAO,WAAW,OAAO,WAAW,OAAO,MAAM;AAAA,QAC9D,iBAAiB,MAAM,OAAO,gBAAgB;AAAA;AAAA,QAG9C,WAAW,MAAM,OAAO,cAAc,aAAa,KAAK,CAAC;AAAA,QACzD,UAAU,CAAC,KAAK,iBAAiB,OAAO,cAAc,SAAS,KAAK,YAAY;AAAA;AAAA,QAGhF,IAAI,CAAC,KAAK,WAAW;AACjB,cAAI;AACA,mBAAO,OAAO,aAAa,EAAE,KAAK,MAAM,KAAK;AAAA,UACjD,SAAS,OAAO;AACZ,gBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,2CAA2C,KAAK;AACjH,mBAAO;AAAA,UACX;AAAA,QACJ;AAAA;AAAA,QAGA,kBAAkB,MAAM,OAAO,aAAa,oBAAoB,KAAK;AAAA,QACrE,SAAS,MAAM,OAAO,cAAc,OAAO,WAAW,OAAO,YAAY,aAAa,CAAC,IAAI;AAAA,QAC3F,eAAe,CAAC,WAAW,OAAO,cAAc,OAAO,WAAW,OAAO,YAAY,mBAAmB,MAAM,CAAC,IAAI;AAAA,QACnH,YAAY,CAAC,UAAU,OAAO,cAAc,OAAO,YAAY,oBAAoB,KAAK,IAAI,QAAQ,QAAQ,EAAE,SAAS,MAAM,QAAQ,gBAAgB,CAAC;AAAA,QACtJ,WAAW,MAAM,OAAO,aAAa,eAAe,KAAK;AAAA,QACzD,WAAW,CAAC,OAAO,YAAY,OAAO,aAAa,eAAe,OAAO,OAAO,KAAK;AAAA,QACrF,cAAc,CAAC,YAAY,OAAO,aAAa,kBAAkB,OAAO,KAAK;AAAA,QAC7E,gBAAgB,MAAM,OAAO,aAAa,cAAc,KAAK;AAAA,QAC7D,YAAY,CAAC,SAAS,OAAO,aAAa,eAAe,IAAI,KAAK;AAAA;AAAA,QAGlE,MAAM,WAAW,SAAS;AACtB,cAAI,CAAC,OAAO,QAAS;AAErB,eAAK,eAAe;AACpB,cAAI;AACA,gBAAI,OAAO,OAAO,YAAY,UAAU;AAEpC,oBAAM,OAAO,MAAM,OAAO,YAAY,mBAAmB,OAAO,OAAO;AACvE,kBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,oBAAoB,SAAS,KAAK,IAAI;AACxG,qBAAO,OAAO,MAAM,IAAI;AACxB,mBAAK,MAAM,eAAe,IAAI;AAAA,YAClC,WAAW,OAAO,OAAO,YAAY,YAAY,SAAS;AAEtD,oBAAM,MAAM,OAAO,QAAQ,OAAO;AAClC,kBAAI,KAAK;AACL,sBAAM,OAAO,MAAM,OAAO,YAAY,mBAAmB,GAAG;AAC5D,oBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,oBAAoB,SAAS,IAAI,OAAO,KAAK,IAAI;AACnH,qBAAK,OAAO,IAAI;AAChB,qBAAK,MAAM,eAAe,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC;AAAA,cACjD;AAAA,YACJ,OAAO;AAEH,oBAAM,KAAK,mBAAmB;AAAA,YAClC;AAAA,UACJ,SAAS,OAAO;AACZ,gBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,4BAA4B,SAAS,KAAK,KAAK;AAChH,iBAAK,MAAM,cAAc,KAAK;AAAA,UAClC,UAAE;AACE,iBAAK,eAAe;AAAA,UACxB;AAAA,QACJ;AAAA;AAAA,QAGA,MAAM,qBAAqB;AACvB,cAAI,CAAC,OAAO,WAAW,OAAO,OAAO,YAAY,SAAU;AAE3D,gBAAM,WAAW,OAAO;AACxB,eAAK,eAAe;AAEpB,cAAI;AAEA,kBAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE,IAAI,OAAO,CAAC,KAAK,GAAG,MAAM;AAChE,kBAAI;AACA,sBAAM,OAAO,MAAM,OAAO,YAAY,mBAAmB,GAAG;AAC5D,uBAAO,EAAE,KAAK,MAAM,SAAS,KAAK;AAAA,cACtC,SAAS,OAAO;AACZ,oBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,mBAAmB,GAAG,QAAQ,SAAS,KAAK,KAAK;AAClH,uBAAO,EAAE,KAAK,OAAO,SAAS,MAAM;AAAA,cACxC;AAAA,YACJ,CAAC;AAED,kBAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ;AAC1C,kBAAM,oBAAoB,CAAC;AAC3B,kBAAM,SAAS,CAAC;AAGhB,oBAAQ,QAAQ,CAAC,EAAE,KAAK,MAAM,OAAO,QAAQ,MAAM;AAC/C,kBAAI,SAAS;AACT,qBAAK,GAAG,IAAI;AACZ,kCAAkB,GAAG,IAAI;AAAA,cAC7B,OAAO;AACH,uBAAO,GAAG,IAAI;AAAA,cAClB;AAAA,YACJ,CAAC;AAED,gBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,6BAA6B,SAAS,KAAK,iBAAiB;AAG9H,gBAAI,OAAO,KAAK,iBAAiB,EAAE,SAAS,GAAG;AAC3C,mBAAK,MAAM,eAAe,iBAAiB;AAAA,YAC/C;AACA,gBAAI,OAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAChC,mBAAK,MAAM,cAAc,MAAM;AAAA,YACnC;AAAA,UAEJ,SAAS,OAAO;AACZ,gBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,qCAAqC,SAAS,KAAK,KAAK;AACzH,iBAAK,MAAM,cAAc,KAAK;AAAA,UAClC,UAAE;AACE,iBAAK,eAAe;AAAA,UACxB;AAAA,QACJ;AAAA;AAAA,QAGA,MAAM,gBAAgB;AAClB,cAAI,OAAO,OAAO,YAAY,UAAU;AACpC,kBAAM,KAAK,WAAW;AAAA,UAC1B,WAAW,OAAO,OAAO,YAAY,UAAU;AAC3C,kBAAM,KAAK,mBAAmB;AAAA,UAClC;AAAA,QACJ;AAAA;AAAA,QAGA,iBAAiB;AACb,gBAAM,QAAQ,SAAS,iBAAiB,8BAA8B;AAEtE,gBAAM,QAAQ,UAAQ;AAElB,iBAAK,oBAAoB,UAAU,KAAK,mBAAmB;AAG3D,kBAAM,eAAe,CAAC,MAAM,KAAK,kBAAkB,CAAC;AACpD,iBAAK,sBAAsB;AAC3B,iBAAK,iBAAiB,UAAU,YAAY;AAE5C,gBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,oBAAoB,KAAK,aAAa,QAAQ,CAAC,EAAE;AAAA,UACvH,CAAC;AAAA,QACL;AAAA;AAAA,QAGA,MAAM,kBAAkB,OAAO;AAC3B,gBAAM,eAAe;AAErB,gBAAM,OAAO,MAAM;AACnB,cAAI,SAAS,KAAK,aAAa,QAAQ;AACvC,gBAAM,SAAS,KAAK,aAAa,QAAQ,KAAK;AAG9C,gBAAM,iBAAiB,KAAK,aAAa,sBAAsB;AAC/D,gBAAM,eAAe,KAAK,aAAa,oBAAoB;AAC3D,gBAAM,iBAAiB,KAAK,aAAa,sBAAsB;AAC/D,gBAAM,aAAa,KAAK,aAAa,eAAe;AAEpD,cAAI;AAEA,gBAAI,kBAAkB,KAAK,cAAc,GAAG;AACxC,mBAAK,cAAc,EAAE,MAAM,IAAI;AAAA,YACnC;AAGA,qBAAS,KAAK,qBAAqB,MAAM;AAGzC,gBAAI,CAAC,KAAK,cAAc,IAAI,GAAG;AAC3B;AAAA,YACJ;AAGA,kBAAM,WAAW,IAAI,SAAS,IAAI;AAClC,kBAAM,OAAO,OAAO,YAAY,SAAS,QAAQ,CAAC;AAElD,gBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,uBAAuB,MAAM,IAAI,IAAI;AAGvG,kBAAM,WAAW,MAAM,KAAK,gBAAgB,QAAQ,QAAQ,MAAM,IAAI;AAGtE,gBAAI,kBAAkB,KAAK,cAAc,GAAG;AACxC,mBAAK,cAAc,EAAE,UAAU,IAAI;AAAA,YACvC;AAGA,gBAAI,YAAY;AACZ,yBAAW,MAAM;AACb,qBAAK,WAAW,UAAU;AAAA,cAC9B,GAAG,GAAI;AAAA,YACX;AAAA,UAEJ,SAAS,OAAO;AACZ,gBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,0BAA0B,KAAK;AAGhG,gBAAI,gBAAgB,KAAK,YAAY,GAAG;AACpC,mBAAK,YAAY,EAAE,OAAO,IAAI;AAAA,YAClC,OAAO;AACH,sBAAQ,MAAM,0BAA0B,KAAK;AAAA,YACjD;AAAA,UACJ,UAAE;AAEE,gBAAI,kBAAkB,KAAK,cAAc,GAAG;AACxC,mBAAK,cAAc,EAAE,OAAO,IAAI;AAAA,YACpC;AAAA,UACJ;AAAA,QACJ;AAAA;AAAA,QAGA,qBAAqB,gBAAgB;AACjC,cAAI,kBAAkB;AAGtB,gBAAM,eAAe,eAAe,MAAM,cAAc;AAExD,cAAI,cAAc;AACd,yBAAa,QAAQ,WAAS;AAC1B,oBAAM,YAAY,MAAM,MAAM,GAAG,EAAE;AAEnC,kBAAI;AAEA,oBAAI,aAAa;AAGjB,6BAAa,KAAK,SAAS,SAAS;AAGpC,oBAAI,eAAe,QAAQ,eAAe,QAAW;AACjD,+BAAa,KAAK,SAAS;AAAA,gBAC/B;AAGA,oBAAI,eAAe,QAAQ,eAAe,QAAW;AACjD,sBAAI,KAAK,SAAS,YAAY,KAAK,SAAS,SAAS,SAAS,GAAG;AAC7D,iCAAa,KAAK,SAAS;AAAA,kBAC/B;AAAA,gBACJ;AAEA,oBAAI,eAAe,QAAQ,eAAe,QAAW;AAEjD,oCAAkB,gBAAgB;AAAA,oBAC9B;AAAA,oBACA,mBAAmB,UAAU;AAAA,kBACjC;AAEA,sBAAI,OAAO,aAAc,QAAO,aAAa,MAAM,eAAe,uBAAuB,SAAS,MAAM,UAAU,EAAE;AAAA,gBACxH,OAAO;AACH,sBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,cAAc,SAAS,0DAA0D;AAAA,gBAEtJ;AAAA,cACJ,SAAS,OAAO;AACZ,oBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,+BAA+B,SAAS,MAAM,KAAK;AAAA,cAExH;AAAA,YACJ,CAAC;AAAA,UACL;AAEA,iBAAO;AAAA,QACX;AAAA;AAAA,QAIA,MAAM,gBAAgB,QAAQ,QAAQ,MAAM,MAAM;AAE9C,gBAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,EAAE,KAAK,QAAM,GAAG,SAAS,UAAU,GAAG,MAAM,SAAS,CAAC;AAE9F,gBAAM,UAAU;AAAA,YACZ,UAAU;AAAA;AAAA,YAEV,GAAI,KAAK,UAAU,KAAK;AAAA,cACpB,iBAAiB,UAAU,KAAK,UAAU,CAAC;AAAA,YAC/C;AAAA,UACJ;AAEA,cAAI;AACJ,cAAI,SAAS;AAET,mBAAO,IAAI,SAAS,IAAI;AAAA,UAE5B,OAAO;AAEH,oBAAQ,cAAc,IAAI;AAC1B,mBAAO,KAAK,UAAU,IAAI;AAAA,UAC9B;AAEA,gBAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,YACjC,QAAQ,OAAO,YAAY;AAAA,YAC3B;AAAA,YACA;AAAA,UACJ,CAAC;AAED,cAAI,CAAC,SAAS,IAAI;AACd,gBAAI;AACJ,gBAAI;AACA,sBAAQ,MAAM,SAAS,KAAK;AAAA,YAChC,SAAS,GAAG;AACR,sBAAQ,EAAE,SAAS,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,GAAG;AAAA,YACzE;AACA,kBAAM,IAAI,MAAM,MAAM,WAAW,QAAQ,SAAS,MAAM,EAAE;AAAA,UAC9D;AAEA,cAAI;AACA,mBAAO,MAAM,SAAS,KAAK;AAAA,UAC/B,SAAS,GAAG;AAER,mBAAO,EAAE,SAAS,KAAK;AAAA,UAC3B;AAAA,QACJ;AAAA;AAAA,QAGA,cAAc,MAAM;AAChB,cAAI,UAAU;AACd,gBAAM,SAAS,KAAK,iBAAiB,yBAAyB;AAE9D,iBAAO,QAAQ,WAAS;AAEpB,gBAAI,CAAC,MAAM,cAAc,GAAG;AACxB,wBAAU;AACV,oBAAM,UAAU,IAAI,OAAO;AAC3B;AAAA,YACJ;AAGA,kBAAM,qBAAqB,MAAM,aAAa,iBAAiB;AAC/D,gBAAI,oBAAoB;AACpB,oBAAM,eAAe,KAAK,eAAe,OAAO,kBAAkB;AAClE,kBAAI,CAAC,cAAc;AACf,0BAAU;AACV,sBAAM,UAAU,IAAI,OAAO;AAAA,cAC/B,OAAO;AACH,sBAAM,UAAU,OAAO,OAAO;AAAA,cAClC;AAAA,YACJ,OAAO;AACH,oBAAM,UAAU,OAAO,OAAO;AAAA,YAClC;AAAA,UACJ,CAAC;AAED,iBAAO;AAAA,QACX;AAAA;AAAA,QAGA,eAAe,OAAO,oBAAoB;AACtC,gBAAM,QAAQ,MAAM;AAGpB,cAAI,OAAO,KAAK,kBAAkB,MAAM,YAAY;AAChD,gBAAI;AACA,qBAAO,KAAK,kBAAkB,EAAE,OAAO,KAAK;AAAA,YAChD,SAAS,OAAO;AACZ,kBAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,wBAAwB,kBAAkB,YAAY,KAAK;AAC5H,qBAAO;AAAA,YACX;AAAA,UACJ;AAGA,cAAI,OAAO,aAAc,QAAO,aAAa,KAAK,eAAe,wBAAwB,kBAAkB,aAAa;AACxH,iBAAO;AAAA,QACX;AAAA,MACJ;AAAA,MACA,YAAY;AAAA,IAChB;AAGA,QAAI,CAAC,gBAAgB,OAAO;AACxB,gBAAU,SAAS;AAAA,IACvB;AAGA,SAAK,OAAO,cAAc,SAAS,UAAU,SAAS;AAEtD,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAK;AACd,WAAO,IACF,MAAM,SAAS,EACf,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,EAAE;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB,WAAW;AAC/B,WAAO,qBAAqB,SAAS,gBAAgB,SAAS;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,SAAS;AAC9B,QAAI;AAEA,YAAM,cAAc,KAAK,OAAO,cAAc,iBAAiB,KAAK,OAAO,cAAc,eAAe,CAAC,KAAK;AAC9G,YAAM,UAAU,cAAc,GAAG,OAAO,IAAI,WAAW,KAAK;AAE5D,WAAK,IAAI,SAAS,uBAAuB,OAAO,EAAE;AAElD,YAAM,WAAW,MAAM,MAAM,SAAS;AAAA,QAClC,QAAQ;AAAA,QACR,SAAS;AAAA,UACL,gBAAgB;AAAA,UAChB,UAAU;AAAA,QACd;AAAA,MACJ,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AACd,cAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,EAAE;AAAA,MAC5D;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,UAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC3C,cAAM,IAAI,MAAM,sCAAsC;AAAA,MAC1D;AAEA,aAAO;AAAA,IAEX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,mCAAmC,KAAK;AAC1D,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,WAAW;AACvB,QAAI,KAAK,OAAO,cAAc;AAC1B,WAAK,OAAO,aAAa,yBAAyB,SAAS;AAAA,IAC/D;AACA,SAAK,IAAI,SAAS,gCAAgC,SAAS,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AACP,WAAO;AAAA,MACH,aAAa,KAAK,OAAO;AAAA,MACzB,SAAS,KAAK,OAAO;AAAA,MACrB,YAAY,KAAK,OAAO;AAAA,MACxB,WAAW,KAAK,OAAO;AAAA,MACvB,eAAe,KAAK,OAAO;AAAA,IAC/B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,WAAW;AACzB,WAAO,KAAK,aAAa,SAAS,EAAE,QAAQ,YAAY,KAAK,EAAE,KAAK;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,eAAe,GAAG,IAAI;AAAA,IAC9D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,IAAI,SAAS,uBAAuB;AACzC,SAAK,SAAS;AAAA,EAClB;AACJ;;;ACrsBO,IAAM,eAAN,MAAmB;AAAA,EACtB,YAAY,QAAQ,UAAU,CAAC,GAAG;AAC9B,SAAK,SAAS;AAAA,MACV,sBAAsB,QAAQ,yBAAyB;AAAA,MACvD,OAAO,QAAQ,SAAS;AAAA,MACxB,UAAU,QAAQ,aAAa,QAAQ,QAAQ,UAAU;AAAA,MACzD,aAAa,QAAQ,eAAe;AAAA,IACxC;AAGA,SAAK,SAAS;AAGd,SAAK,YAAY;AAAA,MACb,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,IACX;AAEA,SAAK,IAAI,QAAQ,gBAAgB,yCAAyC,KAAK,MAAM;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAiB,WAAW,OAAO;AACrC,QAAI,YAAY;AAChB,QAAI,eAAe;AAEnB,SAAK,MAAM,gBAAgB,8BAAU,MAAM,SAAS,MAAM,IAAI;AAG9D,QAAI,MAAM,QAAQ,SAAS,WAAW,KAClC,MAAM,QAAQ,SAAS,KAAK,KAC5B,MAAM,QAAQ,SAAS,mBAAmB,KAC1C,MAAM,QAAQ,SAAS,iBAAiB,KACvC,MAAM,SAAS,eAAe,MAAM,QAAQ,SAAS,SAAS,GAAI;AACnE,kBAAY;AACZ,qBAAe,IAAI,SAAS;AAAA,IAChC,WAAW,MAAM,QAAQ,SAAS,SAAS,KAAK,CAAC,MAAM,QAAQ,SAAS,WAAW,GAAG;AAClF,kBAAY;AACZ,qBAAe;AAAA,IACnB,WAAW,MAAM,QAAQ,SAAS,YAAY,KAAK,MAAM,QAAQ,SAAS,KAAK,GAAG;AAC9E,kBAAY;AACZ,qBAAe;AAAA,IACnB;AAEA,SAAK,MAAM,gBAAgB,2CAAa,SAAS,yBAAU,SAAS,GAAG;AAGvE,QAAI,KAAK,OAAO,sBAAsB;AAClC,WAAK,YAAY,WAAW,OAAO,SAAS;AAAA,IAChD;AAEA,QAAI;AAEA,UAAI,cAAc,KAAK;AACnB,cAAM,KAAK,YAAY;AAAA,MAC3B,OAAO;AAEH,cAAM,KAAK,cAAc,WAAW,YAAY;AAAA,MACpD;AAAA,IACJ,SAAS,eAAe;AACpB,WAAK,MAAM,gBAAgB,8DAAiB,aAAa;AAEzD,WAAK,sBAAsB,WAAW,YAAY;AAAA,IACtD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc;AAChB,QAAI;AACA,WAAK,KAAK,gBAAgB,qBAAqB;AAC/C,YAAM,YAAY,MAAM,KAAK,mBAAmB,KAAK;AACrD,YAAM,KAAK,8BAA8B,WAAW,KAAK;AACzD,WAAK,KAAK,gBAAgB,8BAA8B;AAAA,IAC5D,SAAS,OAAO;AACZ,WAAK,MAAM,gBAAgB,4BAA4B,KAAK;AAE5D,WAAK,sBAAsB,OAAO,wEAAiB;AAAA,IACvD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,WAAW,cAAc;AACzC,QAAI;AACA,WAAK,KAAK,gBAAgB,0BAA0B,SAAS,KAAK;AAGlE,YAAM,iBAAiB,MAAM,KAAK,qBAAqB,WAAW,YAAY;AAC9E,YAAM,KAAK,8BAA8B,gBAAgB,OAAO;AAChE,WAAK,KAAK,gBAAgB,cAAc,SAAS,sBAAsB;AAAA,IAC3E,SAAS,OAAO;AACZ,WAAK,MAAM,gBAAgB,cAAc,SAAS,oBAAoB,KAAK;AAE3E,WAAK,sBAAsB,WAAW,YAAY;AAAA,IACtD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,WAAW,cAAc;AAChD,QAAI;AAEA,YAAM,YAAY,MAAM,KAAK,mBAAmB,OAAO;AAGvD,YAAM,iBAAiB;AAAA,QACnB,GAAG;AAAA,QACH,OAAO;AACH,gBAAM,eAAe,UAAU,OAAO,UAAU,KAAK,IAAI,CAAC;AAC1D,iBAAO;AAAA,YACH,GAAG;AAAA,YACH;AAAA,YACA;AAAA,YACA,WAAW;AAAA,YACX,YAAY;AAAA,UAChB;AAAA,QACJ;AAAA,MACJ;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AAEZ,WAAK,MAAM,gBAAgB,gCAAgC,KAAK;AAChE,YAAM,IAAI,MAAM,2BAA2B,MAAM,OAAO,EAAE;AAAA,IAC9D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,WAAW,cAAc;AAC3C,UAAM,aAAa,SAAS,eAAe,KAAK;AAChD,QAAI,CAAC,WAAY;AAEjB,UAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAwBL,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKT,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuB5B,eAAW,YAAY;AAEvB,SAAK,KAAK,gBAAgB,qCAAqC,SAAS,EAAE;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,WAAW,OAAO,WAAW;AACrC,UAAM,cAAc;AAAA,MAChB,OAAO;AAAA,MACP;AAAA,MACA,cAAc,MAAM;AAAA,MACpB,OAAO,MAAM;AAAA,MACb,KAAK,OAAO,SAAS;AAAA,MACrB,WAAW,UAAU;AAAA,MACrB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,cAAc;AAAA,QACV,aAAa,KAAK,OAAO,OAAO;AAAA,QAChC,MAAM,KAAK,OAAO,OAAO;AAAA,MAC7B;AAAA,IACJ;AAEA,SAAK,MAAM,gBAAgB,uDAAe,WAAW;AAAA,EAIzD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAmB,WAAW;AAChC,QAAI,KAAK,OAAO,aAAa;AACzB,aAAO,MAAM,KAAK,OAAO,YAAY,mBAAmB,SAAS;AAAA,IACrE;AACA,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,8BAA8B,WAAW,WAAW;AACtD,QAAI,KAAK,OAAO,+BAA+B;AAC3C,aAAO,MAAM,KAAK,OAAO,8BAA8B,WAAW,SAAS;AAAA,IAC/E;AACA,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAO,cAAc,MAAM;AAE3B,QAAI,OAAO,UAAU,YAAY,CAAC,KAAK,UAAU,eAAe,KAAK,GAAG;AACpE,aAAO,CAAC,WAAW,GAAG,IAAI;AAC1B,kBAAY;AACZ,cAAQ,KAAK,OAAO,QAAQ,UAAU;AAAA,IAC1C;AAGA,UAAM,oBAAoB,KAAK,UAAU,KAAK,OAAO,QAAQ,KAAK,KAAK,UAAU;AACjF,UAAM,oBAAoB,KAAK,UAAU,KAAK,KAAK,KAAK,UAAU;AAElE,QAAI,oBAAoB,mBAAmB;AACvC;AAAA,IACJ;AAGA,QAAI,KAAK,OAAO,gBAAgB,gBAAgB,oBAAoB,KAAK,UAAU,MAAM;AACrF;AAAA,IACJ;AAEA,UAAM,SAAS,YAAY,IAAI,SAAS,MAAM;AAC9C,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,UAAU,IAAI,EAAE;AAE3D,YAAQ,OAAO;AAAA,MACX,KAAK;AACD,gBAAQ,MAAM,GAAG,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI;AAC/C;AAAA,MACJ,KAAK;AACD,gBAAQ,KAAK,GAAG,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI;AAC9C;AAAA,MACJ,KAAK;AACD,gBAAQ,KAAK,GAAG,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI;AAC9C;AAAA,MACJ,KAAK;AACD,gBAAQ,IAAI,GAAG,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI;AAC7C;AAAA,MACJ;AACI,gBAAQ,IAAI,GAAG,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI;AAAA,IACrD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAM;AACtB,SAAK,IAAI,SAAS,WAAW,GAAG,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,cAAc,MAAM;AACrB,SAAK,IAAI,QAAQ,WAAW,GAAG,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,cAAc,MAAM;AACrB,SAAK,IAAI,QAAQ,WAAW,GAAG,IAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,MAAM;AACtB,SAAK,IAAI,SAAS,WAAW,GAAG,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,SAAS;AACd,SAAK,KAAK,gBAAgB,wBAAwB;AAAA,EACtD;AACJ;;;ACtUO,IAAM,kBAAN,MAAsB;AAAA,EACzB,YAAY,SAAS,MAAM,UAAU,CAAC,GAAG;AAErC,SAAK,SAAS;AAAA,MACV,gBAAgB,QAAQ,kBAAkB;AAAA;AAAA,MAC1C,OAAO,QAAQ,SAAS;AAAA,MACxB,aAAa,QAAQ,eAAe;AAAA,MACpC,GAAG;AAAA,IACP;AAEA,SAAK,SAAS;AACd,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,SAAK,oBAAoB;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,QAAQ,cAAc;AAC3B,WAAK,OAAO,aAAa,IAAI,OAAO,mBAAmB,GAAG,IAAI;AAAA,IAClE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,eAAe;AAC/B,QAAI,CAAC,iBAAiB,OAAO,kBAAkB,UAAU;AACrD,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC/D;AAGA,QAAI,KAAK,gBAAgB,IAAI,aAAa,GAAG;AACzC,aAAO,KAAK,gBAAgB,IAAI,aAAa;AAAA,IACjD;AAEA,UAAM,cAAc,KAAK,uBAAuB,aAAa;AAC7D,SAAK,gBAAgB,IAAI,eAAe,WAAW;AAEnD,QAAI;AACA,YAAM,YAAY,MAAM;AACxB,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,YAAM;AAAA,IACV,UAAE;AACE,WAAK,gBAAgB,OAAO,aAAa;AAAA,IAC7C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAuB,eAAe;AAExC,UAAM,wBAAwB,GAAG,KAAK,OAAO,cAAc,IAAI,aAAa;AAE5E,QAAI;AACJ,QAAI,KAAK,UAAU,KAAK,OAAO,OAAO,SAAS;AAE3C,YAAM,UAAU,KAAK,OAAO,OAAO;AACnC,UAAI,QAAQ,WAAW,MAAM,GAAG;AAE5B,cAAM,eAAe,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AACpE,cAAM,qBAAqB,sBAAsB,WAAW,GAAG,IAAI,wBAAwB,IAAI,qBAAqB;AACpH,wBAAgB,GAAG,YAAY,GAAG,kBAAkB;AAAA,MACxD,OAAO;AACH,wBAAgB,KAAK,OAAO,YAAY,GAAG,OAAO,GAAG,qBAAqB,EAAE;AAAA,MAChF;AAAA,IACJ,OAAO;AAEH,sBAAgB,KAAK,SACjB,KAAK,OAAO,YAAY,OAAO,qBAAqB,EAAE,IACtD,OAAO,qBAAqB;AAAA,IACpC;AAEA,QAAI;AACA,YAAM,SAAS,MAAM,OAAO;AAC5B,YAAM,YAAY,OAAO;AAEzB,UAAI,CAAC,WAAW;AACZ,cAAM,IAAI,MAAM,cAAc,aAAa,yBAAyB;AAAA,MACxE;AAEA,UAAI,CAAC,UAAU,MAAM;AACjB,kBAAU,OAAO;AAAA,MACrB;AAEA,WAAK,IAAI,SAAS,cAAc,aAAa,uBAAuB;AACpE,aAAO;AAAA,IAEX,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,6BAA6B,aAAa,MAAM,KAAK;AACvE,YAAM,IAAI,MAAM,cAAc,aAAa,gBAAgB,MAAM,OAAO,EAAE;AAAA,IAC9E;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB;AACd,SAAK,gBAAgB,MAAM;AAC3B,SAAK,oBAAoB;AACzB,SAAK,IAAI,SAAS,wBAAwB;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,oBAAoB;AAEtB,QAAI,KAAK,mBAAmB;AACxB,WAAK,IAAI,SAAS,mCAAmC;AACrD,aAAO,KAAK;AAAA,IAChB;AAGA,QAAI,KAAK,OAAO,gBAAgB,cAAc;AAC1C,aAAO,MAAM,KAAK,0BAA0B;AAAA,IAChD;AAGA,WAAO,MAAM,KAAK,2BAA2B;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,4BAA4B;AAC9B,QAAI;AACA,YAAM,iBAAiB,GAAG,KAAK,QAAQ,QAAQ,cAAc,SAAS;AACtE,WAAK,IAAI,QAAQ,iDAAiD,cAAc;AAEhF,YAAM,mBAAmB,MAAM,OAAO;AAEtC,UAAI,OAAO,iBAAiB,uBAAuB,YAAY;AAC3D,aAAK,oBAAoB,iBAAiB,cAAc,CAAC;AACzD,aAAK,IAAI,QAAQ,2CAA2C,OAAO,KAAK,KAAK,iBAAiB,EAAE,MAAM,aAAa;AACnH,eAAO,KAAK;AAAA,MAChB,OAAO;AACH,cAAM,IAAI,MAAM,4DAA4D;AAAA,MAChF;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,QAAQ,mDAAmD,MAAM,OAAO;AACjF,WAAK,oBAAoB,CAAC;AAC1B,aAAO,CAAC;AAAA,IACZ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,6BAA6B;AAC/B,UAAM,iBAAiB,KAAK,mBAAmB;AAC/C,UAAM,aAAa,CAAC;AAEpB,SAAK,IAAI,QAAQ,gDAAgD,eAAe,KAAK,IAAI,CAAC,EAAE;AAE5F,eAAW,QAAQ,gBAAgB;AAC/B,UAAI;AACA,cAAM,YAAY,MAAM,KAAK,cAAc,IAAI;AAC/C,YAAI,WAAW;AACX,qBAAW,IAAI,IAAI;AAAA,QACvB;AAAA,MACJ,SAAS,WAAW;AAChB,aAAK,IAAI,QAAQ,0CAA0C,IAAI,KAAK,UAAU,OAAO;AAAA,MACzF;AAAA,IACJ;AAEA,SAAK,oBAAoB;AACzB,SAAK,IAAI,QAAQ,+CAA+C,OAAO,KAAK,UAAU,EAAE,MAAM,aAAa;AAC3G,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB;AACjB,QAAI,MAAM,QAAQ,KAAK,OAAO,cAAc,KAAK,KAAK,OAAO,eAAe,SAAS,GAAG;AACpF,aAAO,CAAC,GAAG,KAAK,OAAO,cAAc;AAAA,IACzC;AAGA,WAAO;AAAA,MACH;AAAA,MAAU;AAAA,MAAS;AAAA,MAAQ;AAAA,MAAS;AAAA,MAAS;AAAA,MAC7C;AAAA,MAAY;AAAA,MAAS;AAAA,MAAkB;AAAA,IAC3C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACN,SAAK,gBAAgB;AACrB,SAAK,IAAI,SAAS,0BAA0B;AAC5C,SAAK,SAAS;AAAA,EAClB;AACJ;;;AChMO,IAAM,kBAAN,MAAsB;AAAA,EACzB,YAAY,UAAU,CAAC,GAAG;AAEtB,SAAK,UAAU,QAAQ,WAAW;AAGlC,SAAK,SAAS,KAAK,aAAa,OAAO;AAEvC,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,kBAAkB;AAGvB,SAAK,uBAAuB;AAG5B,SAAK,UAAU;AACf,SAAK,eAAe;AAGpB,SAAK,0BAA0B,KAAK,kBAAkB,KAAK,IAAI;AAG/D,SAAK,eAAe,KAAK,WAAW;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,SAAS;AAClB,UAAM,gBAAgB,OAAO,SAAS;AAEtC,UAAM,WAAW;AAAA,MACb,UAAU;AAAA;AAAA,MACV,SAAS;AAAA;AAAA,MACT,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU;AAAA,MACV,cAAc;AAAA,MACd,WAAW;AAAA,MACX,eAAe;AAAA,MACf,aAAa;AAAA,MACb,YAAY;AAAA;AAAA,MACZ,sBAAsB;AAAA,MACtB,eAAe;AAAA,MACf,gBAAgB,CAAC,UAAU,SAAS,QAAQ,SAAS,SAAS,QAAQ,YAAY,SAAS,kBAAkB,aAAa;AAAA,MAC1H,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,UAAU;AAAA;AAAA,MACV,UAAU;AAAA,MACV,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,iBAAiB,CAAC;AAAA,MAClB,mBAAmB,CAAC;AAAA,MACpB,cAAc,CAAC,SAAS,YAAY,MAAM;AAAA,MAC1C,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,MAChB,yBAAyB,CAAC,eAAe,SAAS,KAAK;AAAA,MACvD,aAAa;AAAA,MACb,mBAAmB,CAAC;AAAA,MACpB,oBAAoB;AAAA,MACpB,2BAA2B;AAAA,MAC3B,oBAAoB;AAAA,MACpB,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,qBAAqB;AAAA,IACzB;AAEA,UAAM,SAAS,EAAE,GAAG,UAAU,GAAG,QAAQ;AAGzC,WAAO,UAAU,KAAK,YAAY,OAAO,SAAS,OAAO,QAAQ;AACjE,WAAO,aAAa,KAAK,YAAY,OAAO,YAAY,OAAO,QAAQ;AACvE,WAAO,WAAW,KAAK,YAAY,OAAO,UAAU,OAAO,QAAQ;AAEnE,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,MAAM,WAAW,MAAM;AAC/B,UAAM,gBAAgB,OAAO,SAAS;AAGtC,QAAI,KAAK,WAAW,MAAM,GAAG;AACzB,aAAO;AAAA,IACX;AAGA,QAAI,KAAK,WAAW,GAAG,GAAG;AAEtB,UAAI,YAAY,aAAa,KAAK;AAE9B,cAAM,gBAAgB,SAAS,SAAS,GAAG,IAAI,SAAS,MAAM,GAAG,EAAE,IAAI;AACvE,cAAM,YAAY,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACxD,cAAM,WAAW,GAAG,aAAa,GAAG,SAAS;AAC7C,cAAMC,WAAU,GAAG,aAAa,GAAG,QAAQ;AAC3C,eAAOA,SAAQ,QAAQ,iBAAiB,KAAK;AAAA,MACjD;AAEA,aAAO,GAAG,aAAa,GAAG,IAAI;AAAA,IAClC;AAGA,UAAM,kBAAkB,OAAO,SAAS;AACxC,UAAM,cAAc,gBAAgB,SAAS,GAAG,IAC1C,kBACA,gBAAgB,UAAU,GAAG,gBAAgB,YAAY,GAAG,IAAI,CAAC;AAGvE,UAAM,eAAe,KAAK,cAAc,cAAc,IAAI;AAE1D,UAAM,UAAU,GAAG,aAAa,GAAG,YAAY;AAG/C,WAAO,QAAQ,QAAQ,iBAAiB,KAAK;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,MAAM;AAEhB,WAAO,KAAK,QAAQ,QAAQ,GAAG;AAC/B,UAAM,QAAQ,KAAK,MAAM,GAAG,EAAE,OAAO,UAAQ,SAAS,MAAM,SAAS,GAAG;AACxE,UAAM,QAAQ,CAAC;AAEf,eAAW,QAAQ,OAAO;AACtB,UAAI,SAAS,MAAM;AACf,YAAI,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,MAAM,MAAM;AACtD,gBAAM,IAAI;AAAA,QACd,WAAW,CAAC,KAAK,WAAW,GAAG,GAAG;AAC9B,gBAAM,KAAK,IAAI;AAAA,QACnB;AAAA,MACJ,OAAO;AACH,cAAM,KAAK,IAAI;AAAA,MACnB;AAAA,IACJ;AAEA,UAAM,aAAa,MAAM,MAAM,KAAK,GAAG;AACvC,WAAO,eAAe,MAAM,MAAM;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,UAAU,MAAM;AAChB,QAAI,KAAK,cAAc;AACnB,WAAK,aAAa,IAAI,OAAO,UAAU,GAAG,IAAI;AAAA,IAClD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa;AACf,QAAI;AAGA,WAAK,eAAe,IAAI,aAAa,MAAM,KAAK,MAAM;AACtD,WAAK,cAAc,IAAI,YAAY,MAAM,KAAK,MAAM;AACpD,WAAK,eAAe,IAAI,aAAa,MAAM,KAAK,MAAM;AACtD,WAAK,eAAe,IAAI,aAAa,MAAM,KAAK,MAAM;AAGtD,UAAI,KAAK,OAAO,SAAS;AACrB,YAAI;AACA,eAAK,cAAc,IAAI,YAAY,MAAM,KAAK,MAAM;AACpD,cAAI,KAAK,YAAY,aAAa;AAC9B,kBAAM,KAAK,YAAY;AAAA,UAC3B;AACA,eAAK,IAAI,QAAQ,sCAAsC;AAAA,QAC3D,SAAS,WAAW;AAChB,eAAK,IAAI,QAAQ,+DAA+D,UAAU,OAAO;AACjG,eAAK,cAAc;AACnB,eAAK,OAAO,UAAU;AAAA,QAC1B;AAAA,MACJ;AAEA,UAAI,KAAK,OAAO,aAAa;AACzB,aAAK,cAAc,IAAI,YAAY,MAAM,KAAK,MAAM;AAAA,MACxD;AAEA,UAAI,KAAK,OAAO,eAAe;AAC3B,YAAI;AACA,eAAK,kBAAkB,IAAI,gBAAgB,MAAM;AAAA,YAC7C,GAAG,KAAK;AAAA,YACR,UAAU,GAAG,KAAK,OAAO,QAAQ;AAAA,YACjC,OAAO;AAAA,YACP,gBAAgB,KAAK,OAAO;AAAA,UAChC,CAAC;AACD,gBAAM,KAAK,gBAAgB,kBAAkB;AAC7C,eAAK,IAAI,QAAQ,0CAA0C;AAAA,QAC/D,SAAS,gBAAgB;AACrB,eAAK,IAAI,QAAQ,yEAAyE,eAAe,OAAO;AAChH,eAAK,kBAAkB;AAAA,QAC3B;AAAA,MACJ;AAGA,WAAK,UAAU;AACf,WAAK,KAAK;AAAA,IAEd,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,iCAAiC,KAAK;AAExD,WAAK,UAAU;AACf,WAAK,KAAK;AAAA,IACd;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAe;AACjB,QAAI,KAAK,QAAS,QAAO;AACzB,QAAI,KAAK,cAAc;AACnB,YAAM,KAAK;AAAA,IACf;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAGA,OAAO;AACH,UAAM,aAAa,KAAK,OAAO,SAAS;AAGxC,WAAO;AAAA,MACH,aAAa,eAAe;AAAA,MAC5B,KAAK;AAAA,IACT;AAGA,UAAM,YAAY,MAAM;AACpB,UAAI,cAAc,CAAC,OAAO,SAAS,MAAM;AACrC,eAAO,SAAS,OAAO;AAAA,MAC3B,WAAW,CAAC,cAAc,OAAO,SAAS,aAAa,KAAK;AACxD,aAAK,WAAW,MAAM;AAAA,MAC1B,OAAO;AACH,aAAK,kBAAkB;AAAA,MAC3B;AAAA,IACJ;AAEA,QAAI,SAAS,eAAe,WAAW;AACnC,eAAS,iBAAiB,oBAAoB,SAAS;AAAA,IAC3D,OAAO;AAEH,4BAAsB,SAAS;AAAA,IACnC;AAAA,EACJ;AAAA,EAEA,oBAAoB;AAChB,UAAM,EAAE,OAAO,YAAY,IAAI,KAAK,sBAAsB;AAG1D,SAAK,cAAc,sBAAsB,WAAW;AAGpD,QAAI,UAAU,KAAK,eAAe,KAAK,cAAc,sBAAsB,WAAW,GAAG;AACrF,WAAK,cAAc;AACnB,WAAK,UAAU,KAAK;AAAA,IACxB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAwB;AACpB,QAAI,KAAK,OAAO,SAAS,QAAQ;AAC7B,YAAM,WAAW,OAAO,SAAS,KAAK,MAAM,CAAC,KAAK;AAClD,YAAM,CAAC,UAAU,SAAS,IAAI,SAAS,MAAM,GAAG;AAGhD,UAAI,QAAQ;AACZ,UAAI,YAAY,aAAa,KAAK;AAC9B,gBAAQ,SAAS,WAAW,GAAG,IAAI,SAAS,MAAM,CAAC,IAAI;AAAA,MAC3D;AAEA,aAAO;AAAA,QACH,OAAO,SAAS;AAAA,QAChB,aAAa,KAAK,cAAc,iBAAiB,aAAa,OAAO,SAAS,OAAO,MAAM,CAAC,CAAC,KAAK,CAAC;AAAA,MACvG;AAAA,IACJ,OAAO;AAEH,YAAM,WAAW,OAAO,SAAS;AACjC,YAAM,WAAW,KAAK,OAAO,YAAY;AAGzC,UAAI,QAAQ;AACZ,UAAI,aAAa,OAAO,SAAS,WAAW,QAAQ,GAAG;AACnD,gBAAQ,SAAS,MAAM,SAAS,MAAM;AAAA,MAC1C;AAGA,UAAI,MAAM,WAAW,GAAG,GAAG;AACvB,gBAAQ,MAAM,MAAM,CAAC;AAAA,MACzB;AAEA,aAAO;AAAA,QACH,OAAO,SAAS;AAAA,QAChB,aAAa,KAAK,cAAc,iBAAiB,OAAO,SAAS,OAAO,MAAM,CAAC,CAAC,KAAK,CAAC;AAAA,MAC1F;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAM,UAAU,WAAW;AAEvB,UAAM,aAAa,KAAK;AAExB,QAAI,YAAY;AACZ;AAAA,IACJ;AAEA,QAAI;AACA,WAAK,uBAAuB;AAG5B,YAAM,aAAa,KAAK,cACpB,MAAM,KAAK,YAAY,oBAAoB,SAAS,IACpD,EAAE,SAAS,MAAM,QAAQ,gBAAgB;AAC7C,UAAI,CAAC,WAAW,SAAS;AAErB,YAAI,KAAK,aAAa;AAClB,eAAK,YAAY,cAAc,iBAAiB;AAAA,YAC5C,eAAe;AAAA,YACf,YAAY,KAAK,OAAO;AAAA,UAC5B,CAAC;AAGD,cAAI,cAAc,KAAK,OAAO,YAAY;AACtC,iBAAK,WAAW,KAAK,OAAO,YAAY,EAAE,UAAU,UAAU,CAAC;AAAA,UACnE,OAAO;AACH,iBAAK,WAAW,KAAK,OAAO,UAAU;AAAA,UAC1C;AAAA,QACJ;AACA;AAAA,MACJ;AAEA,YAAM,aAAa,SAAS,eAAe,KAAK;AAChD,UAAI,CAAC,YAAY;AACb,cAAM,IAAI,MAAM,uBAAuB;AAAA,MAC3C;AAGA,YAAM,YAAY,MAAM,KAAK,YAAY,mBAAmB,SAAS;AAGrE,YAAM,KAAK,8BAA8B,WAAW,SAAS;AAAA,IAIjE,SAAS,OAAO;AACZ,WAAK,IAAI,SAAS,yBAAyB,SAAS,MAAM,MAAM,OAAO;AAIvE,UAAI,KAAK,cAAc;AACnB,cAAM,KAAK,aAAa,iBAAiB,WAAW,KAAK;AAAA,MAC7D,OAAO;AACH,gBAAQ,MAAM,qCAAqC;AAAA,MACvD;AAAA,IACJ,UAAE;AAEE,WAAK,uBAAuB;AAAA,IAChC;AAAA,EACJ;AAAA,EAEA,MAAM,8BAA8B,cAAc,WAAW;AACzD,UAAM,aAAa,SAAS,eAAe,KAAK;AAChD,QAAI,CAAC,WAAY;AAGjB,UAAM,mBAAmB,SAAS,cAAc,KAAK;AACrD,qBAAiB,YAAY;AAC7B,qBAAiB,KAAK,QAAQ,SAAS,IAAI,KAAK,IAAI,CAAC;AAGrD,UAAM,qBAAqB,WAAW,iBAAiB,iBAAiB;AACxE,uBAAmB,QAAQ,eAAa;AACpC,gBAAU,UAAU,OAAO,cAAc;AACzC,gBAAU,UAAU,IAAI,cAAc;AAAA,IAC1C,CAAC;AAGD,eAAW,YAAY,gBAAgB;AAGvC,QAAI,KAAK,OAAO,gBAAgB,iBAAiB,aAAa,QAAQ;AAClE,WAAK,WAAW,aAAa,QAAQ,SAAS;AAAA,IAClD;AAGA,UAAM,EAAE,UAAU,IAAI;AACtB,UAAM,YAAY,UAAU,YAAY;AAGxC,cAAU,OAAO,iBAAiB,UAAU;AAAA,MACxC,YAAY,CAAC,OAAO,WAAW,KAAK,WAAW,OAAO,MAAM;AAAA,MAC5D,iBAAiB,MAAM,KAAK,gBAAgB;AAAA;AAAA,MAG5C,WAAW,MAAM,KAAK,cAAc,aAAa,KAAK,CAAC;AAAA,MACvD,UAAU,CAAC,KAAK,iBAAiB,KAAK,cAAc,SAAS,KAAK,YAAY;AAAA;AAAA,MAG9E,gBAAgB,MAAM,KAAK,cAAc,eAAe,KAAK,CAAC;AAAA,MAC9D,eAAe,CAAC,KAAK,iBAAiB,KAAK,cAAc,cAAc,KAAK,YAAY;AAAA,MACxF,gBAAgB,CAAC,QAAQ,YAAY,KAAK,cAAc,eAAe,QAAQ,OAAO;AAAA,MACtF,mBAAmB,CAAC,SAAS,KAAK,cAAc,kBAAkB,IAAI;AAAA;AAAA,MAGtE,gBAAgB,MAAM,KAAK,cAAc,eAAe,KAAK,CAAC;AAAA,MAC9D,eAAe,CAAC,KAAK,iBAAiB,KAAK,cAAc,cAAc,KAAK,YAAY;AAAA,MAExF,cAAc,KAAK;AAAA,MACnB,cAAc,KAAK,cAAc,eAAe,KAAK,CAAC;AAAA,IAC1D;AAIA,cAAU,MAAM,IAAI,iBAAiB,EAAE,EAAE;AAGzC,0BAAsB,MAAM;AACxB,WAAK,qBAAqB;AAC1B,WAAK,uBAAuB;AAAA,IAChC,CAAC;AAGD,QAAI,KAAK,eAAe;AACpB,WAAK,iBAAiB,KAAK;AAAA,IAC/B;AAEA,SAAK,gBAAgB;AAAA,EACzB;AAAA,EAEA,uBAAuB;AACnB,UAAM,aAAa,SAAS,eAAe,KAAK;AAChD,QAAI,CAAC,WAAY;AAGjB,UAAM,WAAW,SAAS,uBAAuB;AACjD,UAAM,oBAAoB,WAAW,iBAAiB,8BAA8B;AAGpF,sBAAkB,QAAQ,eAAa,UAAU,OAAO,CAAC;AAGzD,QAAI,KAAK,gBAAgB;AACrB,UAAI;AACA,aAAK,eAAe,QAAQ;AAAA,MAChC,SAAS,OAAO;AAAA,MAEhB;AACA,WAAK,iBAAiB;AAAA,IAC1B;AAII,eAAW,cAAc,UAAU,GAAG,OAAO;AAAA,EACrD;AAAA,EAEA,WAAW,KAAK,WAAW;AAEvB,UAAM,WAAW,SAAS,cAAc,qBAAqB,SAAS,IAAI;AAC1E,QAAI,SAAU,UAAS,OAAO;AAE9B,QAAI,KAAK;AACL,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,cAAc;AACpB,YAAM,aAAa,cAAc,SAAS;AAC1C,eAAS,KAAK,YAAY,KAAK;AAAA,IACnC;AAAA,EACJ;AAAA,EAGA,WAAW,WAAW,SAAS,MAAM;AAEjC,QAAI,OAAO,cAAc,UAAU;AAC/B,eAAS,UAAU,UAAU;AAC7B,kBAAY,UAAU;AAAA,IAC1B;AAGA,QAAI,cAAc,KAAK,eAAe,KAAK,cAAc;AACrD,WAAK,aAAa,iBAAiB;AAAA,IACvC;AAGA,QAAI,KAAK,cAAc;AACnB,WAAK,aAAa,sBAAsB,MAAM;AAAA,IAClD;AAGA,SAAK,UAAU,WAAW,MAAM;AAAA,EACpC;AAAA,EAEA,kBAAkB;AACd,WAAO,KAAK;AAAA,EAChB;AAAA,EAGA,UAAU,OAAO,SAAS,MAAM;AAC5B,UAAM,cAAc,UAAU,KAAK,cAAc,eAAe,KAAK,CAAC;AACtE,UAAM,cAAc,KAAK,cAAc,iBAAiB,WAAW,KAAK;AAGxE,UAAM,WAAW,CAACC,QAAOC,cAAa,SAAS,SAAS;AACpD,UAAI,OAAOD,WAAU,SAAS,MAAM,IAAIA,MAAK;AAG7C,UAAI,CAAC,UAAU,KAAK,OAAO,YAAY,KAAK,OAAO,aAAa,KAAK;AACjE,eAAO,GAAG,KAAK,OAAO,QAAQ,GAAG,IAAI;AAAA,MACzC;AAEA,YAAM,MAAMC,eAAc,GAAG,IAAI,IAAIA,YAAW,KAAK;AACrD,aAAO,SAAS,IAAI,GAAG,KAAK;AAAA,IAChC;AAEA,QAAI,KAAK,OAAO,SAAS,QAAQ;AAC7B,YAAM,UAAU,SAAS,OAAO,WAAW;AAG3C,UAAI,OAAO,SAAS,SAAS,SAAS;AAClC,eAAO,SAAS,OAAO;AAAA,MAC3B;AAAA,IACJ,OAAO;AACH,YAAM,UAAU,SAAS,OAAO,aAAa,KAAK;AAGlD,UAAI,eAAe,UAAU,SAAS,MAAM,IAAI,KAAK;AACrD,UAAI,KAAK,OAAO,YAAY,KAAK,OAAO,aAAa,KAAK;AACtD,uBAAe,GAAG,KAAK,OAAO,QAAQ,GAAG,YAAY;AAAA,MACzD;AAEA,YAAM,cAAc,OAAO,SAAS,aAAa;AAEjD,UAAI,aAAa;AACb,eAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO;AAAA,MAC/C,OAAO;AACH,eAAO,QAAQ,UAAU,CAAC,GAAG,IAAI,OAAO;AAAA,MAC5C;AACA,WAAK,kBAAkB;AAAA,IAC3B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAEN,WAAO;AAAA,MACH,KAAK,OAAO,SAAS,SAAS,eAAe;AAAA,MAC7C,KAAK;AAAA,IACT;AAGA,QAAI,KAAK,eAAe;AACpB,WAAK,cAAc,QAAQ;AAC3B,WAAK,gBAAgB;AAAA,IACzB;AAGA,QAAI,KAAK,gBAAgB;AACrB,WAAK,eAAe,QAAQ;AAC5B,WAAK,iBAAiB;AAAA,IAC1B;AAGA,WAAO,OAAO,IAAI,EAAE,QAAQ,aAAW;AACnC,UAAI,WAAW,OAAO,QAAQ,YAAY,YAAY;AAClD,gBAAQ,QAAQ;AAAA,MACpB;AAAA,IACJ,CAAC;AAGD,SAAK,cAAc,SAAS;AAG5B,UAAM,aAAa,SAAS,eAAe,KAAK;AAChD,QAAI,YAAY;AACZ,iBAAW,YAAY;AAAA,IAC3B;AAEA,SAAK,IAAI,QAAQ,kBAAkB;AAAA,EACvC;AACJ;",
|
|
6
|
+
"names": ["isAuthenticated", "fullUrl", "route", "queryString"]
|
|
7
7
|
}
|