ionic-logging-service
Version:
Logging functionalities for apps built with Ionic framework
1 lines • 56.8 kB
Source Map (JSON)
{"version":3,"file":"ionic-logging-service.mjs","sources":["../../../projects/ionic-logging-service/src/lib/json-layout.model.ts","../../../projects/ionic-logging-service/src/lib/log-level.model.ts","../../../projects/ionic-logging-service/src/lib/log-level.converter.ts","../../../projects/ionic-logging-service/src/lib/ajax-appender.model.ts","../../../projects/ionic-logging-service/src/lib/local-storage-appender.model.ts","../../../projects/ionic-logging-service/src/lib/logger.model.ts","../../../projects/ionic-logging-service/src/lib/memory-appender.model.ts","../../../projects/ionic-logging-service/src/lib/logging.service.ts","../../../projects/ionic-logging-service/src/lib/logging-service.module.ts","../../../projects/ionic-logging-service/src/public_api.ts","../../../projects/ionic-logging-service/src/ionic-logging-service.ts"],"sourcesContent":["import * as log4javascript from \"log4javascript\";\nimport { LoggingEvent } from \"log4javascript\";\n\n/**\n * Formats a logging event into JavaScript Object Notation (JSON).\n * The implemenatation is mainly the same as with log4javascript.JsonLayout,\n * with an improvement of serializing messages containing '\\\"'.\"\n */\nexport class JsonLayout extends log4javascript.JsonLayout {\n\n\t/**\n\t * Formats the log message.\n\t */\n\tpublic format(loggingEvent: LoggingEvent): string {\n\t\tconst eventObj = {\n\t\t\tlogger: loggingEvent.logger.name,\n\t\t\ttimestamp: loggingEvent.timeStampInMilliseconds,\n\t\t\tlevel: loggingEvent.level.toString(),\n\t\t\turl: window.location.href,\n\t\t\tmessage: this.isCombinedMessages() ? loggingEvent.getCombinedMessages() : loggingEvent.messages\n\t\t};\n\t\treturn JSON.stringify(eventObj);\n\t}\n\n\t/**\n\t * Gets the layout's name.\n\t * Mainly for unit testing purposes.\n\t *\n\t * @return layout's name\n\t */\n\tpublic toString(): string {\n\t\treturn \"Ionic.Logging.JsonLayout\";\n\t}\n}\n","/**\n * Logging levels.\n */\nexport enum LogLevel {\n\t/**\n\t * All events should be logged.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tALL,\n\n\t/**\n\t * A fine-grained debug message, typically capturing the flow through the application.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tTRACE,\n\n\t/**\n\t * A general debugging event.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tDEBUG,\n\n\t/**\n\t * An event for informational purposes.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tINFO,\n\n\t/**\n\t * An event that might possible lead to an error.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tWARN,\n\n\t/**\n\t * An error in the application, possibly recoverable.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tERROR,\n\n\t/**\n\t * A severe error that will prevent the application from continuing.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tFATAL,\n\n\t/**\n\t * No events will be logged.\n\t */\n\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\tOFF,\n}\n","import * as log4javascript from \"log4javascript\";\n\nimport { LogLevel } from \"./log-level.model\";\n\n/**\n * Helper class for converting log levels from and to different data type.\n */\nexport class LogLevelConverter {\n\n\t/**\n\t * Converts log4javascript.Level to internal LogLevel.\n\t *\n\t * @param level log4javascript's data type\n\t * @return internal data type.\n\t */\n\tpublic static levelFromLog4Javascript(level: log4javascript.Level): LogLevel {\n\t\tswitch (level) {\n\t\t\tcase log4javascript.Level.ALL:\n\t\t\t\treturn LogLevel.ALL;\n\t\t\tcase log4javascript.Level.DEBUG:\n\t\t\t\treturn LogLevel.DEBUG;\n\t\t\tcase log4javascript.Level.ERROR:\n\t\t\t\treturn LogLevel.ERROR;\n\t\t\tcase log4javascript.Level.FATAL:\n\t\t\t\treturn LogLevel.FATAL;\n\t\t\tcase log4javascript.Level.INFO:\n\t\t\t\treturn LogLevel.INFO;\n\t\t\tcase log4javascript.Level.OFF:\n\t\t\t\treturn LogLevel.OFF;\n\t\t\tcase log4javascript.Level.TRACE:\n\t\t\t\treturn LogLevel.TRACE;\n\t\t\tcase log4javascript.Level.WARN:\n\t\t\t\treturn LogLevel.WARN;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`invalid level ${level}`);\n\t\t}\n\t}\n\n\t/**\n\t * Converts string representation to internal LogLevel.\n\t *\n\t * @param level string representation\n\t * @return internal data type.\n\t */\n\tpublic static levelFromString(level: string): LogLevel {\n\t\tswitch (level) {\n\t\t\tcase \"ALL\":\n\t\t\t\treturn LogLevel.ALL;\n\t\t\tcase \"DEBUG\":\n\t\t\t\treturn LogLevel.DEBUG;\n\t\t\tcase \"ERROR\":\n\t\t\t\treturn LogLevel.ERROR;\n\t\t\tcase \"FATAL\":\n\t\t\t\treturn LogLevel.FATAL;\n\t\t\tcase \"INFO\":\n\t\t\t\treturn LogLevel.INFO;\n\t\t\tcase \"OFF\":\n\t\t\t\treturn LogLevel.OFF;\n\t\t\tcase \"TRACE\":\n\t\t\t\treturn LogLevel.TRACE;\n\t\t\tcase \"WARN\":\n\t\t\t\treturn LogLevel.WARN;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`invalid level ${level}`);\n\t\t}\n\t}\n\n\t/**\n\t * Converts internal LogLevel to log4javascript.Level.\n\t *\n\t * @param internal data type.\n\t * @return level log4javascript's data type\n\t */\n\tpublic static levelToLog4Javascript(level: LogLevel): log4javascript.Level {\n\t\tswitch (level) {\n\t\t\tcase LogLevel.ALL:\n\t\t\t\treturn log4javascript.Level.ALL;\n\t\t\tcase LogLevel.DEBUG:\n\t\t\t\treturn log4javascript.Level.DEBUG;\n\t\t\tcase LogLevel.ERROR:\n\t\t\t\treturn log4javascript.Level.ERROR;\n\t\t\tcase LogLevel.FATAL:\n\t\t\t\treturn log4javascript.Level.FATAL;\n\t\t\tcase LogLevel.INFO:\n\t\t\t\treturn log4javascript.Level.INFO;\n\t\t\tcase LogLevel.OFF:\n\t\t\t\treturn log4javascript.Level.OFF;\n\t\t\tcase LogLevel.TRACE:\n\t\t\t\treturn log4javascript.Level.TRACE;\n\t\t\tcase LogLevel.WARN:\n\t\t\t\treturn log4javascript.Level.WARN;\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`invalid level ${level}`);\n\t\t}\n\t}\n}\n","import { EventEmitter } from \"@angular/core\";\n\nimport * as log4javascript from \"log4javascript\";\n\nimport { AjaxAppenderConfiguration } from \"./ajax-appender.configuration\";\nimport { JsonLayout } from \"./json-layout.model\";\nimport { LogLevelConverter } from \"./log-level.converter\";\n\n/**\n * An appender which sends the log messages to a server via HTTP.\n *\n * A typical configuration could be:\n *\n * ```json\n * {\n * \"url\": \"https://my.backend.xy/LoggingBackend\",\n * \"batchSize\": 10,\n * \"timerInterval\": 60000,\n * \"threshold\": \"INFO\"\n * }\n * ```\n */\nexport class AjaxAppender extends log4javascript.Appender {\n\n\tprivate static batchSizeDefault = 1;\n\tprivate static timerIntervalDefault = 0;\n\tprivate static thresholdDefault = \"WARN\";\n\n\t/**\n\t * Event triggered when the appender could not send log messages to the server.\n\t *\n\t * @param message error message\n\t */\n\tpublic appenderFailed: EventEmitter<string>;\n\n\tprivate ajaxAppender: log4javascript.AjaxAppender;\n\tprivate url: string;\n\tprivate withCredentials: boolean;\n\n\t/**\n\t * Creates a new instance of the appender.\n\t *\n\t * @param configuration configuration for the appender.\n\t */\n\tconstructor(configuration: AjaxAppenderConfiguration) {\n\t\tsuper();\n\n\t\tif (!configuration) {\n\t\t\tthrow new Error(\"configuration must be not empty\");\n\t\t}\n\t\tif (!configuration.url) {\n\t\t\tthrow new Error(\"url must be not empty\");\n\t\t}\n\t\tthis.ajaxAppender = new log4javascript.AjaxAppender(configuration.url, configuration.withCredentials);\n\t\tthis.url = configuration.url;\n\t\tthis.withCredentials = configuration.withCredentials;\n\n\t\tthis.ajaxAppender.setLayout(new JsonLayout(false, false));\n\t\tthis.ajaxAppender.addHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n\t\tthis.ajaxAppender.setSendAllOnUnload(true);\n\n\t\tthis.appenderFailed = new EventEmitter<string>();\n\t\tthis.ajaxAppender.setFailCallback((message: any) => {\n\t\t\tthis.appenderFailed.emit(message);\n\t\t});\n\n\t\t// process remaining configuration\n\t\tthis.configure({\n\t\t\tbatchSize: configuration.batchSize || AjaxAppender.batchSizeDefault,\n\t\t\tthreshold: configuration.threshold || AjaxAppender.thresholdDefault,\n\t\t\ttimerInterval: configuration.timerInterval || AjaxAppender.timerIntervalDefault,\n\t\t\turl: configuration.url,\n\t\t\twithCredentials: configuration.withCredentials\n\t\t});\n\n\t}\n\n\t/**\n\t * Configures the logging depending on the given configuration.\n\t *\n\t * Only the defined properties get overwritten.\n\t * Neither url nor withCredentials can be modified.\n\t *\n\t * @param configuration configuration data.\n\t */\n\tpublic configure(configuration: AjaxAppenderConfiguration): void {\n\t\tif (configuration) {\n\t\t\tif (configuration.url && configuration.url !== this.url) {\n\t\t\t\tthrow new Error(\"url must not be changed\");\n\t\t\t}\n\t\t\tif (configuration.withCredentials && configuration.withCredentials !== this.withCredentials) {\n\t\t\t\tthrow new Error(\"withCredentials must not be changed\");\n\t\t\t}\n\t\t\tif (configuration.batchSize) {\n\t\t\t\tthis.setBatchSize(configuration.batchSize);\n\t\t\t}\n\t\t\tif (typeof configuration.timerInterval === \"number\") {\n\t\t\t\tthis.setTimerInterval(configuration.timerInterval);\n\t\t\t}\n\t\t\tif (configuration.threshold) {\n\t\t\t\tconst convertedThreshold = LogLevelConverter.levelToLog4Javascript(\n\t\t\t\t\tLogLevelConverter.levelFromString(configuration.threshold));\n\t\t\t\tthis.setThreshold(convertedThreshold);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Appender-specific method to append a log message.\n\t *\n\t * @param loggingEvent event to be appended.\n\t */\n\tpublic append(loggingEvent: log4javascript.LoggingEvent): void {\n\t\tthis.ajaxAppender.append(loggingEvent);\n\t}\n\n\t/**\n\t * Gets the appender's name.\n\t * Mainly for unit testing purposes.\n\t *\n\t * @return appender's name\n\t */\n\tpublic toString(): string {\n\t\treturn \"Ionic.Logging.AjaxAppender\";\n\t}\n\n\t/**\n\t * Get the internally used appender.\n\t * Mainly for unit testing purposes.\n\t */\n\tpublic getInternalAppender(): log4javascript.AjaxAppender {\n\t\treturn this.ajaxAppender;\n\t}\n\n\t/**\n\t * Returns the number of log messages sent in each request.\n\t */\n\tpublic getBatchSize(): number {\n\t\treturn this.ajaxAppender.getBatchSize();\n\t}\n\n\t/**\n\t * Sets the number of log messages to send in each request.\n\t *\n\t * @param batchSize new batch size\n\t */\n\tpublic setBatchSize(batchSize: number): void {\n\t\tthis.ajaxAppender.setBatchSize(batchSize);\n\t}\n\n\t/**\n\t * Returns the appender's layout.\n\t */\n\tpublic getLayout(): log4javascript.Layout {\n\t\treturn this.ajaxAppender.getLayout();\n\t}\n\n\t/**\n\t * Sets the appender's layout.\n\t */\n\tpublic setLayout(layout: log4javascript.Layout): void {\n\t\tthis.ajaxAppender.setLayout(layout);\n\t}\n\n\t/**\n\t * Returns the length of time in milliseconds between each sending of queued log messages.\n\t */\n\tpublic getTimerInterval(): number {\n\t\treturn this.ajaxAppender.getTimerInterval();\n\t}\n\n\t/**\n\t * Sets the length of time in milliseconds between each sending of queued log messages.\n\t *\n\t * @param timerInterval new timer interval\n\t */\n\tpublic setTimerInterval(timerInterval: number): void {\n\t\tthis.ajaxAppender.setTimed(timerInterval > 0);\n\t\tthis.ajaxAppender.setTimerInterval(timerInterval);\n\t}\n}\n","import * as log4javascript from \"log4javascript\";\n\nimport { LocalStorageAppenderConfiguration } from \"./local-storage-appender.configuration\";\nimport { LogLevelConverter } from \"./log-level.converter\";\nimport { LogLevel } from \"./log-level.model\";\nimport { LogMessage } from \"./log-message.model\";\n\n/**\n * An appender which stores the log messages in the browser's local storage.\n *\n * The messages are saved JSON-serialized.\n * You have to configure which key is used for storing the messages.\n *\n * A typical configuration could be:\n *\n * ```json\n * {\n * \"localStorageKey\": \"myLogs\",\n * \"maxMessages\": 500,\n * \"threshold\": \"INFO\"\n * }\n * ```\n */\nexport class LocalStorageAppender extends log4javascript.Appender {\n\n\tprivate static maxMessagesDefault = 250;\n\tprivate static thresholdDefault = \"WARN\";\n\n\tprivate maxMessages: number;\n\n\tprivate localStorageKey: string;\n\tprivate logMessages: LogMessage[];\n\n\t/**\n\t * Creates a new instance of the appender.\n\t *\n\t * @param configuration configuration for the appender.\n\t */\n\tconstructor(configuration: LocalStorageAppenderConfiguration) {\n\t\tsuper();\n\n\t\tif (!configuration) {\n\t\t\tthrow new Error(\"configuration must be not empty\");\n\t\t}\n\t\tif (!configuration.localStorageKey || configuration.localStorageKey === \"\") {\n\t\t\tthrow new Error(\"localStorageKey must be not empty\");\n\t\t}\n\t\tthis.localStorageKey = configuration.localStorageKey;\n\n\t\t// read existing logMessages\n\t\tthis.logMessages = LocalStorageAppender.loadLogMessages(this.localStorageKey);\n\n\t\t// process remaining configuration\n\t\tthis.configure({\n\t\t\tlocalStorageKey: configuration.localStorageKey,\n\t\t\tmaxMessages: configuration.maxMessages || LocalStorageAppender.maxMessagesDefault,\n\t\t\tthreshold: configuration.threshold || LocalStorageAppender.thresholdDefault,\n\t\t});\n\t}\n\n\t/**\n\t * Load log messages from local storage which are stored there under the given key.\n\t *\n\t * @param localStorageKey local storage key\n\t * @return stored messages\n\t */\n\tpublic static loadLogMessages(localStorageKey: string): LogMessage[] {\n\t\tlet logMessages: LogMessage[];\n\n\t\tif (!localStorageKey || localStorage.getItem(localStorageKey) === null) {\n\t\t\tlogMessages = [];\n\t\t} else {\n\t\t\tlogMessages = JSON.parse(localStorage.getItem(localStorageKey));\n\t\t\tfor (const logMessage of logMessages) {\n\t\t\t\t// timestamps are serialized as strings\n\t\t\t\tlogMessage.timeStamp = new Date(logMessage.timeStamp);\n\t\t\t}\n\t\t}\n\n\t\treturn logMessages;\n\t}\n\n\t/**\n\t * Remove log messages from local storage which are stored there under the given key.\n\t *\n\t * @param localStorageKey local storage key\n\t */\n\tpublic static removeLogMessages(localStorageKey: string): void {\n\t\tlocalStorage.removeItem(localStorageKey);\n\t}\n\n\t/**\n\t * Configures the logging depending on the given configuration.\n\t *\n\t * Only the defined properties get overwritten.\n\t * The localStorageKey cannot be modified.\n\t *\n\t * @param configuration configuration data.\n\t */\n\tpublic configure(configuration: LocalStorageAppenderConfiguration): void {\n\t\tif (configuration) {\n\t\t\tif (configuration.localStorageKey && configuration.localStorageKey !== this.localStorageKey) {\n\t\t\t\tthrow new Error(\"localStorageKey must not be changed\");\n\t\t\t}\n\t\t\tif (configuration.maxMessages) {\n\t\t\t\tthis.setMaxMessages(configuration.maxMessages);\n\t\t\t}\n\t\t\tif (configuration.threshold) {\n\t\t\t\tconst convertedThreshold = LogLevelConverter.levelToLog4Javascript(\n\t\t\t\t\tLogLevelConverter.levelFromString(configuration.threshold));\n\t\t\t\tthis.setThreshold(convertedThreshold);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Appender-specific method to append a log message.\n\t *\n\t * @param loggingEvent event to be appended.\n\t */\n\tpublic append(loggingEvent: log4javascript.LoggingEvent): void {\n\t\t// if logMessages is already full, remove oldest element\n\t\twhile (this.logMessages.length >= this.maxMessages) {\n\t\t\tthis.logMessages.shift();\n\t\t}\n\t\t// add event to logMessages\n\t\tconst message: LogMessage = {\n\t\t\tlevel: LogLevel[LogLevelConverter.levelFromLog4Javascript(loggingEvent.level)],\n\t\t\tlogger: typeof loggingEvent.logger !== \"undefined\" ? loggingEvent.logger.name : undefined,\n\t\t\tmessage: loggingEvent.messages.slice(1),\n\t\t\tmethodName: loggingEvent.messages[0],\n\t\t\ttimeStamp: loggingEvent.timeStamp,\n\t\t};\n\t\tthis.logMessages.push(message);\n\n\t\t// write values to localStorage\n\t\tlocalStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages));\n\t}\n\n\t/**\n\t * Gets the appender's name.\n\t * Mainly for unit testing purposes.\n\t *\n\t * @return appender's name\n\t */\n\tpublic toString(): string {\n\t\treturn \"Ionic.Logging.LocalStorageAppender\";\n\t}\n\n\t/**\n\t * Get the key which is used to store the messages in the local storage.\n\t */\n\tpublic getLocalStorageKey(): string {\n\t\treturn this.localStorageKey;\n\t}\n\n\t/**\n\t * Get the maximum number of messages which will be stored in local storage.\n\t */\n\tpublic getMaxMessages(): number {\n\t\treturn this.maxMessages;\n\t}\n\n\t/**\n\t * Set the maximum number of messages which will be stored in local storage.\n\t *\n\t * If the appender stores currently more messages than the new value allows, the oldest messages get removed.\n\t *\n\t * @param value new maximum number\n\t */\n\tpublic setMaxMessages(value: number): void {\n\t\tif (this.maxMessages !== value) {\n\t\t\tthis.maxMessages = value;\n\n\t\t\tif (this.logMessages.length > this.maxMessages) {\n\t\t\t\t// there are too much logMessages for the new value, therefore remove oldest messages\n\t\t\t\twhile (this.logMessages.length > this.maxMessages) {\n\t\t\t\t\tthis.logMessages.shift();\n\t\t\t\t}\n\n\t\t\t\t// write values to localStorage\n\t\t\t\tlocalStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets all messages stored in local storage.\n\t * Mainly for unit testing purposes.\n\t *\n\t * @return stored messages\n\t */\n\tpublic getLogMessages(): LogMessage[] {\n\t\treturn this.logMessages;\n\t}\n\n\t/**\n\t * Removes all messages from local storage.\n\t * Mainly for unit testing purposes.\n\t */\n\tpublic clearLog(): void {\n\t\tthis.logMessages = [];\n\t\tlocalStorage.removeItem(this.localStorageKey);\n\t}\n}\n","import * as log4javascript from \"log4javascript\";\n\nimport { LogLevelConverter } from \"./log-level.converter\";\nimport { LogLevel } from \"./log-level.model\";\n\n/**\n * Logger for writing log messages.\n */\nexport class Logger {\n\n\tprivate logger: log4javascript.Logger;\n\n\t/**\n\t * Creates a new instance of a logger.\n\t */\n\tconstructor(logger?: string | any) {\n\t\tif (typeof logger === \"undefined\") {\n\t\t\tthis.logger = log4javascript.getRootLogger();\n\t\t} else if (typeof logger === \"string\") {\n\t\t\tthis.logger = log4javascript.getLogger(logger);\n\t\t} else {\n\t\t\tthis.logger = logger;\n\t\t}\n\t}\n\n\t/**\n\t * Get the log level.\n\t */\n\tpublic getLogLevel(): LogLevel {\n\t\treturn LogLevelConverter.levelFromLog4Javascript(this.logger.getLevel());\n\t}\n\n\t/**\n\t * Set the log level.\n\t *\n\t * @param level the new log level\n\t */\n\tpublic setLogLevel(level: LogLevel): void {\n\t\tthis.logger.setLevel(LogLevelConverter.levelToLog4Javascript(level));\n\t}\n\n\t/**\n\t * Logs a message at level TRACE.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic trace(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isTraceEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.trace.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs a message at level DEBUG.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic debug(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isDebugEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.debug.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs a message at level INFO.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic info(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isInfoEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.info.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs a message at level WARN.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic warn(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isWarnEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.warn.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs a message at level ERROR.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic error(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isErrorEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.error.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs a message at level FATAL.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic fatal(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isFatalEnabled()) {\n\t\t\tconst args = [methodName];\n\t\t\tfor (const param of params) {\n\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t}\n\t\t\tthis.logger.fatal.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs the entry into a method.\n\t * The method name will be logged at level INFO, the parameters at level DEBUG.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic entry(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isInfoEnabled()) {\n\t\t\tconst args = [methodName, \"entry\"];\n\t\t\tif (this.logger.isDebugEnabled()) {\n\t\t\t\tfor (const param of params) {\n\t\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logger.info.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Logs the exit of a method.\n\t * The method name will be logged at level INFO, the parameters at level DEBUG.\n\t *\n\t * @param methodName name of the method\n\t * @param params optional parameters to be logged; objects will be formatted as JSON\n\t */\n\tpublic exit(methodName: string, ...params: any[]): void {\n\t\tif (this.logger.isInfoEnabled()) {\n\t\t\tconst args = [methodName, \"exit\"];\n\t\t\tif (this.logger.isDebugEnabled()) {\n\t\t\t\tfor (const param of params) {\n\t\t\t\t\targs.push(this.formatArgument(param));\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logger.info.apply(this.logger, args);\n\t\t}\n\t}\n\n\t/**\n\t * Formats the given argument.\n\t */\n\tpublic formatArgument(arg: any): string {\n\t\tif (typeof arg === \"string\") {\n\t\t\treturn arg;\n\t\t} else if (typeof arg === \"number\") {\n\t\t\treturn arg.toString();\n\t\t} else if (arg instanceof Error) {\n\t\t\t// JSON.stringify() returns here \"{ }\"\n\t\t\treturn arg.toString();\n\t\t} else {\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(arg);\n\t\t\t} catch (e) {\n\t\t\t\treturn e.message;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the internal Logger (for unit tests only).\n\t */\n\tpublic getInternalLogger(): log4javascript.Logger {\n\t\treturn this.logger;\n\t}\n}\n","import * as log4javascript from \"log4javascript\";\n\nimport { LogLevelConverter } from \"./log-level.converter\";\nimport { LogLevel } from \"./log-level.model\";\nimport { LogMessage } from \"./log-message.model\";\nimport { MemoryAppenderConfiguration } from \"./memory-appender.configuration\";\n\n/**\n * An appender which stores the log messages in the browser's memory.\n *\n * The MemoryAppender is enabled by default.\n * If you do not specify anything else, it is using this configuration:\n *\n * ```JSON\n * {\n * \"memoryAppender\": [\n * {\n * \"maxMessages\": 250,\n * \"threshold\": \"ALL\"\n * }\n * }\n * ```\n */\nexport class MemoryAppender extends log4javascript.Appender {\n\n\tprivate static maxMessagesDefault = 250;\n\tprivate static thresholdDefault = \"ALL\";\n\n\tprivate maxMessages: number;\n\n\tprivate logMessages: LogMessage[];\n\tprivate onLogMessagesChangedCallback: (message: LogMessage) => void;\n\n\t/**\n\t * Creates a new instance of the appender.\n\t *\n\t * @param configuration configuration for the appender.\n\t */\n\tconstructor(configuration?: MemoryAppenderConfiguration) {\n\t\tsuper();\n\n\t\tthis.logMessages = [];\n\n\t\t// process configuration\n\t\tconfiguration = configuration || {};\n\t\tthis.configure({\n\t\t\tmaxMessages: configuration.maxMessages || MemoryAppender.maxMessagesDefault,\n\t\t\tthreshold: configuration.threshold || MemoryAppender.thresholdDefault,\n\t\t});\n\n\t\tthis.maxMessages = MemoryAppender.maxMessagesDefault;\n\t}\n\n\t/**\n\t * Configures the logging depending on the given configuration.\n\t * Only the defined properties get overwritten.\n\t *\n\t * @param configuration configuration data.\n\t */\n\tpublic configure(configuration: MemoryAppenderConfiguration): void {\n\t\tif (configuration) {\n\t\t\tif (configuration.maxMessages) {\n\t\t\t\tthis.setMaxMessages(configuration.maxMessages);\n\t\t\t}\n\t\t\tif (configuration.threshold) {\n\t\t\t\tconst convertedThreshold = LogLevelConverter.levelToLog4Javascript(\n\t\t\t\t\tLogLevelConverter.levelFromString(configuration.threshold));\n\t\t\t\tthis.setThreshold(convertedThreshold);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Appender-specific method to append a log message.\n\t *\n\t * @param loggingEvent event to be appended.\n\t */\n\tpublic append(loggingEvent: log4javascript.LoggingEvent): void {\n\t\t// if logMessages is already full, remove oldest element\n\t\twhile (this.logMessages.length >= this.maxMessages) {\n\t\t\tthis.logMessages.shift();\n\t\t}\n\t\t// add event to logMessages\n\t\tconst message: LogMessage = {\n\t\t\tlevel: LogLevel[LogLevelConverter.levelFromLog4Javascript(loggingEvent.level)],\n\t\t\tlogger: typeof loggingEvent.logger === \"object\" ? loggingEvent.logger.name : undefined,\n\t\t\tmessage: loggingEvent.messages.slice(1),\n\t\t\tmethodName: loggingEvent.messages[0],\n\t\t\ttimeStamp: loggingEvent.timeStamp,\n\t\t};\n\t\tthis.logMessages.push(message);\n\n\t\t// inform about new message\n\t\tif (typeof this.onLogMessagesChangedCallback === \"function\") {\n\t\t\tthis.onLogMessagesChangedCallback(message);\n\t\t}\n\t}\n\n\t/**\n\t * Gets the appender's name.\n\t * Mainly for unit testing purposes.\n\t *\n\t * @return appender's name\n\t */\n\tpublic toString(): string {\n\t\treturn \"Ionic.Logging.MemoryAppender\";\n\t}\n\n\t/**\n\t * Get the maximum number of messages which will be stored in memory.\n\t */\n\tpublic getMaxMessages(): number {\n\t\treturn this.maxMessages;\n\t}\n\n\t/**\n\t * Set the maximum number of messages which will be stored in memory.\n\t *\n\t * If the appender stores currently more messages than the new value allows, the oldest messages get removed.\n\t *\n\t * @param value new maximum number\n\t */\n\tpublic setMaxMessages(value: number): void {\n\t\tthis.maxMessages = value;\n\n\t\t// if there are too much logMessages for the new value, remove oldest messages\n\t\tif (this.logMessages.length > this.maxMessages) {\n\t\t\tthis.logMessages.splice(0, this.logMessages.length - this.maxMessages);\n\t\t}\n\t}\n\n\t/**\n\t * Gets all messages stored in memory.\n\t *\n\t * @return stored messages\n\t */\n\tpublic getLogMessages(): LogMessage[] {\n\t\treturn this.logMessages;\n\t}\n\n\t/**\n\t * Remove all messages stored in memory.\n\t */\n\tpublic removeLogMessages(): void {\n\t\tthis.logMessages.splice(0);\n\t}\n\n\t/**\n\t * Registers a callback which will be called every time a new message is appended.\n\t * This could be useful if you want to show new messages in realtime.\n\t *\n\t * @param callback callback to be called\n\t */\n\tpublic setOnLogMessagesChangedCallback(callback: (message: LogMessage) => void): void {\n\t\tthis.onLogMessagesChangedCallback = callback;\n\t}\n}\n","import { EventEmitter, Injectable, Optional } from \"@angular/core\";\n\nimport * as log4javascript from \"log4javascript\";\n\nimport { AjaxAppender } from \"./ajax-appender.model\";\nimport { LocalStorageAppender } from \"./local-storage-appender.model\";\nimport { LogLevelConverter } from \"./log-level.converter\";\nimport { LogMessage } from \"./log-message.model\";\nimport { Logger } from \"./logger.model\";\nimport { LoggingServiceConfiguration } from \"./logging-service.configuration\";\nimport { MemoryAppender } from \"./memory-appender.model\";\n\n/**\n * Service for logging functionality.\n *\n * By default, the following settings are used:\n * - logger: root with level WARN\n * - appender: BrowserConsoleAppender with threshold DEBUG and MemoryAppender with threshold ALL\n *\n * Via [configure](#configure), it is possible to amend these settings.\n */\n@Injectable({\n\tprovidedIn: \"root\"\n})\nexport class LoggingService {\n\n\t/**\n\t * Event triggered when the log messages got (potentially) change.\n\t * This can happen when:\n\t * - new message was added\n\t * - all message where removed from memory\n\t * - all massages where removed for one spcific LocalStorageAppender\n\t */\n\tpublic logMessagesChanged: EventEmitter<void>;\n\n\t/**\n\t * Event triggered when ajax appender could not send log messages to the server.\n\t *\n\t * @param message error message\n\t */\n\tpublic ajaxAppenderFailed: EventEmitter<string>;\n\n\tprivate memoryAppender: MemoryAppender;\n\tprivate browserConsoleAppender: log4javascript.BrowserConsoleAppender;\n\n\t/**\n\t * Creates a new instance of the service.\n\t */\n\tconstructor() {\n\n\t\t// prevent log4javascript to show alerts on case of errors\n\t\tlog4javascript.logLog.setQuietMode(true);\n\n\t\t// create event emitter\n\t\tthis.logMessagesChanged = new EventEmitter<void>();\n\t\tthis.ajaxAppenderFailed = new EventEmitter<string>();\n\n\t\t// configure appender\n\t\tconst logger = log4javascript.getRootLogger();\n\t\tlogger.setLevel(log4javascript.Level.WARN);\n\n\t\t// browser console appender for debugger\n\t\tthis.browserConsoleAppender = new log4javascript.BrowserConsoleAppender();\n\t\tthis.browserConsoleAppender.setLayout(new log4javascript.PatternLayout(\"%d{HH:mm:ss,SSS} %c %m\"));\n\t\tthis.browserConsoleAppender.setThreshold(log4javascript.Level.ALL);\n\t\tlogger.addAppender(this.browserConsoleAppender);\n\n\t\t// in-memory appender for display on log messages page\n\t\tthis.memoryAppender = new MemoryAppender();\n\t\tthis.memoryAppender.setLayout(new log4javascript.PatternLayout(\"%d{HH:mm:ss,SSS} %c %m\"));\n\t\tthis.memoryAppender.setOnLogMessagesChangedCallback((message) => {\n\t\t\tthis.logMessagesChanged.emit();\n\t\t});\n\t\tlogger.addAppender(this.memoryAppender);\n\n\t\tthis.configure();\n\t}\n\n\t/**\n\t * Configures the logging depending on the given configuration.\n\t *\n\t * @param configuration configuration data.\n\t */\n\tpublic configure(configuration?: LoggingServiceConfiguration): void {\n\n\t\tif (typeof configuration === \"undefined\") {\n\t\t\tconfiguration = {};\n\t\t}\n\n\t\t// set log levels\n\t\tif (typeof configuration.logLevels !== \"undefined\") {\n\t\t\tfor (const level of configuration.logLevels) {\n\t\t\t\tlet logger: log4javascript.Logger;\n\t\t\t\tif (level.loggerName === \"root\") {\n\t\t\t\t\tlogger = log4javascript.getRootLogger();\n\t\t\t\t} else {\n\t\t\t\t\tlogger = log4javascript.getLogger(level.loggerName);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tlogger.setLevel(LogLevelConverter.levelToLog4Javascript(LogLevelConverter.levelFromString(level.logLevel)));\n\t\t\t\t} catch (e) {\n\t\t\t\t\tthrow new Error(`invalid log level ${level.logLevel}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// configure AjaxAppender\n\t\tif (typeof configuration.ajaxAppender !== \"undefined\") {\n\t\t\tconst ajaxAppender = new AjaxAppender(configuration.ajaxAppender);\n\t\t\tajaxAppender.appenderFailed.subscribe((message: string) => {\n\t\t\t\tthis.ajaxAppenderFailed.emit(message);\n\t\t\t});\n\t\t\tlog4javascript.getRootLogger().addAppender(ajaxAppender);\n\t\t}\n\n\t\t// configure LocalStorageAppender\n\t\tif (typeof configuration.localStorageAppender !== \"undefined\") {\n\t\t\tconst localStorageAppender = new LocalStorageAppender(configuration.localStorageAppender);\n\t\t\tlog4javascript.getRootLogger().addAppender(localStorageAppender);\n\n\t\t\t// ensure that an eventual memoryAppender is behind the localStorageAppender\n\t\t\tconst appenders = new Logger().getInternalLogger().getEffectiveAppenders();\n\t\t\tconst memoryAppender = appenders.find((a) => a.toString() === \"Ionic.Logging.MemoryAppender\") as MemoryAppender;\n\t\t\tif (memoryAppender) {\n\t\t\t\tlog4javascript.getRootLogger().removeAppender(memoryAppender);\n\t\t\t\tlog4javascript.getRootLogger().addAppender(memoryAppender);\n\t\t\t}\n\t\t}\n\n\t\t// configure MemoryAppender\n\t\tif (configuration.memoryAppender) {\n\t\t\tthis.memoryAppender.configure(configuration.memoryAppender);\n\t\t}\n\n\t\t// configure BrowserConsoleAppender\n\t\tif (configuration.browserConsoleAppender) {\n\t\t\tif (configuration.browserConsoleAppender.threshold) {\n\t\t\t\tconst convertedThreshold = LogLevelConverter.levelToLog4Javascript(\n\t\t\t\t\tLogLevelConverter.levelFromString(configuration.browserConsoleAppender.threshold));\n\t\t\t\tthis.browserConsoleAppender.setThreshold(convertedThreshold);\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Gets the root logger from which all other loggers derive.\n\t *\n\t * @return root logger\n\t */\n\tpublic getRootLogger(): Logger {\n\t\treturn new Logger();\n\t}\n\n\t/**\n\t * Gets a logger with the specified name, creating it if a logger with that name does not already exist.\n\t *\n\t * @param loggerName name of the logger\n\t * @return logger\n\t */\n\tpublic getLogger(loggerName: string): Logger {\n\t\treturn new Logger(loggerName);\n\t}\n\n\t/**\n\t * Gets the last log messages.\n\t *\n\t * The log messages are retrieved from the internal [MemoryAppender](../memoryappender.html).\n\t * That means you will get only the most current messages. The number of the messages is limited\n\t * by its maxMessages value.\n\t *\n\t * @return log messages\n\t */\n\tpublic getLogMessages(): LogMessage[] {\n\t\treturn this.memoryAppender.getLogMessages();\n\t}\n\n\t/**\n\t * Loads the log messages written by the LocalStorageAppender with the given key.\n\t *\n\t * @param localStorageKey key for the local storage\n\t * @returns log messages\n\t */\n\tpublic getLogMessagesFromLocalStorage(localStorageKey: string): LogMessage[] {\n\t\treturn LocalStorageAppender.loadLogMessages(localStorageKey);\n\t}\n\n\t/**\n\t * Remove all log messages.\n\t */\n\tpublic removeLogMessages(): void {\n\t\tthis.memoryAppender.removeLogMessages();\n\t\tthis.logMessagesChanged.emit();\n\t}\n\n\t/**\n\t * Removes the log messages written by the LocalStorageAppender with the given key.\n\t *\n\t * @param localStorageKey key for the local storage\n\t */\n\tpublic removeLogMessagesFromLocalStorage(localStorageKey: string): void {\n\t\tLocalStorageAppender.removeLogMessages(localStorageKey);\n\t\tthis.logMessagesChanged.emit();\n\t}\n}\n","import { NgModule } from \"@angular/core\";\n\n@NgModule({\n\timports: [\n\t],\n\tdeclarations: [\n\t],\n\texports: [\n\t]\n})\nexport class LoggingServiceModule { }\n","/*\n * Public API Surface of ionic-logging-service.\n */\n\nexport * from \"./lib/ajax-appender.configuration\";\nexport * from \"./lib/ajax-appender.model\";\nexport * from \"./lib/browser-console-appender.configuration\";\nexport * from \"./lib/local-storage-appender.configuration\";\nexport * from \"./lib/local-storage-appender.model\";\nexport * from \"./lib/log-level.converter\";\nexport * from \"./lib/log-level.model\";\nexport * from \"./lib/log-message.model\";\nexport * from \"./lib/logger.model\";\nexport * from \"./lib/logging.service\";\nexport * from \"./lib/logging-service.configuration\";\nexport * from \"./lib/logging-service.module\";\nexport * from \"./lib/memory-appender.configuration\";\nexport * from \"./lib/memory-appender.model\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;AACU,MAAA,UAAW,SAAQ,cAAc,CAAC,UAAU,CAAA;AAExD;;AAEG;AACI,IAAA,MAAM,CAAC,YAA0B,EAAA;AACvC,QAAA,MAAM,QAAQ,GAAG;AAChB,YAAA,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI;YAChC,SAAS,EAAE,YAAY,CAAC,uBAAuB;AAC/C,YAAA,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,QAAQ,EAAE;AACpC,YAAA,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;AACzB,YAAA,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,GAAG,YAAY,CAAC,mBAAmB,EAAE,GAAG,YAAY,CAAC,QAAQ;SAC/F,CAAC;AACF,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;KAChC;AAED;;;;;AAKG;IACI,QAAQ,GAAA;AACd,QAAA,OAAO,0BAA0B,CAAC;KAClC;AACD;;ACjCD;;AAEG;IACS,SAgDX;AAhDD,CAAA,UAAY,QAAQ,EAAA;AACnB;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAG,CAAA;AAEH;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAK,CAAA;AAEL;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAK,CAAA;AAEL;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAI,CAAA;AAEJ;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAI,CAAA;AAEJ;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAK,CAAA;AAEL;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAK,CAAA;AAEL;;AAEG;;AAEH,IAAA,QAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA,KAAG,CAAA;AACJ,CAAC,EAhDW,QAAQ,KAAR,QAAQ,GAgDnB,EAAA,CAAA,CAAA;;AC/CD;;AAEG;MACU,iBAAiB,CAAA;AAE7B;;;;;AAKG;IACI,OAAO,uBAAuB,CAAC,KAA2B,EAAA;QAChE,QAAQ,KAAK;AACZ,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,GAAG;gBAC5B,OAAO,QAAQ,CAAC,GAAG,CAAC;AACrB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,KAAK;gBAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,KAAK;gBAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,KAAK;gBAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,IAAI;gBAC7B,OAAO,QAAQ,CAAC,IAAI,CAAC;AACtB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,GAAG;gBAC5B,OAAO,QAAQ,CAAC,GAAG,CAAC;AACrB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,KAAK;gBAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,cAAc,CAAC,KAAK,CAAC,IAAI;gBAC7B,OAAO,QAAQ,CAAC,IAAI,CAAC;AACtB,YAAA;AACC,gBAAA,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAA,CAAE,CAAC,CAAC;SAC3C;KACD;AAED;;;;;AAKG;IACI,OAAO,eAAe,CAAC,KAAa,EAAA;QAC1C,QAAQ,KAAK;AACZ,YAAA,KAAK,KAAK;gBACT,OAAO,QAAQ,CAAC,GAAG,CAAC;AACrB,YAAA,KAAK,OAAO;gBACX,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,OAAO;gBACX,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,OAAO;gBACX,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,MAAM;gBACV,OAAO,QAAQ,CAAC,IAAI,CAAC;AACtB,YAAA,KAAK,KAAK;gBACT,OAAO,QAAQ,CAAC,GAAG,CAAC;AACrB,YAAA,KAAK,OAAO;gBACX,OAAO,QAAQ,CAAC,KAAK,CAAC;AACvB,YAAA,KAAK,MAAM;gBACV,OAAO,QAAQ,CAAC,IAAI,CAAC;AACtB,YAAA;AACC,gBAAA,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAA,CAAE,CAAC,CAAC;SAC3C;KACD;AAED;;;;;AAKG;IACI,OAAO,qBAAqB,CAAC,KAAe,EAAA;QAClD,QAAQ,KAAK;YACZ,KAAK,QAAQ,CAAC,GAAG;AAChB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;YACjC,KAAK,QAAQ,CAAC,KAAK;AAClB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YACnC,KAAK,QAAQ,CAAC,KAAK;AAClB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YACnC,KAAK,QAAQ,CAAC,KAAK;AAClB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YACnC,KAAK,QAAQ,CAAC,IAAI;AACjB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;YAClC,KAAK,QAAQ,CAAC,GAAG;AAChB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;YACjC,KAAK,QAAQ,CAAC,KAAK;AAClB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YACnC,KAAK,QAAQ,CAAC,IAAI;AACjB,gBAAA,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;AAClC,YAAA;AACC,gBAAA,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAA,CAAE,CAAC,CAAC;SAC3C;KACD;AACD;;ACvFD;;;;;;;;;;;;;AAaG;AACU,MAAA,YAAa,SAAQ,cAAc,CAAC,QAAQ,CAAA;aAEzC,IAAgB,CAAA,gBAAA,GAAG,CAAC,CAAC,EAAA;aACrB,IAAoB,CAAA,oBAAA,GAAG,CAAC,CAAC,EAAA;aACzB,IAAgB,CAAA,gBAAA,GAAG,MAAM,CAAC,EAAA;AAazC;;;;AAIG;AACH,IAAA,WAAA,CAAY,aAAwC,EAAA;AACnD,QAAA,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,aAAa,EAAE;AACnB,YAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACnD;AACD,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE;AACvB,YAAA,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;SACzC;AACD,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;AACtG,QAAA,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;AAC7B,QAAA,IAAI,CAAC,eAAe,GAAG,aAAa,CAAC,eAAe,CAAC;AAErD,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAC;AAC/E,QAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAE3C,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI,YAAY,EAAU,CAAC;QACjD,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,OAAY,KAAI;AAClD,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACnC,SAAC,CAAC,CAAC;;QAGH,IAAI,CAAC,SAAS,CAAC;AACd,YAAA,SAAS,EAAE,aAAa,CAAC,SAAS,IAAI,YAAY,CAAC,gBAAgB;AACnE,YAAA,SAAS,EAAE,aAAa,CAAC,SAAS,IAAI,YAAY,CAAC,gBAAgB;AACnE,YAAA,aAAa,EAAE,aAAa,CAAC,aAAa,IAAI,YAAY,CAAC,oBAAoB;YAC/E,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,eAAe,EAAE,aAAa,CAAC,eAAe;AAC9C,SAAA,CAAC,CAAC;KAEH;AAED;;;;;;;AAOG;AACI,IAAA,SAAS,CAAC,aAAwC,EAAA;QACxD,IAAI,aAAa,EAAE;AAClB,YAAA,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,EAAE;AACxD,gBAAA,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;aAC3C;AACD,YAAA,IAAI,aAAa,CAAC,eAAe,IAAI,aAAa,CAAC,eAAe,KAAK,IAAI,CAAC,eAAe,EAAE;AAC5F,gBAAA,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;aACvD;AACD,YAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC5B,gBAAA,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;aAC3C;AACD,YAAA,IAAI,OAAO,aAAa,CAAC,aAAa,KAAK,QAAQ,EAAE;AACpD,gBAAA,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;aACnD;AACD,YAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,qBAAqB,CACjE,iBAAiB,CAAC,eAAe,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;AAC7D,gBAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;aACtC;SACD;KACD;AAED;;;;AAIG;AACI,IAAA,MAAM,CAAC,YAAyC,EAAA;AACtD,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;KACvC;AAED;;;;;AAKG;IACI,QAAQ,GAAA;AACd,QAAA,OAAO,4BAA4B,CAAC;KACpC;AAED;;;AAGG;IACI,mBAAmB,GAAA;QACzB,OAAO,IAAI,CAAC,YAAY,CAAC;KACzB;AAED;;AAEG;IACI,YAAY,GAAA;AAClB,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;KACxC;AAED;;;;AAIG;AACI,IAAA,YAAY,CAAC,SAAiB,EAAA;AACpC,QAAA,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;KAC1C;AAED;;AAEG;IACI,SAAS,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;KACrC;AAED;;AAEG;AACI,IAAA,SAAS,CAAC,MAA6B,EAAA;AAC7C,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;KACpC;AAED;;AAEG;IACI,gBAAgB,GAAA;AACtB,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAC;KAC5C;AAED;;;;AAIG;AACI,IAAA,gBAAgB,CAAC,aAAqB,EAAA;QAC5C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;KAClD;;;AC5KF;;;;;;;;;;;;;;;AAeG;AACU,MAAA,oBAAqB,SAAQ,cAAc,CAAC,QAAQ,CAAA;aAEjD,IAAkB,CAAA,kBAAA,GAAG,GAAG,CAAC,EAAA;aACzB,IAAgB,CAAA,gBAAA,GAAG,MAAM,CAAC,EAAA;AAOzC;;;;AAIG;AACH,IAAA,WAAA,CAAY,aAAgD,EAAA;AAC3D,QAAA,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,aAAa,EAAE;AACnB,YAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACnD;QACD,IAAI,CAAC,aAAa,CAAC,eAAe,IAAI,aAAa,CAAC,eAAe,KAAK,EAAE,EAAE;AAC3E,YAAA,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;SACrD;AACD,QAAA,IAAI,CAAC,eAAe,GAAG,aAAa,CAAC,eAAe,CAAC;;QAGrD,IAAI,CAAC,WAAW,GAAG,oBAAoB,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;;QAG9E,IAAI,CAAC,SAAS,CAAC;YACd,eAAe,EAAE,aAAa,CAAC,eAAe;AAC9C,YAAA,WAAW,EAAE,aAAa,CAAC,WAAW,IAAI,oBAAoB,CAAC,kBAAkB;AACjF,YAAA,SAAS,EAAE,aAAa,CAAC,SAAS,IAAI,oBAAoB,CAAC,gBAAgB;AAC3E,SAAA,CAAC,CAAC;KACH;AAED;;;;;AAKG;IACI,OAAO,eAAe,CAAC,eAAuB,EAAA;AACpD,QAAA,IAAI,WAAyB,CAAC;AAE9B,QAAA,IAAI,CAAC,eAAe,IAAI,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;YACvE,WAAW,GAAG,EAAE,CAAC;SACjB;aAAM;AACN,YAAA,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;AAChE,YAAA,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;;gBAErC,UAAU,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;aACtD;SACD;AAED,QAAA,OAAO,WAAW,CAAC;KACnB;AAED;;;;AAIG;IACI,OAAO,iBAAiB,CAAC,eAAuB,EAAA;AACtD,QAAA,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;KACzC;AAED;;;;;;;AAOG;AACI,IAAA,SAAS,CAAC,aAAgD,EAAA;QAChE,IAAI,aAAa,EAAE;AAClB,YAAA,IAAI,aAAa,CAAC,eAAe,IAAI,aAAa,CAAC,eAAe,KAAK,IAAI,CAAC,eAAe,EAAE;AAC5F,gBAAA,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;aACvD;AACD,YAAA,IAAI,aAAa,CAAC,WAAW,EAAE;AAC9B,gBAAA,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;aAC/C;AACD,YAAA,IAAI,aAAa,CAAC,SAAS,EAAE;AAC5B,gBAAA,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,qBAAqB,CACjE,iBAAiB,CAAC,eAAe,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;AAC7D,gBAAA,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;aACtC;SACD;KACD;AAED;;;;AAIG;AACI,IAAA,MAAM,CAAC,YAAyC,EAAA;;QAEtD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;AACnD,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;SACzB;;AAED,QAAA,MAAM,OAAO,GAAe;YAC3B,KAAK,EAAE,QAAQ,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AAC9E,YAAA,MAAM,EAAE,OAAO,YAAY,CAAC,MAAM,KAAK,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,GAAG,SAAS;YACzF,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,YAAA,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;YACpC,SAAS,EAAE,YAAY,CAAC,SAAS;SACjC,CAAC;AACF,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;AAG/B,QAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;KAC7E;AAED;;;;;AAKG;IACI,QAAQ,GAAA;AACd,QAAA,OAAO,oCAAoC,CAAC;KAC5C;AAED;;AAEG;IACI,kBAAkB,GAAA;QACxB,OAAO,IAAI,CAAC,eAAe,CAAC;KAC5B;AAED;;AAEG;IACI,cAAc,GAAA;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;KACxB;AAED;;;;;;AAMG;AACI,IAAA,cAAc,CAAC,KAAa,EAAA;AAClC,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK,EAAE;AAC/B,YAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAEzB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;;gBAE/C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE;AAClD,oBAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;iBACzB;;AAGD,gBAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;aAC7E;SACD;KACD;AAED;;;;;AAKG;IACI,cAAc,GAAA;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;KACxB;AAED;;;AAGG;IACI,QAAQ,GAAA;AACd,QAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;AACtB,QAAA,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;KAC9C;;;ACtMF;;AAEG;MACU,MAAM,CAAA;AAIlB;;AAEG;AACH,IAAA,WAAA,CAAY,MAAqB,EAAA;AAChC,QAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AAClC,YAAA,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC;SAC7C;AAAM,aAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YACtC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;SAC/C;aAAM;AACN,YAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;SACrB;KACD;AAED;;AAEG;IACI,WAAW,GAAA;QACjB,OAAO,iBAAiB,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;KACzE;AAED;;;;AAIG;AACI,IAAA,WAAW,CAAC,KAAe,EAAA;AACjC,QAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;KACrE;AAED;;;;;AAKG;AACI,IAAA,KAAK,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC3C;KACD;AAED;;;;;AAKG;AACI,IAAA,KAAK,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC3C;KACD;AAED;;;;;AAKG;AACI,IAAA,IAAI,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAC/C,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE;AAChC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC1C;KACD;AAED;;;;;AAKG;AACI,IAAA,IAAI,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAC/C,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE;AAChC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC1C;KACD;AAED;;;;;AAKG;AACI,IAAA,KAAK,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC3C;KACD;AAED;;;;;AAKG;AACI,IAAA,KAAK,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;aACtC;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC3C;KACD;AAED;;;;;;AAMG;AACI,IAAA,KAAK,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAChD,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE;AAChC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACnC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,gBAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;oBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;iBACtC;aACD;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC1C;KACD;AAED;;;;;;AAMG;AACI,IAAA,IAAI,CAAC,UAAkB,EAAE,GAAG,MAAa,EAAA;AAC/C,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE;AAChC,YAAA,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAClC,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE;AACjC,gBAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;oBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;iBACtC;aACD;AACD,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;SAC1C;KACD;AAED;;AAEG;AACI,IAAA,cAAc,CAAC,GAAQ,EAAA;AAC7B,QAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC5B,YAAA,OAAO,GAAG,CAAC;SACX;AAAM,aAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AACnC,YAAA,OAAO,G