@wener/common 2.0.2 → 2.0.5
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.
- package/lib/ai/qwen3vl/index.js +2 -0
- package/lib/ai/qwen3vl/index.js.map +1 -0
- package/lib/ai/qwen3vl/utils.js +31 -0
- package/lib/ai/qwen3vl/utils.js.map +1 -0
- package/lib/ai/vision/DocLayoutElementTypeSchema.js +28 -0
- package/lib/ai/vision/DocLayoutElementTypeSchema.js.map +1 -0
- package/lib/ai/vision/ImageAnnotationSchema.js +50 -0
- package/lib/ai/vision/ImageAnnotationSchema.js.map +1 -0
- package/lib/ai/vision/index.js +3 -0
- package/lib/ai/vision/index.js.map +1 -0
- package/lib/ai/vision/resolveImageAnnotation.js +105 -0
- package/lib/ai/vision/resolveImageAnnotation.js.map +1 -0
- package/lib/cn/ChineseResidentIdNo.js +22 -15
- package/lib/cn/ChineseResidentIdNo.js.map +1 -0
- package/lib/cn/ChineseResidentIdNo.test.js +1 -1
- package/lib/cn/DivisionCode.js +30 -25
- package/lib/cn/DivisionCode.js.map +1 -0
- package/lib/cn/DivisionCode.test.js +1 -1
- package/lib/cn/Mod11.js +38 -81
- package/lib/cn/Mod11.js.map +1 -0
- package/lib/cn/Mod31.js +41 -90
- package/lib/cn/Mod31.js.map +1 -0
- package/lib/cn/UnifiedSocialCreditCode.js +43 -34
- package/lib/cn/UnifiedSocialCreditCode.js.map +1 -0
- package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
- package/lib/cn/formatChineseAmount.js +77 -0
- package/lib/cn/formatChineseAmount.js.map +1 -0
- package/lib/cn/index.js +7 -1
- package/lib/cn/index.js.map +1 -0
- package/lib/cn/parseChineseNumber.js +94 -0
- package/lib/cn/parseChineseNumber.js.map +1 -0
- package/lib/cn/parseChineseNumber.test.js +278 -0
- package/lib/cn/pinyin/cartesianProduct.js +22 -0
- package/lib/cn/pinyin/cartesianProduct.js.map +1 -0
- package/lib/cn/pinyin/cartesianProduct.test.js +179 -0
- package/lib/cn/pinyin/data.json +23573 -0
- package/lib/cn/pinyin/loader.js +14 -0
- package/lib/cn/pinyin/loader.js.map +1 -0
- package/lib/cn/pinyin/preload.js +3 -0
- package/lib/cn/pinyin/preload.js.map +1 -0
- package/lib/cn/pinyin/toPinyin.test.js +167 -0
- package/lib/cn/pinyin/toPinyinPure.js +33 -0
- package/lib/cn/pinyin/toPinyinPure.js.map +1 -0
- package/lib/cn/pinyin/transform.js +14 -0
- package/lib/cn/pinyin/transform.js.map +1 -0
- package/lib/cn/types.d.js +2 -0
- package/lib/cn/types.d.js.map +1 -0
- package/lib/consola/createStandardConsolaReporter.js +6 -6
- package/lib/consola/createStandardConsolaReporter.js.map +1 -0
- package/lib/consola/formatLogObject.js +66 -146
- package/lib/consola/formatLogObject.js.map +1 -0
- package/lib/consola/formatLogObject.test.js +184 -0
- package/lib/consola/index.js +1 -0
- package/lib/consola/index.js.map +1 -0
- package/lib/data/formatSort.js +6 -5
- package/lib/data/formatSort.js.map +1 -0
- package/lib/data/index.js +1 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/maybeNumber.js +6 -8
- package/lib/data/maybeNumber.js.map +1 -0
- package/lib/data/parseSort.js +22 -28
- package/lib/data/parseSort.js.map +1 -0
- package/lib/data/resolvePagination.js +13 -17
- package/lib/data/resolvePagination.js.map +1 -0
- package/lib/data/types.d.js +2 -0
- package/lib/data/types.d.js.map +1 -0
- package/lib/dayjs/dayjs.js +21 -19
- package/lib/dayjs/dayjs.js.map +1 -0
- package/lib/dayjs/formatDuration.js +15 -14
- package/lib/dayjs/formatDuration.js.map +1 -0
- package/lib/dayjs/index.js +2 -0
- package/lib/dayjs/index.js.map +1 -0
- package/lib/dayjs/parseDuration.js +5 -8
- package/lib/dayjs/parseDuration.js.map +1 -0
- package/lib/dayjs/parseRelativeTime.js +90 -0
- package/lib/dayjs/parseRelativeTime.js.map +1 -0
- package/lib/dayjs/parseRelativeTime.test.js +247 -0
- package/lib/dayjs/resolveRelativeTime.js +87 -0
- package/lib/dayjs/resolveRelativeTime.js.map +1 -0
- package/lib/dayjs/resolveRelativeTime.test.js +310 -0
- package/lib/decimal/index.js +1 -0
- package/lib/decimal/index.js.map +1 -0
- package/lib/decimal/parseDecimal.js +3 -1
- package/lib/decimal/parseDecimal.js.map +1 -0
- package/lib/drain3/Drain.js +356 -0
- package/lib/drain3/Drain.js.map +1 -0
- package/lib/drain3/LogCluster.js +38 -0
- package/lib/drain3/LogCluster.js.map +1 -0
- package/lib/drain3/Node.js +39 -0
- package/lib/drain3/Node.js.map +1 -0
- package/lib/drain3/TemplateMiner.js +204 -0
- package/lib/drain3/TemplateMiner.js.map +1 -0
- package/lib/drain3/index.js +31 -0
- package/lib/drain3/index.js.map +1 -0
- package/lib/drain3/persistence/FilePersistence.js +24 -0
- package/lib/drain3/persistence/FilePersistence.js.map +1 -0
- package/lib/drain3/persistence/MemoryPersistence.js +18 -0
- package/lib/drain3/persistence/MemoryPersistence.js.map +1 -0
- package/lib/drain3/persistence/PersistenceHandler.js +5 -0
- package/lib/drain3/persistence/PersistenceHandler.js.map +1 -0
- package/lib/drain3/types.js +7 -0
- package/lib/drain3/types.js.map +1 -0
- package/lib/emittery/emitter.js +10 -0
- package/lib/emittery/emitter.js.map +1 -0
- package/lib/emittery/index.js +2 -0
- package/lib/emittery/index.js.map +1 -0
- package/lib/foundation/schema/SexType.js +5 -3
- package/lib/foundation/schema/SexType.js.map +1 -0
- package/lib/foundation/schema/index.js +1 -0
- package/lib/foundation/schema/index.js.map +1 -0
- package/lib/foundation/schema/parseSexType.js +1 -0
- package/lib/foundation/schema/parseSexType.js.map +1 -0
- package/lib/foundation/schema/types.js +4 -2
- package/lib/foundation/schema/types.js.map +1 -0
- package/lib/fs/FileSystemError.js +23 -0
- package/lib/fs/FileSystemError.js.map +1 -0
- package/lib/fs/IFileSystem.d.js +3 -0
- package/lib/fs/IFileSystem.d.js.map +1 -0
- package/lib/fs/MemoryFileSystem.test.js +188 -0
- package/lib/fs/createBrowserFileSystem.js +250 -0
- package/lib/fs/createBrowserFileSystem.js.map +1 -0
- package/lib/fs/createMemoryFileSystem.js +517 -0
- package/lib/fs/createMemoryFileSystem.js.map +1 -0
- package/lib/fs/createSandboxFileSystem.js +108 -0
- package/lib/fs/createSandboxFileSystem.js.map +1 -0
- package/lib/fs/createWebDavFileSystem.js +154 -0
- package/lib/fs/createWebDavFileSystem.js.map +1 -0
- package/lib/fs/createWebFileSystem.js +225 -0
- package/lib/fs/createWebFileSystem.js.map +1 -0
- package/lib/fs/findMimeType.js +17 -0
- package/lib/fs/findMimeType.js.map +1 -0
- package/lib/fs/index.js +8 -0
- package/lib/fs/index.js.map +1 -0
- package/lib/fs/minio/createMinioFileSystem.js +974 -0
- package/lib/fs/minio/createMinioFileSystem.js.map +1 -0
- package/lib/fs/minio/index.js +2 -0
- package/lib/fs/minio/index.js.map +1 -0
- package/lib/fs/orpc/FileSystemContract.js +93 -0
- package/lib/fs/orpc/FileSystemContract.js.map +1 -0
- package/lib/fs/orpc/createContractClientFileSystem.js +93 -0
- package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -0
- package/lib/fs/orpc/index.js +3 -0
- package/lib/fs/orpc/index.js.map +1 -0
- package/lib/fs/orpc/server/createFileSystemContractImpl.js +63 -0
- package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -0
- package/lib/fs/orpc/server/index.js +2 -0
- package/lib/fs/orpc/server/index.js.map +1 -0
- package/lib/fs/s3/createS3MiniFileSystem.js +753 -0
- package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -0
- package/lib/fs/s3/index.js +2 -0
- package/lib/fs/s3/index.js.map +1 -0
- package/lib/fs/s3/s3mini.test.js +584 -0
- package/lib/fs/scandir.js +59 -0
- package/lib/fs/scandir.js.map +1 -0
- package/lib/fs/server/createDatabaseFileSystem.js +750 -0
- package/lib/fs/server/createDatabaseFileSystem.js.map +1 -0
- package/lib/fs/server/createNodeFileSystem.js +426 -0
- package/lib/fs/server/createNodeFileSystem.js.map +1 -0
- package/lib/fs/server/dbfs.test.js +221 -0
- package/lib/fs/server/index.js +2 -0
- package/lib/fs/server/index.js.map +1 -0
- package/lib/fs/server/loadTestDatabase.js +127 -0
- package/lib/fs/server/loadTestDatabase.js.map +1 -0
- package/lib/fs/tests/runFileSystemTest.js +319 -0
- package/lib/fs/tests/runFileSystemTest.js.map +1 -0
- package/lib/fs/types.js +27 -0
- package/lib/fs/types.js.map +1 -0
- package/lib/fs/utils/getFileUrl.js +35 -0
- package/lib/fs/utils/getFileUrl.js.map +1 -0
- package/lib/fs/utils.js +22 -0
- package/lib/fs/utils.js.map +1 -0
- package/lib/fs/webdav/index.js +2 -0
- package/lib/fs/webdav/index.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/jsonschema/JsonSchema.js +146 -172
- package/lib/jsonschema/JsonSchema.js.map +1 -0
- package/lib/jsonschema/forEachJsonSchema.js +44 -0
- package/lib/jsonschema/forEachJsonSchema.js.map +1 -0
- package/lib/jsonschema/index.js +2 -0
- package/lib/jsonschema/index.js.map +1 -0
- package/lib/jsonschema/types.d.js +2 -0
- package/lib/jsonschema/types.d.js.map +1 -0
- package/lib/meta/defineFileType.js +20 -103
- package/lib/meta/defineFileType.js.map +1 -0
- package/lib/meta/defineInit.js +31 -250
- package/lib/meta/defineInit.js.map +1 -0
- package/lib/meta/defineMetadata.js +24 -140
- package/lib/meta/defineMetadata.js.map +1 -0
- package/lib/meta/index.js +1 -0
- package/lib/meta/index.js.map +1 -0
- package/lib/orpc/createOpenApiContractClient.js +27 -0
- package/lib/orpc/createOpenApiContractClient.js.map +1 -0
- package/lib/orpc/createRpcContractClient.js +34 -0
- package/lib/orpc/createRpcContractClient.js.map +1 -0
- package/lib/orpc/index.js +3 -0
- package/lib/orpc/index.js.map +1 -0
- package/lib/orpc/resolveLinkPlugins.js +28 -0
- package/lib/orpc/resolveLinkPlugins.js.map +1 -0
- package/lib/password/PHC.js +63 -87
- package/lib/password/PHC.js.map +1 -0
- package/lib/password/PHC.test.js +11 -3
- package/lib/password/Password.js +29 -294
- package/lib/password/Password.js.map +1 -0
- package/lib/password/Password.test.js +35 -22
- package/lib/password/createArgon2PasswordAlgorithm.js +35 -191
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -0
- package/lib/password/createBase64PasswordAlgorithm.js +8 -141
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -0
- package/lib/password/createBcryptPasswordAlgorithm.js +13 -168
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -0
- package/lib/password/createPBKDF2PasswordAlgorithm.js +46 -228
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -0
- package/lib/password/createScryptPasswordAlgorithm.js +55 -211
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -0
- package/lib/password/index.js +1 -0
- package/lib/password/index.js.map +1 -0
- package/lib/password/server/index.js +1 -0
- package/lib/password/server/index.js.map +1 -0
- package/lib/resource/Identifiable.js +2 -0
- package/lib/resource/Identifiable.js.map +1 -0
- package/lib/resource/ListQuery.js +21 -93
- package/lib/resource/ListQuery.js.map +1 -0
- package/lib/resource/getTitleOfResource.js +3 -5
- package/lib/resource/getTitleOfResource.js.map +1 -0
- package/lib/resource/index.js +1 -0
- package/lib/resource/index.js.map +1 -0
- package/lib/resource/schema/AnyResourceSchema.js +2 -1
- package/lib/resource/schema/AnyResourceSchema.js.map +1 -0
- package/lib/resource/schema/BaseResourceSchema.js +2 -1
- package/lib/resource/schema/BaseResourceSchema.js.map +1 -0
- package/lib/resource/schema/ResourceActionType.js +6 -4
- package/lib/resource/schema/ResourceActionType.js.map +1 -0
- package/lib/resource/schema/ResourceStatus.js +5 -3
- package/lib/resource/schema/ResourceStatus.js.map +1 -0
- package/lib/resource/schema/ResourceType.js +5 -3
- package/lib/resource/schema/ResourceType.js.map +1 -0
- package/lib/resource/schema/index.js +1 -0
- package/lib/resource/schema/index.js.map +1 -0
- package/lib/resource/schema/types.js +16 -20
- package/lib/resource/schema/types.js.map +1 -0
- package/lib/s3/formatS3Url.js +65 -0
- package/lib/s3/formatS3Url.js.map +1 -0
- package/lib/s3/formatS3Url.test.js +262 -0
- package/lib/s3/index.js +3 -0
- package/lib/s3/index.js.map +1 -0
- package/lib/s3/parseS3Url.js +65 -0
- package/lib/s3/parseS3Url.js.map +1 -0
- package/lib/s3/parseS3Url.test.js +270 -0
- package/lib/schema/SchemaRegistry.js +38 -38
- package/lib/schema/SchemaRegistry.js.map +1 -0
- package/lib/schema/TypeSchema.d.js +2 -0
- package/lib/schema/TypeSchema.d.js.map +1 -0
- package/lib/schema/createSchemaData.js +26 -125
- package/lib/schema/createSchemaData.js.map +1 -0
- package/lib/schema/findJsonSchemaByPath.js +13 -36
- package/lib/schema/findJsonSchemaByPath.js.map +1 -0
- package/lib/schema/formatZodError.js +138 -0
- package/lib/schema/formatZodError.js.map +1 -0
- package/lib/schema/formatZodError.test.js +196 -0
- package/lib/schema/getSchemaCache.js +5 -5
- package/lib/schema/getSchemaCache.js.map +1 -0
- package/lib/schema/getSchemaOptions.js +8 -11
- package/lib/schema/getSchemaOptions.js.map +1 -0
- package/lib/schema/index.js +2 -1
- package/lib/schema/index.js.map +1 -0
- package/lib/schema/toJsonSchema.js +50 -293
- package/lib/schema/toJsonSchema.js.map +1 -0
- package/lib/schema/validate.js +34 -46
- package/lib/schema/validate.js.map +1 -0
- package/lib/tools/generateSchema.js +39 -197
- package/lib/tools/generateSchema.js.map +1 -0
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js +55 -143
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -0
- package/lib/utils/buildBaseUrl.js +13 -0
- package/lib/utils/buildBaseUrl.js.map +1 -0
- package/lib/utils/buildRedactorFormSchema.js +59 -0
- package/lib/utils/buildRedactorFormSchema.js.map +1 -0
- package/lib/utils/getEstimateProcessTime.js +12 -11
- package/lib/utils/getEstimateProcessTime.js.map +1 -0
- package/lib/utils/index.js +3 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/resolveFeatureOptions.js +12 -0
- package/lib/utils/resolveFeatureOptions.js.map +1 -0
- package/package.json +80 -13
- package/src/ai/qwen3vl/index.ts +1 -0
- package/src/ai/qwen3vl/utils.ts +36 -0
- package/src/ai/vision/DocLayoutElementTypeSchema.ts +30 -0
- package/src/ai/vision/ImageAnnotationSchema.ts +60 -0
- package/src/ai/vision/index.ts +2 -0
- package/src/ai/vision/resolveImageAnnotation.ts +135 -0
- package/src/cn/ChineseResidentIdNo.test.ts +1 -1
- package/src/cn/ChineseResidentIdNo.ts +9 -1
- package/src/cn/DivisionCode.test.ts +1 -1
- package/src/cn/DivisionCode.ts +8 -0
- package/src/cn/Mod11.ts +1 -1
- package/src/cn/UnifiedSocialCreditCode.test.ts +1 -1
- package/src/cn/UnifiedSocialCreditCode.ts +15 -0
- package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
- package/src/cn/formatChineseAmount.ts +61 -0
- package/src/cn/index.ts +7 -1
- package/src/cn/parseChineseNumber.test.ts +159 -0
- package/src/cn/parseChineseNumber.ts +97 -0
- package/src/cn/pinyin/cartesianProduct.test.ts +64 -0
- package/src/cn/pinyin/cartesianProduct.ts +24 -0
- package/src/cn/pinyin/data.json +23573 -0
- package/src/cn/pinyin/loader.ts +12 -0
- package/src/cn/pinyin/preload.ts +3 -0
- package/src/cn/pinyin/toPinyin.test.ts +12 -0
- package/src/cn/pinyin/toPinyinPure.ts +43 -0
- package/src/cn/pinyin/transform.ts +12 -0
- package/src/consola/formatLogObject.test.ts +27 -0
- package/src/consola/formatLogObject.ts +40 -12
- package/src/data/maybeNumber.ts +1 -1
- package/src/data/parseSort.test.ts +0 -1
- package/src/data/types.d.ts +2 -2
- package/src/dayjs/dayjs.ts +18 -18
- package/src/dayjs/formatDuration.ts +2 -2
- package/src/dayjs/index.ts +3 -1
- package/src/dayjs/parseRelativeTime.test.ts +185 -0
- package/src/dayjs/parseRelativeTime.ts +115 -0
- package/src/dayjs/resolveRelativeTime.test.ts +357 -0
- package/src/dayjs/resolveRelativeTime.ts +164 -0
- package/src/drain3/Drain.test.ts +378 -0
- package/src/drain3/Drain.ts +394 -0
- package/src/drain3/LogCluster.ts +46 -0
- package/src/drain3/Node.ts +53 -0
- package/src/drain3/TemplateMiner.ts +246 -0
- package/src/drain3/index.ts +36 -0
- package/src/drain3/persistence/FilePersistence.ts +24 -0
- package/src/drain3/persistence/MemoryPersistence.ts +23 -0
- package/src/drain3/persistence/PersistenceHandler.ts +19 -0
- package/src/drain3/types.ts +75 -0
- package/src/emittery/emitter.ts +9 -0
- package/src/emittery/index.ts +1 -0
- package/src/fs/FileSystemError.ts +26 -0
- package/src/fs/IFileSystem.d.ts +101 -0
- package/src/fs/MemoryFileSystem.test.ts +37 -0
- package/src/fs/createBrowserFileSystem.ts +293 -0
- package/src/fs/createMemoryFileSystem.ts +600 -0
- package/src/fs/createSandboxFileSystem.ts +136 -0
- package/src/fs/createWebDavFileSystem.ts +190 -0
- package/src/fs/createWebFileSystem.ts +242 -0
- package/src/fs/findMimeType.ts +20 -0
- package/src/fs/index.ts +8 -0
- package/src/fs/minio/createMinioFileSystem.ts +1148 -0
- package/src/fs/minio/index.ts +1 -0
- package/src/fs/orpc/FileSystemContract.ts +92 -0
- package/src/fs/orpc/createContractClientFileSystem.ts +115 -0
- package/src/fs/orpc/index.ts +2 -0
- package/src/fs/orpc/server/createFileSystemContractImpl.ts +64 -0
- package/src/fs/orpc/server/index.ts +1 -0
- package/src/fs/s3/createS3MiniFileSystem.ts +871 -0
- package/src/fs/s3/index.ts +1 -0
- package/src/fs/s3/s3fs.test.ts +441 -0
- package/src/fs/s3/s3mini.test.ts +264 -0
- package/src/fs/scandir.ts +75 -0
- package/src/fs/server/createDatabaseFileSystem.ts +668 -0
- package/src/fs/server/createNodeFileSystem.ts +518 -0
- package/src/fs/server/dbfs.test.ts +48 -0
- package/src/fs/server/index.ts +1 -0
- package/src/fs/server/loadTestDatabase.ts +131 -0
- package/src/fs/tests/runFileSystemTest.ts +289 -0
- package/src/fs/types.ts +29 -0
- package/src/fs/utils/getFileUrl.ts +44 -0
- package/src/fs/utils.ts +23 -0
- package/src/fs/webdav/index.ts +1 -0
- package/src/jsonschema/JsonSchema.ts +118 -110
- package/src/jsonschema/forEachJsonSchema.ts +50 -0
- package/src/jsonschema/index.ts +1 -0
- package/src/jsonschema/types.d.ts +1 -1
- package/src/meta/defineMetadata.ts +1 -1
- package/src/orpc/createOpenApiContractClient.ts +52 -0
- package/src/orpc/createRpcContractClient.ts +50 -0
- package/src/orpc/index.ts +2 -0
- package/src/orpc/resolveLinkPlugins.ts +29 -0
- package/src/password/PHC.ts +6 -6
- package/src/password/Password.test.ts +1 -1
- package/src/password/createArgon2PasswordAlgorithm.ts +1 -1
- package/src/password/createBase64PasswordAlgorithm.ts +2 -2
- package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
- package/src/password/createPBKDF2PasswordAlgorithm.ts +4 -4
- package/src/password/createScryptPasswordAlgorithm.ts +4 -4
- package/src/resource/ListQuery.ts +4 -1
- package/src/resource/index.ts +2 -2
- package/src/resource/schema/AnyResourceSchema.ts +16 -2
- package/src/s3/formatS3Url.test.ts +254 -0
- package/src/s3/formatS3Url.ts +84 -0
- package/src/s3/index.ts +2 -0
- package/src/s3/parseS3Url.test.ts +258 -0
- package/src/s3/parseS3Url.ts +88 -0
- package/src/schema/SchemaRegistry.ts +35 -33
- package/src/schema/TypeSchema.d.ts +6 -6
- package/src/schema/createSchemaData.ts +4 -4
- package/src/schema/findJsonSchemaByPath.ts +4 -4
- package/src/schema/formatZodError.test.ts +197 -0
- package/src/schema/formatZodError.ts +139 -0
- package/src/schema/getSchemaOptions.ts +2 -2
- package/src/schema/index.ts +1 -1
- package/src/schema/toJsonSchema.ts +6 -6
- package/src/schema/validate.ts +1 -1
- package/src/utils/buildBaseUrl.ts +12 -0
- package/src/utils/buildRedactorFormSchema.ts +85 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/resolveFeatureOptions.ts +14 -0
- package/src/cn/ChineseResidentIdNo.mod.ts +0 -7
- package/src/cn/DivisionCode.mod.ts +0 -7
- package/src/cn/UnifiedSocialCreditCode.mod.ts +0 -7
- package/src/cn/mod.ts +0 -3
- package/src/schema/SchemaRegistry.mod.ts +0 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { LogCluster } from "./LogCluster.js";
|
|
2
|
+
import { Node } from "./Node.js";
|
|
3
|
+
/**
|
|
4
|
+
* Simple LRU cache using Map iteration order.
|
|
5
|
+
* Map preserves insertion order; re-inserting a key moves it to the end.
|
|
6
|
+
*/ let SimpleLRU = class SimpleLRU {
|
|
7
|
+
max;
|
|
8
|
+
map = new Map();
|
|
9
|
+
constructor(max) {
|
|
10
|
+
this.max = max;
|
|
11
|
+
}
|
|
12
|
+
get(key) {
|
|
13
|
+
const value = this.map.get(key);
|
|
14
|
+
if (value !== undefined) {
|
|
15
|
+
// Move to end (most recently used)
|
|
16
|
+
this.map.delete(key);
|
|
17
|
+
this.map.set(key, value);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
set(key, value) {
|
|
22
|
+
if (this.map.has(key)) {
|
|
23
|
+
this.map.delete(key);
|
|
24
|
+
}
|
|
25
|
+
else if (this.map.size >= this.max) {
|
|
26
|
+
// Evict oldest (first key)
|
|
27
|
+
const first = this.map.keys().next().value;
|
|
28
|
+
if (first !== undefined) {
|
|
29
|
+
this.map.delete(first);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
this.map.set(key, value);
|
|
33
|
+
}
|
|
34
|
+
values() {
|
|
35
|
+
return this.map.values();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
function isSliceEqual(a, b) {
|
|
39
|
+
if (a.length !== b.length)
|
|
40
|
+
return false;
|
|
41
|
+
for (let i = 0; i < a.length; i++) {
|
|
42
|
+
if (a[i] !== b[i])
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
function hasNumbers(s) {
|
|
48
|
+
return /\d/.test(s);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Core Drain algorithm for log clustering.
|
|
52
|
+
*
|
|
53
|
+
* Drain is an online log parsing algorithm that groups log messages into clusters
|
|
54
|
+
* based on their structural similarity, extracting templates by parameterizing
|
|
55
|
+
* variable parts of the logs.
|
|
56
|
+
*/ export class Drain {
|
|
57
|
+
logClusterDepth;
|
|
58
|
+
maxNodeDepth;
|
|
59
|
+
simTh;
|
|
60
|
+
maxChildren;
|
|
61
|
+
rootNode;
|
|
62
|
+
maxClusters;
|
|
63
|
+
extraDelimiters;
|
|
64
|
+
paramStr;
|
|
65
|
+
parametrizeNumericTokens;
|
|
66
|
+
idToCluster;
|
|
67
|
+
clustersCounter = 0;
|
|
68
|
+
constructor(options = {}) {
|
|
69
|
+
this.logClusterDepth = options.logClusterDepth ?? 4;
|
|
70
|
+
this.simTh = options.simTh ?? 0.4;
|
|
71
|
+
this.maxChildren = options.maxChildren ?? 100;
|
|
72
|
+
this.maxClusters = options.maxClusters ?? 1000;
|
|
73
|
+
this.extraDelimiters = options.extraDelimiters ?? [];
|
|
74
|
+
this.paramStr = options.paramStr ?? "<*>";
|
|
75
|
+
this.parametrizeNumericTokens = options.parametrizeNumericTokens ?? true;
|
|
76
|
+
if (this.logClusterDepth < 3) {
|
|
77
|
+
throw new Error("depth argument must be at least 3");
|
|
78
|
+
}
|
|
79
|
+
this.maxNodeDepth = this.logClusterDepth - 2;
|
|
80
|
+
this.rootNode = Node.newNode();
|
|
81
|
+
this.idToCluster = new SimpleLRU(this.maxClusters);
|
|
82
|
+
}
|
|
83
|
+
addLogMessage(content) {
|
|
84
|
+
const contentTokens = this.getContentAsTokens(content);
|
|
85
|
+
const matchCluster = this.treeSearch(this.rootNode, contentTokens, this.simTh, false);
|
|
86
|
+
let updateType = "none";
|
|
87
|
+
if (matchCluster === null) {
|
|
88
|
+
this.clustersCounter++;
|
|
89
|
+
const clusterId = this.clustersCounter;
|
|
90
|
+
const cluster = new LogCluster(clusterId, contentTokens);
|
|
91
|
+
this.idToCluster.set(clusterId, cluster);
|
|
92
|
+
this.addSeqToPrefixTree(this.rootNode, cluster);
|
|
93
|
+
updateType = "created";
|
|
94
|
+
return {
|
|
95
|
+
cluster,
|
|
96
|
+
updateType
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const newTemplateTokens = this.createTemplate(contentTokens, matchCluster.logTemplateTokens);
|
|
100
|
+
if (!isSliceEqual(newTemplateTokens, matchCluster.logTemplateTokens)) {
|
|
101
|
+
matchCluster.logTemplateTokens = newTemplateTokens;
|
|
102
|
+
updateType = "templateChanged";
|
|
103
|
+
}
|
|
104
|
+
matchCluster.size++;
|
|
105
|
+
// Touch cluster to update its position in the LRU cache
|
|
106
|
+
this.idToCluster.get(matchCluster.clusterId);
|
|
107
|
+
return {
|
|
108
|
+
cluster: matchCluster,
|
|
109
|
+
updateType
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
getContentAsTokens(content) {
|
|
113
|
+
let processed = content.trim();
|
|
114
|
+
for (const delimiter of this.extraDelimiters) {
|
|
115
|
+
processed = processed.replaceAll(delimiter, " ");
|
|
116
|
+
}
|
|
117
|
+
return processed.split(/\s+/).filter((token) => token.length > 0);
|
|
118
|
+
}
|
|
119
|
+
treeSearch(rootNode, tokens, simTh, includeParams) {
|
|
120
|
+
const tokenCount = tokens.length;
|
|
121
|
+
const firstNode = rootNode.keyToChildNode.get(tokenCount.toString());
|
|
122
|
+
if (firstNode === undefined)
|
|
123
|
+
return null;
|
|
124
|
+
if (tokenCount === 0) {
|
|
125
|
+
const firstClusterId = firstNode.clusterIds[0];
|
|
126
|
+
if (firstClusterId === undefined)
|
|
127
|
+
return null;
|
|
128
|
+
return this.idToCluster.get(firstClusterId) ?? null;
|
|
129
|
+
}
|
|
130
|
+
let currentNode = firstNode;
|
|
131
|
+
let currentNodeDepth = 1;
|
|
132
|
+
for (const token of tokens) {
|
|
133
|
+
if (currentNodeDepth >= this.maxNodeDepth || currentNodeDepth === tokenCount)
|
|
134
|
+
break;
|
|
135
|
+
const keyToChildNode = currentNode.keyToChildNode;
|
|
136
|
+
let nextNode = keyToChildNode.get(token);
|
|
137
|
+
if (nextNode === undefined) {
|
|
138
|
+
nextNode = keyToChildNode.get(this.paramStr);
|
|
139
|
+
}
|
|
140
|
+
if (nextNode === undefined)
|
|
141
|
+
return null;
|
|
142
|
+
currentNode = nextNode;
|
|
143
|
+
currentNodeDepth += 1;
|
|
144
|
+
}
|
|
145
|
+
return this.fastMatch(currentNode.clusterIds, tokens, simTh, includeParams);
|
|
146
|
+
}
|
|
147
|
+
fastMatch(clusterIds, tokens, simTh, includeParams) {
|
|
148
|
+
let maxSim = -1;
|
|
149
|
+
let maxParamCount = -1;
|
|
150
|
+
let maxCluster = null;
|
|
151
|
+
for (const clusterId of clusterIds) {
|
|
152
|
+
const cluster = this.idToCluster.get(clusterId);
|
|
153
|
+
if (cluster === undefined)
|
|
154
|
+
continue;
|
|
155
|
+
const [currentSim, paramCount] = this.getSeqDistance(cluster.logTemplateTokens, tokens, includeParams);
|
|
156
|
+
if (currentSim > maxSim || currentSim === maxSim && paramCount > maxParamCount) {
|
|
157
|
+
maxSim = currentSim;
|
|
158
|
+
maxParamCount = paramCount;
|
|
159
|
+
maxCluster = cluster;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return maxSim >= simTh ? maxCluster : null;
|
|
163
|
+
}
|
|
164
|
+
getSeqDistance(seq1, seq2, includeParams) {
|
|
165
|
+
if (seq1.length !== seq2.length) {
|
|
166
|
+
throw new Error(`seq1 length ${seq1.length} not equals to seq2 length ${seq2.length}`);
|
|
167
|
+
}
|
|
168
|
+
if (seq1.length === 0)
|
|
169
|
+
return [
|
|
170
|
+
1,
|
|
171
|
+
0
|
|
172
|
+
];
|
|
173
|
+
let simTokens = 0;
|
|
174
|
+
let paramCount = 0;
|
|
175
|
+
for (let i = 0; i < seq1.length; i++) {
|
|
176
|
+
if (seq1[i] === this.paramStr) {
|
|
177
|
+
paramCount++;
|
|
178
|
+
}
|
|
179
|
+
else if (seq1[i] === seq2[i]) {
|
|
180
|
+
simTokens++;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (includeParams)
|
|
184
|
+
simTokens += paramCount;
|
|
185
|
+
return [
|
|
186
|
+
simTokens / seq1.length,
|
|
187
|
+
paramCount
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
addSeqToPrefixTree(rootNode, cluster) {
|
|
191
|
+
const tokenCount = cluster.logTemplateTokens.length;
|
|
192
|
+
const tokenCountStr = tokenCount.toString();
|
|
193
|
+
let firstLayerNode = rootNode.keyToChildNode.get(tokenCountStr);
|
|
194
|
+
if (firstLayerNode === undefined) {
|
|
195
|
+
firstLayerNode = Node.newNode();
|
|
196
|
+
rootNode.keyToChildNode.set(tokenCountStr, firstLayerNode);
|
|
197
|
+
}
|
|
198
|
+
let currentNode = firstLayerNode;
|
|
199
|
+
if (tokenCount === 0) {
|
|
200
|
+
currentNode.clusterIds = [
|
|
201
|
+
cluster.clusterId
|
|
202
|
+
];
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
let currentDepth = 1;
|
|
206
|
+
for (const token of cluster.logTemplateTokens) {
|
|
207
|
+
if (currentDepth >= this.maxNodeDepth || currentDepth >= tokenCount) {
|
|
208
|
+
const newClusterIds = [];
|
|
209
|
+
for (const clusterId of currentNode.clusterIds) {
|
|
210
|
+
if (this.idToCluster.get(clusterId) !== undefined) {
|
|
211
|
+
newClusterIds.push(clusterId);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
newClusterIds.push(cluster.clusterId);
|
|
215
|
+
currentNode.clusterIds = newClusterIds;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
if (!currentNode.keyToChildNode.has(token)) {
|
|
219
|
+
if (this.parametrizeNumericTokens && hasNumbers(token)) {
|
|
220
|
+
const node = currentNode.keyToChildNode.get(this.paramStr);
|
|
221
|
+
if (node === undefined) {
|
|
222
|
+
const newNode = Node.newNode();
|
|
223
|
+
currentNode.keyToChildNode.set(this.paramStr, newNode);
|
|
224
|
+
currentNode = newNode;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
currentNode = node;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
const wildcardNode = currentNode.keyToChildNode.get(this.paramStr);
|
|
232
|
+
if (wildcardNode !== undefined) {
|
|
233
|
+
if (currentNode.keyToChildNode.size < this.maxChildren) {
|
|
234
|
+
const newNode = Node.newNode();
|
|
235
|
+
currentNode.keyToChildNode.set(token, newNode);
|
|
236
|
+
currentNode = newNode;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
currentNode = wildcardNode;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
if (currentNode.keyToChildNode.size + 1 < this.maxChildren) {
|
|
244
|
+
const newNode = Node.newNode();
|
|
245
|
+
currentNode.keyToChildNode.set(token, newNode);
|
|
246
|
+
currentNode = newNode;
|
|
247
|
+
}
|
|
248
|
+
else if (currentNode.keyToChildNode.size + 1 === this.maxChildren) {
|
|
249
|
+
const newNode = Node.newNode();
|
|
250
|
+
currentNode.keyToChildNode.set(this.paramStr, newNode);
|
|
251
|
+
currentNode = newNode;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
currentNode = currentNode.keyToChildNode.get(this.paramStr);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
currentNode = currentNode.keyToChildNode.get(token);
|
|
261
|
+
}
|
|
262
|
+
currentDepth++;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
createTemplate(seq1, seq2) {
|
|
266
|
+
if (seq1.length !== seq2.length) {
|
|
267
|
+
throw new Error(`seq1 length ${seq1.length} not equals to seq2 length ${seq2.length}`);
|
|
268
|
+
}
|
|
269
|
+
const retVal = [
|
|
270
|
+
...seq2
|
|
271
|
+
];
|
|
272
|
+
for (let i = 0; i < seq1.length; i++) {
|
|
273
|
+
if (seq1[i] !== seq2[i]) {
|
|
274
|
+
retVal[i] = this.paramStr;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return retVal;
|
|
278
|
+
}
|
|
279
|
+
match(content, strategy = "never") {
|
|
280
|
+
const requiredSimTh = 1;
|
|
281
|
+
const contentTokens = this.getContentAsTokens(content);
|
|
282
|
+
const fullSearch = () => {
|
|
283
|
+
const allIds = this.getClustersIdsForSeqLen(contentTokens.length);
|
|
284
|
+
return this.fastMatch(allIds, contentTokens, requiredSimTh, true);
|
|
285
|
+
};
|
|
286
|
+
if (strategy === "always")
|
|
287
|
+
return fullSearch();
|
|
288
|
+
const matchCluster = this.treeSearch(this.rootNode, contentTokens, requiredSimTh, true);
|
|
289
|
+
if (matchCluster !== null)
|
|
290
|
+
return matchCluster;
|
|
291
|
+
if (strategy === "never")
|
|
292
|
+
return null;
|
|
293
|
+
return fullSearch();
|
|
294
|
+
}
|
|
295
|
+
getClustersIdsForSeqLen(seqLen) {
|
|
296
|
+
const appendClusterRecursive = (node, idListToFill) => {
|
|
297
|
+
idListToFill.push(...node.clusterIds);
|
|
298
|
+
for (const childNode of node.keyToChildNode.values()) {
|
|
299
|
+
appendClusterRecursive(childNode, idListToFill);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
const currentNode = this.rootNode.keyToChildNode.get(seqLen.toString());
|
|
303
|
+
if (currentNode === undefined)
|
|
304
|
+
return [];
|
|
305
|
+
const target = [];
|
|
306
|
+
appendClusterRecursive(currentNode, target);
|
|
307
|
+
return target;
|
|
308
|
+
}
|
|
309
|
+
getClusters() {
|
|
310
|
+
return [
|
|
311
|
+
...this.idToCluster.values()
|
|
312
|
+
];
|
|
313
|
+
}
|
|
314
|
+
toJSON() {
|
|
315
|
+
return {
|
|
316
|
+
logClusterDepth: this.logClusterDepth,
|
|
317
|
+
maxNodeDepth: this.maxNodeDepth,
|
|
318
|
+
simTh: this.simTh,
|
|
319
|
+
maxChildren: this.maxChildren,
|
|
320
|
+
rootNode: this.rootNode.toJSON(),
|
|
321
|
+
maxClusters: this.maxClusters,
|
|
322
|
+
extraDelimiters: [
|
|
323
|
+
...this.extraDelimiters
|
|
324
|
+
],
|
|
325
|
+
paramStr: this.paramStr,
|
|
326
|
+
parametrizeNumericTokens: this.parametrizeNumericTokens,
|
|
327
|
+
clusters: this.getClusters().map((c) => c.toJSON()),
|
|
328
|
+
clustersCounter: this.clustersCounter
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
static fromJSON(data) {
|
|
332
|
+
const drain = new Drain({
|
|
333
|
+
logClusterDepth: data.logClusterDepth,
|
|
334
|
+
simTh: data.simTh,
|
|
335
|
+
maxChildren: data.maxChildren,
|
|
336
|
+
maxClusters: data.maxClusters,
|
|
337
|
+
extraDelimiters: data.extraDelimiters,
|
|
338
|
+
paramStr: data.paramStr,
|
|
339
|
+
parametrizeNumericTokens: data.parametrizeNumericTokens
|
|
340
|
+
});
|
|
341
|
+
drain.rootNode.keyToChildNode.clear();
|
|
342
|
+
drain.rootNode.clusterIds = [];
|
|
343
|
+
const rootNode = Node.fromJSON(data.rootNode);
|
|
344
|
+
for (const [key, node] of rootNode.keyToChildNode) {
|
|
345
|
+
drain.rootNode.keyToChildNode.set(key, node);
|
|
346
|
+
}
|
|
347
|
+
drain.rootNode.clusterIds = rootNode.clusterIds;
|
|
348
|
+
for (const clusterData of data.clusters) {
|
|
349
|
+
const cluster = LogCluster.fromJSON(clusterData);
|
|
350
|
+
drain.idToCluster.set(cluster.clusterId, cluster);
|
|
351
|
+
}
|
|
352
|
+
drain.clustersCounter = data.clustersCounter;
|
|
353
|
+
return drain;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=Drain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/drain3/Drain.ts"],"sourcesContent":["import { LogCluster } from './LogCluster';\nimport { Node } from './Node';\nimport type { ClusterUpdateType, DrainOptions, SearchStrategy } from './types';\n\n/**\n * Simple LRU cache using Map iteration order.\n * Map preserves insertion order; re-inserting a key moves it to the end.\n */\nclass SimpleLRU<K, V> {\n\tprivate readonly map = new Map<K, V>();\n\tconstructor(private readonly max: number) {}\n\n\tget(key: K): V | undefined {\n\t\tconst value = this.map.get(key);\n\t\tif (value !== undefined) {\n\t\t\t// Move to end (most recently used)\n\t\t\tthis.map.delete(key);\n\t\t\tthis.map.set(key, value);\n\t\t}\n\t\treturn value;\n\t}\n\n\tset(key: K, value: V): void {\n\t\tif (this.map.has(key)) {\n\t\t\tthis.map.delete(key);\n\t\t} else if (this.map.size >= this.max) {\n\t\t\t// Evict oldest (first key)\n\t\t\tconst first = this.map.keys().next().value;\n\t\t\tif (first !== undefined) {\n\t\t\t\tthis.map.delete(first);\n\t\t\t}\n\t\t}\n\t\tthis.map.set(key, value);\n\t}\n\n\tvalues(): IterableIterator<V> {\n\t\treturn this.map.values();\n\t}\n}\n\nfunction isSliceEqual<T>(a: T[], b: T[]): boolean {\n\tif (a.length !== b.length) return false;\n\tfor (let i = 0; i < a.length; i++) {\n\t\tif (a[i] !== b[i]) return false;\n\t}\n\treturn true;\n}\n\nfunction hasNumbers(s: string): boolean {\n\treturn /\\d/.test(s);\n}\n\n/**\n * Core Drain algorithm for log clustering.\n *\n * Drain is an online log parsing algorithm that groups log messages into clusters\n * based on their structural similarity, extracting templates by parameterizing\n * variable parts of the logs.\n */\nexport class Drain {\n\tpublic readonly logClusterDepth: number;\n\tpublic readonly maxNodeDepth: number;\n\tpublic readonly simTh: number;\n\tpublic readonly maxChildren: number;\n\tpublic readonly rootNode: Node;\n\tpublic readonly maxClusters: number;\n\tpublic readonly extraDelimiters: readonly string[];\n\tpublic readonly paramStr: string;\n\tpublic readonly parametrizeNumericTokens: boolean;\n\n\tprivate readonly idToCluster: SimpleLRU<number, LogCluster>;\n\tprivate clustersCounter: number = 0;\n\n\tconstructor(options: DrainOptions = {}) {\n\t\tthis.logClusterDepth = options.logClusterDepth ?? 4;\n\t\tthis.simTh = options.simTh ?? 0.4;\n\t\tthis.maxChildren = options.maxChildren ?? 100;\n\t\tthis.maxClusters = options.maxClusters ?? 1000;\n\t\tthis.extraDelimiters = options.extraDelimiters ?? [];\n\t\tthis.paramStr = options.paramStr ?? '<*>';\n\t\tthis.parametrizeNumericTokens = options.parametrizeNumericTokens ?? true;\n\n\t\tif (this.logClusterDepth < 3) {\n\t\t\tthrow new Error('depth argument must be at least 3');\n\t\t}\n\n\t\tthis.maxNodeDepth = this.logClusterDepth - 2;\n\t\tthis.rootNode = Node.newNode();\n\t\tthis.idToCluster = new SimpleLRU<number, LogCluster>(this.maxClusters);\n\t}\n\n\taddLogMessage(content: string): { cluster: LogCluster; updateType: ClusterUpdateType } {\n\t\tconst contentTokens = this.getContentAsTokens(content);\n\t\tconst matchCluster = this.treeSearch(this.rootNode, contentTokens, this.simTh, false);\n\n\t\tlet updateType: ClusterUpdateType = 'none';\n\n\t\tif (matchCluster === null) {\n\t\t\tthis.clustersCounter++;\n\t\t\tconst clusterId = this.clustersCounter;\n\t\t\tconst cluster = new LogCluster(clusterId, contentTokens);\n\t\t\tthis.idToCluster.set(clusterId, cluster);\n\t\t\tthis.addSeqToPrefixTree(this.rootNode, cluster);\n\t\t\tupdateType = 'created';\n\t\t\treturn { cluster, updateType };\n\t\t}\n\n\t\tconst newTemplateTokens = this.createTemplate(contentTokens, matchCluster.logTemplateTokens);\n\n\t\tif (!isSliceEqual(newTemplateTokens, matchCluster.logTemplateTokens)) {\n\t\t\tmatchCluster.logTemplateTokens = newTemplateTokens;\n\t\t\tupdateType = 'templateChanged';\n\t\t}\n\n\t\tmatchCluster.size++;\n\n\t\t// Touch cluster to update its position in the LRU cache\n\t\tthis.idToCluster.get(matchCluster.clusterId);\n\n\t\treturn { cluster: matchCluster, updateType };\n\t}\n\n\tgetContentAsTokens(content: string): string[] {\n\t\tlet processed = content.trim();\n\t\tfor (const delimiter of this.extraDelimiters) {\n\t\t\tprocessed = processed.replaceAll(delimiter, ' ');\n\t\t}\n\t\treturn processed.split(/\\s+/).filter((token) => token.length > 0);\n\t}\n\n\tprivate treeSearch(rootNode: Node, tokens: string[], simTh: number, includeParams: boolean): LogCluster | null {\n\t\tconst tokenCount = tokens.length;\n\t\tconst firstNode = rootNode.keyToChildNode.get(tokenCount.toString());\n\n\t\tif (firstNode === undefined) return null;\n\n\t\tif (tokenCount === 0) {\n\t\t\tconst firstClusterId = firstNode.clusterIds[0];\n\t\t\tif (firstClusterId === undefined) return null;\n\t\t\treturn this.idToCluster.get(firstClusterId) ?? null;\n\t\t}\n\n\t\tlet currentNode: Node = firstNode;\n\t\tlet currentNodeDepth = 1;\n\t\tfor (const token of tokens) {\n\t\t\tif (currentNodeDepth >= this.maxNodeDepth || currentNodeDepth === tokenCount) break;\n\n\t\t\tconst keyToChildNode: Map<string, Node> = currentNode.keyToChildNode;\n\t\t\tlet nextNode: Node | undefined = keyToChildNode.get(token);\n\t\t\tif (nextNode === undefined) {\n\t\t\t\tnextNode = keyToChildNode.get(this.paramStr);\n\t\t\t}\n\t\t\tif (nextNode === undefined) return null;\n\n\t\t\tcurrentNode = nextNode;\n\t\t\tcurrentNodeDepth += 1;\n\t\t}\n\n\t\treturn this.fastMatch(currentNode.clusterIds, tokens, simTh, includeParams);\n\t}\n\n\tprivate fastMatch(clusterIds: number[], tokens: string[], simTh: number, includeParams: boolean): LogCluster | null {\n\t\tlet maxSim = -1;\n\t\tlet maxParamCount = -1;\n\t\tlet maxCluster: LogCluster | null = null;\n\n\t\tfor (const clusterId of clusterIds) {\n\t\t\tconst cluster = this.idToCluster.get(clusterId);\n\t\t\tif (cluster === undefined) continue;\n\n\t\t\tconst [currentSim, paramCount] = this.getSeqDistance(cluster.logTemplateTokens, tokens, includeParams);\n\n\t\t\tif (currentSim > maxSim || (currentSim === maxSim && paramCount > maxParamCount)) {\n\t\t\t\tmaxSim = currentSim;\n\t\t\t\tmaxParamCount = paramCount;\n\t\t\t\tmaxCluster = cluster;\n\t\t\t}\n\t\t}\n\n\t\treturn maxSim >= simTh ? maxCluster : null;\n\t}\n\n\tprivate getSeqDistance(seq1: string[], seq2: string[], includeParams: boolean): [number, number] {\n\t\tif (seq1.length !== seq2.length) {\n\t\t\tthrow new Error(`seq1 length ${seq1.length} not equals to seq2 length ${seq2.length}`);\n\t\t}\n\n\t\tif (seq1.length === 0) return [1, 0];\n\n\t\tlet simTokens = 0;\n\t\tlet paramCount = 0;\n\n\t\tfor (let i = 0; i < seq1.length; i++) {\n\t\t\tif (seq1[i] === this.paramStr) {\n\t\t\t\tparamCount++;\n\t\t\t} else if (seq1[i] === seq2[i]) {\n\t\t\t\tsimTokens++;\n\t\t\t}\n\t\t}\n\n\t\tif (includeParams) simTokens += paramCount;\n\n\t\treturn [simTokens / seq1.length, paramCount];\n\t}\n\n\tprivate addSeqToPrefixTree(rootNode: Node, cluster: LogCluster): void {\n\t\tconst tokenCount = cluster.logTemplateTokens.length;\n\t\tconst tokenCountStr = tokenCount.toString();\n\t\tlet firstLayerNode = rootNode.keyToChildNode.get(tokenCountStr);\n\t\tif (firstLayerNode === undefined) {\n\t\t\tfirstLayerNode = Node.newNode();\n\t\t\trootNode.keyToChildNode.set(tokenCountStr, firstLayerNode);\n\t\t}\n\n\t\tlet currentNode = firstLayerNode;\n\n\t\tif (tokenCount === 0) {\n\t\t\tcurrentNode.clusterIds = [cluster.clusterId];\n\t\t\treturn;\n\t\t}\n\n\t\tlet currentDepth = 1;\n\t\tfor (const token of cluster.logTemplateTokens) {\n\t\t\tif (currentDepth >= this.maxNodeDepth || currentDepth >= tokenCount) {\n\t\t\t\tconst newClusterIds: number[] = [];\n\t\t\t\tfor (const clusterId of currentNode.clusterIds) {\n\t\t\t\t\tif (this.idToCluster.get(clusterId) !== undefined) {\n\t\t\t\t\t\tnewClusterIds.push(clusterId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnewClusterIds.push(cluster.clusterId);\n\t\t\t\tcurrentNode.clusterIds = newClusterIds;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (!currentNode.keyToChildNode.has(token)) {\n\t\t\t\tif (this.parametrizeNumericTokens && hasNumbers(token)) {\n\t\t\t\t\tconst node = currentNode.keyToChildNode.get(this.paramStr);\n\t\t\t\t\tif (node === undefined) {\n\t\t\t\t\t\tconst newNode = Node.newNode();\n\t\t\t\t\t\tcurrentNode.keyToChildNode.set(this.paramStr, newNode);\n\t\t\t\t\t\tcurrentNode = newNode;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrentNode = node;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst wildcardNode = currentNode.keyToChildNode.get(this.paramStr);\n\t\t\t\t\tif (wildcardNode !== undefined) {\n\t\t\t\t\t\tif (currentNode.keyToChildNode.size < this.maxChildren) {\n\t\t\t\t\t\t\tconst newNode = Node.newNode();\n\t\t\t\t\t\t\tcurrentNode.keyToChildNode.set(token, newNode);\n\t\t\t\t\t\t\tcurrentNode = newNode;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrentNode = wildcardNode;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (currentNode.keyToChildNode.size + 1 < this.maxChildren) {\n\t\t\t\t\t\t\tconst newNode = Node.newNode();\n\t\t\t\t\t\t\tcurrentNode.keyToChildNode.set(token, newNode);\n\t\t\t\t\t\t\tcurrentNode = newNode;\n\t\t\t\t\t\t} else if (currentNode.keyToChildNode.size + 1 === this.maxChildren) {\n\t\t\t\t\t\t\tconst newNode = Node.newNode();\n\t\t\t\t\t\t\tcurrentNode.keyToChildNode.set(this.paramStr, newNode);\n\t\t\t\t\t\t\tcurrentNode = newNode;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrentNode = currentNode.keyToChildNode.get(this.paramStr)!;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrentNode = currentNode.keyToChildNode.get(token)!;\n\t\t\t}\n\n\t\t\tcurrentDepth++;\n\t\t}\n\t}\n\n\tprivate createTemplate(seq1: string[], seq2: string[]): string[] {\n\t\tif (seq1.length !== seq2.length) {\n\t\t\tthrow new Error(`seq1 length ${seq1.length} not equals to seq2 length ${seq2.length}`);\n\t\t}\n\t\tconst retVal = [...seq2];\n\t\tfor (let i = 0; i < seq1.length; i++) {\n\t\t\tif (seq1[i] !== seq2[i]) {\n\t\t\t\tretVal[i] = this.paramStr;\n\t\t\t}\n\t\t}\n\t\treturn retVal;\n\t}\n\n\tmatch(content: string, strategy: SearchStrategy = 'never'): LogCluster | null {\n\t\tconst requiredSimTh = 1.0;\n\t\tconst contentTokens = this.getContentAsTokens(content);\n\n\t\tconst fullSearch = (): LogCluster | null => {\n\t\t\tconst allIds = this.getClustersIdsForSeqLen(contentTokens.length);\n\t\t\treturn this.fastMatch(allIds, contentTokens, requiredSimTh, true);\n\t\t};\n\n\t\tif (strategy === 'always') return fullSearch();\n\n\t\tconst matchCluster = this.treeSearch(this.rootNode, contentTokens, requiredSimTh, true);\n\t\tif (matchCluster !== null) return matchCluster;\n\n\t\tif (strategy === 'never') return null;\n\n\t\treturn fullSearch();\n\t}\n\n\tprivate getClustersIdsForSeqLen(seqLen: number): number[] {\n\t\tconst appendClusterRecursive = (node: Node, idListToFill: number[]): void => {\n\t\t\tidListToFill.push(...node.clusterIds);\n\t\t\tfor (const childNode of node.keyToChildNode.values()) {\n\t\t\t\tappendClusterRecursive(childNode, idListToFill);\n\t\t\t}\n\t\t};\n\n\t\tconst currentNode = this.rootNode.keyToChildNode.get(seqLen.toString());\n\t\tif (currentNode === undefined) return [];\n\n\t\tconst target: number[] = [];\n\t\tappendClusterRecursive(currentNode, target);\n\t\treturn target;\n\t}\n\n\tgetClusters(): LogCluster[] {\n\t\treturn [...this.idToCluster.values()];\n\t}\n\n\ttoJSON() {\n\t\treturn {\n\t\t\tlogClusterDepth: this.logClusterDepth,\n\t\t\tmaxNodeDepth: this.maxNodeDepth,\n\t\t\tsimTh: this.simTh,\n\t\t\tmaxChildren: this.maxChildren,\n\t\t\trootNode: this.rootNode.toJSON(),\n\t\t\tmaxClusters: this.maxClusters,\n\t\t\textraDelimiters: [...this.extraDelimiters],\n\t\t\tparamStr: this.paramStr,\n\t\t\tparametrizeNumericTokens: this.parametrizeNumericTokens,\n\t\t\tclusters: this.getClusters().map((c) => c.toJSON()),\n\t\t\tclustersCounter: this.clustersCounter,\n\t\t};\n\t}\n\n\tstatic fromJSON(data: {\n\t\tlogClusterDepth: number;\n\t\tmaxNodeDepth: number;\n\t\tsimTh: number;\n\t\tmaxChildren: number;\n\t\trootNode: {\n\t\t\tkeyToChildNode: Record<string, unknown>;\n\t\t\tclusterIds: number[];\n\t\t};\n\t\tmaxClusters: number;\n\t\textraDelimiters: string[];\n\t\tparamStr: string;\n\t\tparametrizeNumericTokens: boolean;\n\t\tclusters: Array<{\n\t\t\tclusterId: number;\n\t\t\tlogTemplateTokens: string[];\n\t\t\tsize: number;\n\t\t}>;\n\t\tclustersCounter: number;\n\t}): Drain {\n\t\tconst drain = new Drain({\n\t\t\tlogClusterDepth: data.logClusterDepth,\n\t\t\tsimTh: data.simTh,\n\t\t\tmaxChildren: data.maxChildren,\n\t\t\tmaxClusters: data.maxClusters,\n\t\t\textraDelimiters: data.extraDelimiters,\n\t\t\tparamStr: data.paramStr,\n\t\t\tparametrizeNumericTokens: data.parametrizeNumericTokens,\n\t\t});\n\n\t\tdrain.rootNode.keyToChildNode.clear();\n\t\tdrain.rootNode.clusterIds = [];\n\n\t\tconst rootNode = Node.fromJSON(data.rootNode);\n\t\tfor (const [key, node] of rootNode.keyToChildNode) {\n\t\t\tdrain.rootNode.keyToChildNode.set(key, node);\n\t\t}\n\t\tdrain.rootNode.clusterIds = rootNode.clusterIds;\n\n\t\tfor (const clusterData of data.clusters) {\n\t\t\tconst cluster = LogCluster.fromJSON(clusterData);\n\t\t\tdrain.idToCluster.set(cluster.clusterId, cluster);\n\t\t}\n\n\t\tdrain.clustersCounter = data.clustersCounter;\n\n\t\treturn drain;\n\t}\n}\n"],"names":["LogCluster","Node","SimpleLRU","map","Map","max","get","key","value","undefined","delete","set","has","size","first","keys","next","values","isSliceEqual","a","b","length","i","hasNumbers","s","test","Drain","logClusterDepth","maxNodeDepth","simTh","maxChildren","rootNode","maxClusters","extraDelimiters","paramStr","parametrizeNumericTokens","idToCluster","clustersCounter","options","Error","newNode","addLogMessage","content","contentTokens","getContentAsTokens","matchCluster","treeSearch","updateType","clusterId","cluster","addSeqToPrefixTree","newTemplateTokens","createTemplate","logTemplateTokens","processed","trim","delimiter","replaceAll","split","filter","token","tokens","includeParams","tokenCount","firstNode","keyToChildNode","toString","firstClusterId","clusterIds","currentNode","currentNodeDepth","nextNode","fastMatch","maxSim","maxParamCount","maxCluster","currentSim","paramCount","getSeqDistance","seq1","seq2","simTokens","tokenCountStr","firstLayerNode","currentDepth","newClusterIds","push","node","wildcardNode","retVal","match","strategy","requiredSimTh","fullSearch","allIds","getClustersIdsForSeqLen","seqLen","appendClusterRecursive","idListToFill","childNode","target","getClusters","toJSON","clusters","c","fromJSON","data","drain","clear","clusterData"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a cluster of similar log messages with a common template.
|
|
3
|
+
*/ export class LogCluster {
|
|
4
|
+
clusterId;
|
|
5
|
+
logTemplateTokens;
|
|
6
|
+
size;
|
|
7
|
+
constructor(clusterId, logTemplateTokens, size = 1){
|
|
8
|
+
this.clusterId = clusterId;
|
|
9
|
+
this.logTemplateTokens = logTemplateTokens;
|
|
10
|
+
this.size = size;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns the template as a space-separated string.
|
|
14
|
+
*/ getTemplate() {
|
|
15
|
+
return this.logTemplateTokens.join(' ');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns a string representation of the cluster.
|
|
19
|
+
*/ toString() {
|
|
20
|
+
return `ID=${this.clusterId.toString().padEnd(5)} : size=${this.size.toString().padEnd(10)}: ${this.getTemplate()}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a LogCluster from JSON data.
|
|
24
|
+
*/ static fromJSON(data) {
|
|
25
|
+
return new LogCluster(data.clusterId, data.logTemplateTokens, data.size);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Converts the cluster to JSON for serialization.
|
|
29
|
+
*/ toJSON() {
|
|
30
|
+
return {
|
|
31
|
+
clusterId: this.clusterId,
|
|
32
|
+
logTemplateTokens: this.logTemplateTokens,
|
|
33
|
+
size: this.size
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=LogCluster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/drain3/LogCluster.ts"],"sourcesContent":["/**\n * Represents a cluster of similar log messages with a common template.\n */\nexport class LogCluster {\n\tconstructor(\n\t\tpublic readonly clusterId: number,\n\t\tpublic logTemplateTokens: string[],\n\t\tpublic size: number = 1,\n\t) {}\n\n\t/**\n\t * Returns the template as a space-separated string.\n\t */\n\tgetTemplate(): string {\n\t\treturn this.logTemplateTokens.join(' ');\n\t}\n\n\t/**\n\t * Returns a string representation of the cluster.\n\t */\n\ttoString(): string {\n\t\treturn `ID=${this.clusterId.toString().padEnd(5)} : size=${this.size.toString().padEnd(10)}: ${this.getTemplate()}`;\n\t}\n\n\t/**\n\t * Creates a LogCluster from JSON data.\n\t */\n\tstatic fromJSON(data: { clusterId: number; logTemplateTokens: string[]; size: number }): LogCluster {\n\t\treturn new LogCluster(data.clusterId, data.logTemplateTokens, data.size);\n\t}\n\n\t/**\n\t * Converts the cluster to JSON for serialization.\n\t */\n\ttoJSON(): {\n\t\tclusterId: number;\n\t\tlogTemplateTokens: string[];\n\t\tsize: number;\n\t} {\n\t\treturn {\n\t\t\tclusterId: this.clusterId,\n\t\t\tlogTemplateTokens: this.logTemplateTokens,\n\t\t\tsize: this.size,\n\t\t};\n\t}\n}\n"],"names":["LogCluster","clusterId","logTemplateTokens","size","getTemplate","join","toString","padEnd","fromJSON","data","toJSON"],"mappings":"AAAA;;CAEC,GACD,OAAO,MAAMA;;;;IACZ,YACC,AAAgBC,SAAiB,EACjC,AAAOC,iBAA2B,EAClC,AAAOC,OAAe,CAAC,CACtB;aAHeF,YAAAA;aACTC,oBAAAA;aACAC,OAAAA;IACL;IAEH;;EAEC,GACDC,cAAsB;QACrB,OAAO,IAAI,CAACF,iBAAiB,CAACG,IAAI,CAAC;IACpC;IAEA;;EAEC,GACDC,WAAmB;QAClB,OAAO,CAAC,GAAG,EAAE,IAAI,CAACL,SAAS,CAACK,QAAQ,GAAGC,MAAM,CAAC,GAAG,QAAQ,EAAE,IAAI,CAACJ,IAAI,CAACG,QAAQ,GAAGC,MAAM,CAAC,IAAI,EAAE,EAAE,IAAI,CAACH,WAAW,IAAI;IACpH;IAEA;;EAEC,GACD,OAAOI,SAASC,IAAsE,EAAc;QACnG,OAAO,IAAIT,WAAWS,KAAKR,SAAS,EAAEQ,KAAKP,iBAAiB,EAAEO,KAAKN,IAAI;IACxE;IAEA;;EAEC,GACDO,SAIE;QACD,OAAO;YACNT,WAAW,IAAI,CAACA,SAAS;YACzBC,mBAAmB,IAAI,CAACA,iBAAiB;YACzCC,MAAM,IAAI,CAACA,IAAI;QAChB;IACD;AACD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a node in the prefix tree used by Drain algorithm.
|
|
3
|
+
*/ export class Node {
|
|
4
|
+
/**
|
|
5
|
+
* Map of token keys to child nodes.
|
|
6
|
+
*/ keyToChildNode = new Map();
|
|
7
|
+
/**
|
|
8
|
+
* List of cluster IDs associated with this node.
|
|
9
|
+
*/ clusterIds = [];
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new empty node.
|
|
12
|
+
*/ static newNode() {
|
|
13
|
+
return new Node();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Converts the node to JSON for serialization.
|
|
17
|
+
*/ toJSON() {
|
|
18
|
+
const keyToChildNode = {};
|
|
19
|
+
for (const [key, node] of this.keyToChildNode){
|
|
20
|
+
keyToChildNode[key] = node.toJSON();
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
keyToChildNode,
|
|
24
|
+
clusterIds: this.clusterIds
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Creates a Node from JSON data.
|
|
29
|
+
*/ static fromJSON(data) {
|
|
30
|
+
const node = new Node();
|
|
31
|
+
node.clusterIds = data.clusterIds;
|
|
32
|
+
for (const [key, childData] of Object.entries(data.keyToChildNode)){
|
|
33
|
+
node.keyToChildNode.set(key, Node.fromJSON(childData));
|
|
34
|
+
}
|
|
35
|
+
return node;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=Node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/drain3/Node.ts"],"sourcesContent":["/**\n * Represents a node in the prefix tree used by Drain algorithm.\n */\nexport class Node {\n\t/**\n\t * Map of token keys to child nodes.\n\t */\n\tpublic readonly keyToChildNode: Map<string, Node> = new Map();\n\n\t/**\n\t * List of cluster IDs associated with this node.\n\t */\n\tpublic clusterIds: number[] = [];\n\n\t/**\n\t * Creates a new empty node.\n\t */\n\tstatic newNode(): Node {\n\t\treturn new Node();\n\t}\n\n\t/**\n\t * Converts the node to JSON for serialization.\n\t */\n\ttoJSON(): {\n\t\tkeyToChildNode: Record<string, unknown>;\n\t\tclusterIds: number[];\n\t} {\n\t\tconst keyToChildNode: Record<string, unknown> = {};\n\t\tfor (const [key, node] of this.keyToChildNode) {\n\t\t\tkeyToChildNode[key] = node.toJSON();\n\t\t}\n\t\treturn {\n\t\t\tkeyToChildNode,\n\t\t\tclusterIds: this.clusterIds,\n\t\t};\n\t}\n\n\t/**\n\t * Creates a Node from JSON data.\n\t */\n\tstatic fromJSON(data: { keyToChildNode: Record<string, unknown>; clusterIds: number[] }): Node {\n\t\tconst node = new Node();\n\t\tnode.clusterIds = data.clusterIds;\n\t\tfor (const [key, childData] of Object.entries(data.keyToChildNode)) {\n\t\t\tnode.keyToChildNode.set(\n\t\t\t\tkey,\n\t\t\t\tNode.fromJSON(childData as { keyToChildNode: Record<string, unknown>; clusterIds: number[] }),\n\t\t\t);\n\t\t}\n\t\treturn node;\n\t}\n}\n"],"names":["Node","keyToChildNode","Map","clusterIds","newNode","toJSON","key","node","fromJSON","data","childData","Object","entries","set"],"mappings":"AAAA;;CAEC,GACD,OAAO,MAAMA;IACZ;;EAEC,GACD,AAAgBC,iBAAoC,IAAIC,MAAM;IAE9D;;EAEC,GACD,AAAOC,aAAuB,EAAE,CAAC;IAEjC;;EAEC,GACD,OAAOC,UAAgB;QACtB,OAAO,IAAIJ;IACZ;IAEA;;EAEC,GACDK,SAGE;QACD,MAAMJ,iBAA0C,CAAC;QACjD,KAAK,MAAM,CAACK,KAAKC,KAAK,IAAI,IAAI,CAACN,cAAc,CAAE;YAC9CA,cAAc,CAACK,IAAI,GAAGC,KAAKF,MAAM;QAClC;QACA,OAAO;YACNJ;YACAE,YAAY,IAAI,CAACA,UAAU;QAC5B;IACD;IAEA;;EAEC,GACD,OAAOK,SAASC,IAAuE,EAAQ;QAC9F,MAAMF,OAAO,IAAIP;QACjBO,KAAKJ,UAAU,GAAGM,KAAKN,UAAU;QACjC,KAAK,MAAM,CAACG,KAAKI,UAAU,IAAIC,OAAOC,OAAO,CAACH,KAAKR,cAAc,EAAG;YACnEM,KAAKN,cAAc,CAACY,GAAG,CACtBP,KACAN,KAAKQ,QAAQ,CAACE;QAEhB;QACA,OAAOH;IACR;AACD"}
|