gt 2.14.35 → 2.14.37
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/CHANGELOG.md +22 -1
- package/dist/api/collectUserEditDiffs.js +112 -155
- package/dist/api/collectUserEditDiffs.js.map +1 -0
- package/dist/api/downloadFileBatch.js +164 -241
- package/dist/api/downloadFileBatch.js.map +1 -0
- package/dist/api/saveLocalEdits.js +37 -41
- package/dist/api/saveLocalEdits.js.map +1 -0
- package/dist/bin/bin-entry.js +17 -7
- package/dist/bin/bin-entry.js.map +1 -0
- package/dist/bin/bin-main.js +43 -61
- package/dist/bin/bin-main.js.map +1 -0
- package/dist/cli/base.js +382 -497
- package/dist/cli/base.js.map +1 -0
- package/dist/cli/commands/download.js +41 -49
- package/dist/cli/commands/download.js.map +1 -0
- package/dist/cli/commands/enqueue.js +26 -25
- package/dist/cli/commands/enqueue.js.map +1 -0
- package/dist/cli/commands/setupProject.js +33 -36
- package/dist/cli/commands/setupProject.js.map +1 -0
- package/dist/cli/commands/stage.js +53 -61
- package/dist/cli/commands/stage.js.map +1 -0
- package/dist/cli/commands/translate.js +75 -112
- package/dist/cli/commands/translate.js.map +1 -0
- package/dist/cli/commands/upload.js +185 -213
- package/dist/cli/commands/upload.js.map +1 -0
- package/dist/cli/commands/utils/validation.js +39 -34
- package/dist/cli/commands/utils/validation.js.map +1 -0
- package/dist/cli/flags.js +35 -62
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/inline.js +112 -137
- package/dist/cli/inline.js.map +1 -0
- package/dist/cli/next.js +17 -12
- package/dist/cli/next.js.map +1 -0
- package/dist/cli/node.js +19 -15
- package/dist/cli/node.js.map +1 -0
- package/dist/cli/python.js +13 -8
- package/dist/cli/python.js.map +1 -0
- package/dist/cli/react.js +61 -78
- package/dist/cli/react.js.map +1 -0
- package/dist/config/defaults.js +16 -11
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/generateSettings.js +167 -269
- package/dist/config/generateSettings.js.map +1 -0
- package/dist/config/optionPresets.js +78 -96
- package/dist/config/optionPresets.js.map +1 -0
- package/dist/config/resolveConfig.js +27 -32
- package/dist/config/resolveConfig.js.map +1 -0
- package/dist/config/utils.js +7 -3
- package/dist/config/utils.js.map +1 -0
- package/dist/config/validateSettings.js +19 -30
- package/dist/config/validateSettings.js.map +1 -0
- package/dist/console/colors.js +18 -13
- package/dist/console/colors.js.map +1 -0
- package/dist/console/displayTranslateSummary.js +40 -37
- package/dist/console/displayTranslateSummary.js.map +1 -0
- package/dist/console/formatting.js +8 -5
- package/dist/console/formatting.js.map +1 -0
- package/dist/console/index.d.ts +11 -9
- package/dist/console/index.js +53 -50
- package/dist/console/index.js.map +1 -0
- package/dist/console/inkFields.d.ts +23 -0
- package/dist/console/inkFields.js +87 -0
- package/dist/console/inkFields.js.map +1 -0
- package/dist/console/inkLayout.d.ts +7 -0
- package/dist/console/inkLayout.js +139 -0
- package/dist/console/inkLayout.js.map +1 -0
- package/dist/console/inkLocaleData.d.ts +4 -0
- package/dist/console/inkLocaleData.js +32 -0
- package/dist/console/inkLocaleData.js.map +1 -0
- package/dist/console/inkPrompts.d.ts +8 -0
- package/dist/console/inkPrompts.js +496 -0
- package/dist/console/inkPrompts.js.map +1 -0
- package/dist/console/inkSession.d.ts +3 -0
- package/dist/console/inkSession.js +42 -0
- package/dist/console/inkSession.js.map +1 -0
- package/dist/console/inkTerminal.d.ts +4 -0
- package/dist/console/inkTerminal.js +15 -0
- package/dist/console/inkTerminal.js.map +1 -0
- package/dist/console/inkTypes.d.ts +66 -0
- package/dist/console/inkTypes.js +1 -0
- package/dist/console/inkUtils.d.ts +24 -0
- package/dist/console/inkUtils.js +87 -0
- package/dist/console/inkUtils.js.map +1 -0
- package/dist/console/logger.js +209 -249
- package/dist/console/logger.js.map +1 -0
- package/dist/console/logging.d.ts +14 -0
- package/dist/console/logging.js +203 -162
- package/dist/console/logging.js.map +1 -0
- package/dist/console/promptParsing.d.ts +5 -0
- package/dist/console/promptParsing.js +28 -0
- package/dist/console/promptParsing.js.map +1 -0
- package/dist/console/terminalSession.d.ts +5 -0
- package/dist/console/terminalSession.js +38 -0
- package/dist/console/terminalSession.js.map +1 -0
- package/dist/extraction/index.js +3 -2
- package/dist/extraction/mapToUpdates.js +19 -18
- package/dist/extraction/mapToUpdates.js.map +1 -0
- package/dist/extraction/postProcess.js +68 -86
- package/dist/extraction/postProcess.js.map +1 -0
- package/dist/formats/files/aggregateFiles.js +223 -304
- package/dist/formats/files/aggregateFiles.js.map +1 -0
- package/dist/formats/files/collectFiles.js +53 -54
- package/dist/formats/files/collectFiles.js.map +1 -0
- package/dist/formats/files/convertToFileTranslationData.js +21 -19
- package/dist/formats/files/convertToFileTranslationData.js.map +1 -0
- package/dist/formats/files/fileMapping.js +82 -119
- package/dist/formats/files/fileMapping.js.map +1 -0
- package/dist/formats/files/preprocess/mdx.js +15 -12
- package/dist/formats/files/preprocess/mdx.js.map +1 -0
- package/dist/formats/files/preprocess/mintlify.js +15 -13
- package/dist/formats/files/preprocess/mintlify.js.map +1 -0
- package/dist/formats/files/preprocessContent.js +20 -21
- package/dist/formats/files/preprocessContent.js.map +1 -0
- package/dist/formats/files/save.js +18 -15
- package/dist/formats/files/save.js.map +1 -0
- package/dist/formats/files/supportedFiles.js +27 -22
- package/dist/formats/files/supportedFiles.js.map +1 -0
- package/dist/formats/files/transformFormat.js +93 -100
- package/dist/formats/files/transformFormat.js.map +1 -0
- package/dist/formats/json/extractJson.js +83 -110
- package/dist/formats/json/extractJson.js.map +1 -0
- package/dist/formats/json/flattenJson.js +41 -48
- package/dist/formats/json/flattenJson.js.map +1 -0
- package/dist/formats/json/jsonPath.js +20 -15
- package/dist/formats/json/jsonPath.js.map +1 -0
- package/dist/formats/json/jsonPointer.js +17 -17
- package/dist/formats/json/jsonPointer.js.map +1 -0
- package/dist/formats/json/mergeJson.js +230 -371
- package/dist/formats/json/mergeJson.js.map +1 -0
- package/dist/formats/json/parseJson.js +74 -111
- package/dist/formats/json/parseJson.js.map +1 -0
- package/dist/formats/json/transformJson.js +53 -61
- package/dist/formats/json/transformJson.js.map +1 -0
- package/dist/formats/json/utils.js +158 -187
- package/dist/formats/json/utils.js.map +1 -0
- package/dist/formats/parseKeyedMetadata.js +85 -106
- package/dist/formats/parseKeyedMetadata.js.map +1 -0
- package/dist/formats/utils.js +13 -23
- package/dist/formats/utils.js.map +1 -0
- package/dist/formats/yaml/extractYaml.js +32 -31
- package/dist/formats/yaml/extractYaml.js.map +1 -0
- package/dist/formats/yaml/mergeYaml.js +43 -60
- package/dist/formats/yaml/mergeYaml.js.map +1 -0
- package/dist/formats/yaml/parseYaml.js +34 -23
- package/dist/formats/yaml/parseYaml.js.map +1 -0
- package/dist/formats/yaml/utils.js +19 -21
- package/dist/formats/yaml/utils.js.map +1 -0
- package/dist/fs/clearLocaleDirs.js +82 -114
- package/dist/fs/clearLocaleDirs.js.map +1 -0
- package/dist/fs/config/downloadedVersions.js +174 -188
- package/dist/fs/config/downloadedVersions.js.map +1 -0
- package/dist/fs/config/loadConfig.js +12 -8
- package/dist/fs/config/loadConfig.js.map +1 -0
- package/dist/fs/config/parseFilesConfig.js +166 -227
- package/dist/fs/config/parseFilesConfig.js.map +1 -0
- package/dist/fs/config/setupConfig.js +43 -52
- package/dist/fs/config/setupConfig.js.map +1 -0
- package/dist/fs/config/updateConfig.js +44 -56
- package/dist/fs/config/updateConfig.js.map +1 -0
- package/dist/fs/config/updateVersions.js +27 -28
- package/dist/fs/config/updateVersions.js.map +1 -0
- package/dist/fs/copyFile.js +33 -37
- package/dist/fs/copyFile.js.map +1 -0
- package/dist/fs/createLoadTranslationsFile.js +32 -48
- package/dist/fs/createLoadTranslationsFile.js.map +1 -0
- package/dist/fs/determineFramework/detectPythonLibrary.js +30 -34
- package/dist/fs/determineFramework/detectPythonLibrary.js.map +1 -0
- package/dist/fs/determineFramework/index.js +46 -64
- package/dist/fs/determineFramework/index.js.map +1 -0
- package/dist/fs/determineFramework/matchPyprojectDependency.js +65 -78
- package/dist/fs/determineFramework/matchPyprojectDependency.js.map +1 -0
- package/dist/fs/determineFramework/matchRequirementsTxtDependency.js +21 -19
- package/dist/fs/determineFramework/matchRequirementsTxtDependency.js.map +1 -0
- package/dist/fs/determineFramework/matchSetupPyDependency.js +60 -81
- package/dist/fs/determineFramework/matchSetupPyDependency.js.map +1 -0
- package/dist/fs/determineFramework/resolveGtDependency.js +15 -15
- package/dist/fs/determineFramework/resolveGtDependency.js.map +1 -0
- package/dist/fs/findFilepath.js +63 -78
- package/dist/fs/findFilepath.js.map +1 -0
- package/dist/fs/loadJSON.js +18 -15
- package/dist/fs/loadJSON.js.map +1 -0
- package/dist/fs/matchFiles.js +12 -7
- package/dist/fs/matchFiles.js.map +1 -0
- package/dist/fs/saveJSON.js +10 -6
- package/dist/fs/saveJSON.js.map +1 -0
- package/dist/fs/utils.js +19 -15
- package/dist/fs/utils.js.map +1 -0
- package/dist/functions.d.ts +2 -1
- package/dist/functions.js +3 -6
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +6 -2
- package/dist/generated/version.js.map +1 -0
- package/dist/git/branches.js +77 -83
- package/dist/git/branches.js.map +1 -0
- package/dist/hooks/postProcess.js +97 -114
- package/dist/hooks/postProcess.js.map +1 -0
- package/dist/index.js +23 -31
- package/dist/index.js.map +1 -0
- package/dist/locadex/setupFlow.js +11 -8
- package/dist/locadex/setupFlow.js.map +1 -0
- package/dist/main.js +17 -7
- package/dist/main.js.map +1 -0
- package/dist/next/config/parseNextConfig.js +32 -51
- package/dist/next/config/parseNextConfig.js.map +1 -0
- package/dist/next/jsx/utils.js +25 -37
- package/dist/next/jsx/utils.js.map +1 -0
- package/dist/next/parse/handleInitGT.js +87 -154
- package/dist/next/parse/handleInitGT.js.map +1 -0
- package/dist/next/parse/wrapContent.js +136 -158
- package/dist/next/parse/wrapContent.js.map +1 -0
- package/dist/python/parse/createPythonInlineUpdates.js +36 -33
- package/dist/python/parse/createPythonInlineUpdates.js.map +1 -0
- package/dist/react/config/createESBuildConfig.js +115 -115
- package/dist/react/config/createESBuildConfig.js.map +1 -0
- package/dist/react/jsx/evaluateJsx.js +90 -124
- package/dist/react/jsx/evaluateJsx.js.map +1 -0
- package/dist/react/jsx/utils/buildImportMap.js +24 -28
- package/dist/react/jsx/utils/buildImportMap.js.map +1 -0
- package/dist/react/jsx/utils/constants.js +79 -87
- package/dist/react/jsx/utils/constants.js.map +1 -0
- package/dist/react/jsx/utils/extractSourceCode.js +36 -37
- package/dist/react/jsx/utils/extractSourceCode.js.map +1 -0
- package/dist/react/jsx/utils/getCalleeNameFromExpression.js +30 -30
- package/dist/react/jsx/utils/getCalleeNameFromExpression.js.map +1 -0
- package/dist/react/jsx/utils/getPathsAndAliases.js +70 -105
- package/dist/react/jsx/utils/getPathsAndAliases.js.map +1 -0
- package/dist/react/jsx/utils/isNumberLiteral.js +13 -11
- package/dist/react/jsx/utils/isNumberLiteral.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.js +103 -148
- package/dist/react/jsx/utils/jsxParsing/addGTIdentifierToSyntaxTree.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/autoInsertion.js +305 -389
- package/dist/react/jsx/utils/jsxParsing/autoInsertion.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js +122 -193
- package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.js +50 -64
- package/dist/react/jsx/utils/jsxParsing/multiplication/findMultiplicationNode.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.js +41 -68
- package/dist/react/jsx/utils/jsxParsing/multiplication/multiplyJsxTree.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/parseJsx.js +760 -1107
- package/dist/react/jsx/utils/jsxParsing/parseJsx.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/parseTProps.js +35 -71
- package/dist/react/jsx/utils/jsxParsing/parseTProps.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.js +39 -58
- package/dist/react/jsx/utils/jsxParsing/removeNullChildrenFields.js.map +1 -0
- package/dist/react/jsx/utils/jsxParsing/types.js +10 -24
- package/dist/react/jsx/utils/jsxParsing/types.js.map +1 -0
- package/dist/react/jsx/utils/mapAttributeName.js +13 -13
- package/dist/react/jsx/utils/mapAttributeName.js.map +1 -0
- package/dist/react/jsx/utils/parseAst.js +142 -272
- package/dist/react/jsx/utils/parseAst.js.map +1 -0
- package/dist/react/jsx/utils/parseString.js +726 -1090
- package/dist/react/jsx/utils/parseString.js.map +1 -0
- package/dist/react/jsx/utils/parseStringFunction.js +274 -401
- package/dist/react/jsx/utils/parseStringFunction.js.map +1 -0
- package/dist/react/jsx/utils/resolveImportPath.d.ts +1 -1
- package/dist/react/jsx/utils/resolveImportPath.js +125 -108
- package/dist/react/jsx/utils/resolveImportPath.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/derivation/containsDeriveCall.js +18 -24
- package/dist/react/jsx/utils/stringParsing/derivation/containsDeriveCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/derivation/handleDerivation.js +412 -579
- package/dist/react/jsx/utils/stringParsing/derivation/handleDerivation.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/derivation/index.js +57 -67
- package/dist/react/jsx/utils/stringParsing/derivation/index.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.js +26 -36
- package/dist/react/jsx/utils/stringParsing/derivation/isDeriveCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/handleTaggedTemplateTranslationCall.js +29 -24
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/handleTaggedTemplateTranslationCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/index.js +34 -32
- package/dist/react/jsx/utils/stringParsing/processTaggedTemplateCall/index.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/extractStringEntryMetadata.js +80 -117
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/extractStringEntryMetadata.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleDeriveTranslationCall.js +24 -19
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleDeriveTranslationCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleInvalidTranslationCall.js +18 -21
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleInvalidTranslationCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleLiteralTranslationCall.js +45 -50
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/handleLiteralTranslationCall.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/index.js +54 -59
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/index.js.map +1 -0
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/routeTranslationCall.js +56 -69
- package/dist/react/jsx/utils/stringParsing/processTranslationCall/routeTranslationCall.js.map +1 -0
- package/dist/react/jsx/utils/validateStringFunction.js +21 -29
- package/dist/react/jsx/utils/validateStringFunction.js.map +1 -0
- package/dist/react/jsx/wrapJsx.js +192 -375
- package/dist/react/jsx/wrapJsx.js.map +1 -0
- package/dist/react/parse/addVitePlugin/index.js +40 -34
- package/dist/react/parse/addVitePlugin/index.js.map +1 -0
- package/dist/react/parse/addVitePlugin/installCompiler.js +18 -20
- package/dist/react/parse/addVitePlugin/installCompiler.js.map +1 -0
- package/dist/react/parse/addVitePlugin/updateViteConfig.js +107 -111
- package/dist/react/parse/addVitePlugin/updateViteConfig.js.map +1 -0
- package/dist/react/parse/addVitePlugin/utils/addCompilerImport.js +23 -26
- package/dist/react/parse/addVitePlugin/utils/addCompilerImport.js.map +1 -0
- package/dist/react/parse/addVitePlugin/utils/addPluginInvocation.js +29 -43
- package/dist/react/parse/addVitePlugin/utils/addPluginInvocation.js.map +1 -0
- package/dist/react/parse/addVitePlugin/utils/checkCompilerImport.js +70 -104
- package/dist/react/parse/addVitePlugin/utils/checkCompilerImport.js.map +1 -0
- package/dist/react/parse/addVitePlugin/utils/checkPluginInvocation.js +23 -29
- package/dist/react/parse/addVitePlugin/utils/checkPluginInvocation.js.map +1 -0
- package/dist/react/parse/createDictionaryUpdates.js +121 -185
- package/dist/react/parse/createDictionaryUpdates.js.map +1 -0
- package/dist/react/parse/createInlineUpdates.js +123 -139
- package/dist/react/parse/createInlineUpdates.js.map +1 -0
- package/dist/react/parse/wrapContent.js +131 -156
- package/dist/react/parse/wrapContent.js.map +1 -0
- package/dist/react/utils/flattenDictionary.js +55 -70
- package/dist/react/utils/flattenDictionary.js.map +1 -0
- package/dist/react/utils/getEntryAndMetadata.js +14 -10
- package/dist/react/utils/getEntryAndMetadata.js.map +1 -0
- package/dist/react/utils/getVariableName.js +36 -33
- package/dist/react/utils/getVariableName.js.map +1 -0
- package/dist/setup/detectFramework.js +85 -102
- package/dist/setup/detectFramework.js.map +1 -0
- package/dist/setup/frameworkUtils.js +17 -28
- package/dist/setup/frameworkUtils.js.map +1 -0
- package/dist/setup/userInput.js +24 -31
- package/dist/setup/userInput.js.map +1 -0
- package/dist/setup/wizard.js +141 -143
- package/dist/setup/wizard.js.map +1 -0
- package/dist/state/mintlifyRefMap.js +12 -9
- package/dist/state/mintlifyRefMap.js.map +1 -0
- package/dist/state/recentDownloads.js +26 -23
- package/dist/state/recentDownloads.js.map +1 -0
- package/dist/state/translateWarnings.js +17 -8
- package/dist/state/translateWarnings.js.map +1 -0
- package/dist/translation/parse.js +77 -98
- package/dist/translation/parse.js.map +1 -0
- package/dist/translation/stage.js +28 -43
- package/dist/translation/stage.js.map +1 -0
- package/dist/translation/validate.js +68 -91
- package/dist/translation/validate.js.map +1 -0
- package/dist/types/libraries.js +93 -91
- package/dist/types/libraries.js.map +1 -0
- package/dist/types/parsing.js +19 -10
- package/dist/types/parsing.js.map +1 -0
- package/dist/utils/addExplicitAnchorIds.js +270 -389
- package/dist/utils/addExplicitAnchorIds.js.map +1 -0
- package/dist/utils/calculateTimeoutMs.js +11 -6
- package/dist/utils/calculateTimeoutMs.js.map +1 -0
- package/dist/utils/constants.js +15 -12
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/credentials.js +67 -114
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/fetch.js +22 -20
- package/dist/utils/fetch.js.map +1 -0
- package/dist/utils/flattenJsonFiles.js +27 -34
- package/dist/utils/flattenJsonFiles.js.map +1 -0
- package/dist/utils/gitDiff.js +30 -32
- package/dist/utils/gitDiff.js.map +1 -0
- package/dist/utils/gt.js +7 -2
- package/dist/utils/gt.js.map +1 -0
- package/dist/utils/hash.js +14 -9
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/headers.js +10 -13
- package/dist/utils/headers.js.map +1 -0
- package/dist/utils/installPackage.js +70 -75
- package/dist/utils/installPackage.js.map +1 -0
- package/dist/utils/localizeRelativeAssets.js +114 -157
- package/dist/utils/localizeRelativeAssets.js.map +1 -0
- package/dist/utils/localizeStaticImports.js +229 -371
- package/dist/utils/localizeStaticImports.js.map +1 -0
- package/dist/utils/localizeStaticUrls.js +241 -424
- package/dist/utils/localizeStaticUrls.js.map +1 -0
- package/dist/utils/mintlifyTitleFallback.js +64 -72
- package/dist/utils/mintlifyTitleFallback.js.map +1 -0
- package/dist/utils/monorepoVersionCheck.js +177 -215
- package/dist/utils/monorepoVersionCheck.js.map +1 -0
- package/dist/utils/packageInfo.js +17 -16
- package/dist/utils/packageInfo.js.map +1 -0
- package/dist/utils/packageJson.js +51 -66
- package/dist/utils/packageJson.js.map +1 -0
- package/dist/utils/packageManager.js +237 -260
- package/dist/utils/packageManager.js.map +1 -0
- package/dist/utils/parse/needsCJS.js +36 -69
- package/dist/utils/parse/needsCJS.js.map +1 -0
- package/dist/utils/persistPostprocessHashes.js +30 -32
- package/dist/utils/persistPostprocessHashes.js.map +1 -0
- package/dist/utils/processAnchorIds.js +32 -54
- package/dist/utils/processAnchorIds.js.map +1 -0
- package/dist/utils/processOpenApi.js +469 -578
- package/dist/utils/processOpenApi.js.map +1 -0
- package/dist/utils/resolveMintlifyRefs.js +89 -105
- package/dist/utils/resolveMintlifyRefs.js.map +1 -0
- package/dist/utils/resolvePublish.js +46 -54
- package/dist/utils/resolvePublish.js.map +1 -0
- package/dist/utils/sanitizeFileContent.js +20 -27
- package/dist/utils/sanitizeFileContent.js.map +1 -0
- package/dist/utils/sharedStaticAssets.js +248 -366
- package/dist/utils/sharedStaticAssets.js.map +1 -0
- package/dist/utils/splitMintlifyLanguageRefs.js +208 -282
- package/dist/utils/splitMintlifyLanguageRefs.js.map +1 -0
- package/dist/utils/validateMdx.js +26 -23
- package/dist/utils/validateMdx.js.map +1 -0
- package/dist/utils/wrapPlainUrls.js +58 -70
- package/dist/utils/wrapPlainUrls.js.map +1 -0
- package/dist/workflows/download.js +92 -126
- package/dist/workflows/download.js.map +1 -0
- package/dist/workflows/enqueue.js +47 -54
- package/dist/workflows/enqueue.js.map +1 -0
- package/dist/workflows/publish.js +29 -29
- package/dist/workflows/publish.js.map +1 -0
- package/dist/workflows/setupProject.js +39 -40
- package/dist/workflows/setupProject.js.map +1 -0
- package/dist/workflows/stage.js +61 -65
- package/dist/workflows/stage.js.map +1 -0
- package/dist/workflows/steps/BranchStep.js +118 -163
- package/dist/workflows/steps/BranchStep.js.map +1 -0
- package/dist/workflows/steps/DownloadStep.js +107 -137
- package/dist/workflows/steps/DownloadStep.js.map +1 -0
- package/dist/workflows/steps/EnqueueStep.js +32 -32
- package/dist/workflows/steps/EnqueueStep.js.map +1 -0
- package/dist/workflows/steps/PollJobsStep.js +208 -292
- package/dist/workflows/steps/PollJobsStep.js.map +1 -0
- package/dist/workflows/steps/PublishStep.js +33 -38
- package/dist/workflows/steps/PublishStep.js.map +1 -0
- package/dist/workflows/steps/SetupStep.js +71 -72
- package/dist/workflows/steps/SetupStep.js.map +1 -0
- package/dist/workflows/steps/TagStep.js +39 -44
- package/dist/workflows/steps/TagStep.js.map +1 -0
- package/dist/workflows/steps/UploadSourcesStep.js +108 -140
- package/dist/workflows/steps/UploadSourcesStep.js.map +1 -0
- package/dist/workflows/steps/UploadTranslationsStep.js +61 -71
- package/dist/workflows/steps/UploadTranslationsStep.js.map +1 -0
- package/dist/workflows/steps/UserEditDiffsStep.js +32 -34
- package/dist/workflows/steps/UserEditDiffsStep.js.map +1 -0
- package/dist/workflows/steps/WorkflowStep.js +6 -2
- package/dist/workflows/steps/WorkflowStep.js.map +1 -0
- package/dist/workflows/upload.js +45 -46
- package/dist/workflows/upload.js.map +1 -0
- package/package.json +14 -7
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { unified } from
|
|
2
|
-
import remarkParse from
|
|
3
|
-
import remarkMdx from
|
|
4
|
-
import remarkFrontmatter from
|
|
1
|
+
import { unified } from "unified";
|
|
2
|
+
import remarkParse from "remark-parse";
|
|
3
|
+
import remarkMdx from "remark-mdx";
|
|
4
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
5
|
+
//#region src/utils/validateMdx.ts
|
|
5
6
|
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return { isValid: false, error: errorMessage };
|
|
24
|
-
}
|
|
7
|
+
* Validates if an MDX file content can be parsed as a valid AST
|
|
8
|
+
* @param content - The MDX file content to validate
|
|
9
|
+
* @param filePath - The file path for error reporting
|
|
10
|
+
* @returns object with isValid boolean and optional error message
|
|
11
|
+
*/
|
|
12
|
+
function isValidMdx(content, _filePath) {
|
|
13
|
+
try {
|
|
14
|
+
const parseProcessor = unified().use(remarkParse).use(remarkFrontmatter, ["yaml", "toml"]).use(remarkMdx);
|
|
15
|
+
const ast = parseProcessor.parse(content);
|
|
16
|
+
parseProcessor.runSync(ast);
|
|
17
|
+
return { isValid: true };
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return {
|
|
20
|
+
isValid: false,
|
|
21
|
+
error: error instanceof Error ? error.message : String(error)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
25
24
|
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { isValidMdx };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=validateMdx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateMdx.js","names":[],"sources":["../../src/utils/validateMdx.ts"],"sourcesContent":["import { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkMdx from 'remark-mdx';\nimport remarkFrontmatter from 'remark-frontmatter';\n\n/**\n * Validates if an MDX file content can be parsed as a valid AST\n * @param content - The MDX file content to validate\n * @param filePath - The file path for error reporting\n * @returns object with isValid boolean and optional error message\n */\nexport function isValidMdx(\n content: string,\n _filePath: string\n): {\n isValid: boolean;\n error?: string;\n} {\n try {\n const parseProcessor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, ['yaml', 'toml'])\n .use(remarkMdx);\n\n const ast = parseProcessor.parse(content);\n parseProcessor.runSync(ast);\n return { isValid: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return { isValid: false, error: errorMessage };\n }\n}\n"],"mappings":";;;;;;;;;;;AAWA,SAAgB,WACd,SACA,WAIA;AACA,KAAI;EACF,MAAM,iBAAiB,SAAS,CAC7B,IAAI,YAAY,CAChB,IAAI,mBAAmB,CAAC,QAAQ,OAAO,CAAC,CACxC,IAAI,UAAU;EAEjB,MAAM,MAAM,eAAe,MAAM,QAAQ;AACzC,iBAAe,QAAQ,IAAI;AAC3B,SAAO,EAAE,SAAS,MAAM;UACjB,OAAO;AAEd,SAAO;GAAE,SAAS;GAAO,OADJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;GAC7B"}
|
|
@@ -1,72 +1,60 @@
|
|
|
1
|
-
import { unified } from
|
|
2
|
-
import remarkParse from
|
|
3
|
-
import remarkMdx from
|
|
4
|
-
import remarkFrontmatter from
|
|
5
|
-
import { visit } from
|
|
1
|
+
import { unified } from "unified";
|
|
2
|
+
import remarkParse from "remark-parse";
|
|
3
|
+
import remarkMdx from "remark-mdx";
|
|
4
|
+
import remarkFrontmatter from "remark-frontmatter";
|
|
5
|
+
import { visit } from "unist-util-visit";
|
|
6
|
+
//#region src/utils/wrapPlainUrls.ts
|
|
6
7
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// Calculate the absolute offset in the original content
|
|
58
|
-
const urlStart = nodeStartOffset + match.index;
|
|
59
|
-
const urlEnd = urlStart + url.length;
|
|
60
|
-
replacements.push({ start: urlStart, end: urlEnd, url });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
if (replacements.length === 0)
|
|
64
|
-
return content;
|
|
65
|
-
// Apply replacements in reverse order to preserve positions
|
|
66
|
-
let result = content;
|
|
67
|
-
for (let i = replacements.length - 1; i >= 0; i--) {
|
|
68
|
-
const { start, end, url } = replacements[i];
|
|
69
|
-
result = result.slice(0, start) + `[${url}](${url})` + result.slice(end);
|
|
70
|
-
}
|
|
71
|
-
return result;
|
|
8
|
+
* Wraps plain URLs in markdown link syntax [url](url) so that
|
|
9
|
+
* translation pipelines preserve the URL separately from surrounding text.
|
|
10
|
+
*
|
|
11
|
+
* Uses remark AST parsing to identify URLs that appear in text nodes only.
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
function wrapPlainUrls(content) {
|
|
15
|
+
const URL_REGEX = /https?:\/\/[^\s<>\u005b\u005d]*[^\s<>\u005b\u005d.,;:!?'"\u005d}>]/g;
|
|
16
|
+
let ast;
|
|
17
|
+
try {
|
|
18
|
+
const processor = unified().use(remarkParse).use(remarkFrontmatter, ["yaml", "toml"]).use(remarkMdx);
|
|
19
|
+
ast = processor.parse(content);
|
|
20
|
+
ast = processor.runSync(ast);
|
|
21
|
+
} catch {
|
|
22
|
+
return content;
|
|
23
|
+
}
|
|
24
|
+
const replacements = [];
|
|
25
|
+
visit(ast, "text", (node, _index, parent) => {
|
|
26
|
+
if (parent && parent.type === "link") return;
|
|
27
|
+
const pos = node.position;
|
|
28
|
+
if (!pos) return;
|
|
29
|
+
const value = node.value;
|
|
30
|
+
let match;
|
|
31
|
+
while ((match = URL_REGEX.exec(value)) !== null) {
|
|
32
|
+
let url = match[0];
|
|
33
|
+
const nodeStartOffset = pos.start.offset;
|
|
34
|
+
if (nodeStartOffset === void 0) continue;
|
|
35
|
+
while (url.endsWith(")")) {
|
|
36
|
+
const open = url.split("(").length - 1;
|
|
37
|
+
if (url.split(")").length - 1 > open) url = url.slice(0, -1);
|
|
38
|
+
else break;
|
|
39
|
+
}
|
|
40
|
+
const urlStart = nodeStartOffset + match.index;
|
|
41
|
+
const urlEnd = urlStart + url.length;
|
|
42
|
+
replacements.push({
|
|
43
|
+
start: urlStart,
|
|
44
|
+
end: urlEnd,
|
|
45
|
+
url
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if (replacements.length === 0) return content;
|
|
50
|
+
let result = content;
|
|
51
|
+
for (let i = replacements.length - 1; i >= 0; i--) {
|
|
52
|
+
const { start, end, url } = replacements[i];
|
|
53
|
+
result = result.slice(0, start) + `[${url}](${url})` + result.slice(end);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
72
56
|
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { wrapPlainUrls as default };
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=wrapPlainUrls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapPlainUrls.js","names":[],"sources":["../../src/utils/wrapPlainUrls.ts"],"sourcesContent":["import { unified } from 'unified';\nimport remarkParse from 'remark-parse';\nimport remarkMdx from 'remark-mdx';\nimport remarkFrontmatter from 'remark-frontmatter';\nimport { visit } from 'unist-util-visit';\nimport type { Root, Text } from 'mdast';\n\n/**\n * Wraps plain URLs in markdown link syntax [url](url) so that\n * translation pipelines preserve the URL separately from surrounding text.\n *\n * Uses remark AST parsing to identify URLs that appear in text nodes only.\n *\n */\nexport default function wrapPlainUrls(content: string): string {\n const URL_REGEX =\n /https?:\\/\\/[^\\s<>\\u005b\\u005d]*[^\\s<>\\u005b\\u005d.,;:!?'\"\\u005d}>]/g;\n let ast: Root;\n try {\n const processor = unified()\n .use(remarkParse)\n .use(remarkFrontmatter, ['yaml', 'toml'])\n .use(remarkMdx);\n\n ast = processor.parse(content);\n ast = processor.runSync(ast) as Root;\n } catch {\n // If parsing fails, return content unchanged\n return content;\n }\n\n // Collect all URL replacements from text nodes with their positions\n const replacements: { start: number; end: number; url: string }[] = [];\n\n visit(ast, 'text', (node: Text, _index, parent) => {\n // Skip text nodes inside links — those are already display text for a link\n if (parent && parent.type === 'link') return;\n\n const pos = node.position;\n if (!pos) return;\n\n const value = node.value;\n let match: RegExpExecArray | null;\n\n while ((match = URL_REGEX.exec(value)) !== null) {\n let url = match[0];\n const nodeStartOffset = pos.start.offset;\n if (nodeStartOffset === undefined) continue;\n\n // Trim unbalanced trailing ')' so that prose like \"(see https://example.com)\"\n // doesn't absorb the surrounding paren, while Wikipedia-style URLs with\n // balanced parens (e.g. /wiki/Unix_(operating_system)) are kept intact.\n while (url.endsWith(')')) {\n const open = url.split('(').length - 1;\n const close = url.split(')').length - 1;\n if (close > open) {\n url = url.slice(0, -1);\n } else {\n break;\n }\n }\n\n // Calculate the absolute offset in the original content\n const urlStart = nodeStartOffset + match.index;\n const urlEnd = urlStart + url.length;\n\n replacements.push({ start: urlStart, end: urlEnd, url });\n }\n });\n\n if (replacements.length === 0) return content;\n\n // Apply replacements in reverse order to preserve positions\n let result = content;\n for (let i = replacements.length - 1; i >= 0; i--) {\n const { start, end, url } = replacements[i];\n result = result.slice(0, start) + `[${url}](${url})` + result.slice(end);\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAwB,cAAc,SAAyB;CAC7D,MAAM,YACJ;CACF,IAAI;AACJ,KAAI;EACF,MAAM,YAAY,SAAS,CACxB,IAAI,YAAY,CAChB,IAAI,mBAAmB,CAAC,QAAQ,OAAO,CAAC,CACxC,IAAI,UAAU;AAEjB,QAAM,UAAU,MAAM,QAAQ;AAC9B,QAAM,UAAU,QAAQ,IAAI;SACtB;AAEN,SAAO;;CAIT,MAAM,eAA8D,EAAE;AAEtE,OAAM,KAAK,SAAS,MAAY,QAAQ,WAAW;AAEjD,MAAI,UAAU,OAAO,SAAS,OAAQ;EAEtC,MAAM,MAAM,KAAK;AACjB,MAAI,CAAC,IAAK;EAEV,MAAM,QAAQ,KAAK;EACnB,IAAI;AAEJ,UAAQ,QAAQ,UAAU,KAAK,MAAM,MAAM,MAAM;GAC/C,IAAI,MAAM,MAAM;GAChB,MAAM,kBAAkB,IAAI,MAAM;AAClC,OAAI,oBAAoB,KAAA,EAAW;AAKnC,UAAO,IAAI,SAAS,IAAI,EAAE;IACxB,MAAM,OAAO,IAAI,MAAM,IAAI,CAAC,SAAS;AAErC,QADc,IAAI,MAAM,IAAI,CAAC,SAAS,IAC1B,KACV,OAAM,IAAI,MAAM,GAAG,GAAG;QAEtB;;GAKJ,MAAM,WAAW,kBAAkB,MAAM;GACzC,MAAM,SAAS,WAAW,IAAI;AAE9B,gBAAa,KAAK;IAAE,OAAO;IAAU,KAAK;IAAQ;IAAK,CAAC;;GAE1D;AAEF,KAAI,aAAa,WAAW,EAAG,QAAO;CAGtC,IAAI,SAAS;AACb,MAAK,IAAI,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;EACjD,MAAM,EAAE,OAAO,KAAK,QAAQ,aAAa;AACzC,WAAS,OAAO,MAAM,GAAG,MAAM,GAAG,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,MAAM,IAAI;;AAG1E,QAAO"}
|
|
@@ -1,131 +1,97 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { gt } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import chalk from
|
|
1
|
+
import { logger } from "../console/logger.js";
|
|
2
|
+
import { gt } from "../utils/gt.js";
|
|
3
|
+
import { logErrorAndExit } from "../console/logging.js";
|
|
4
|
+
import { branchResolutionError } from "../console/index.js";
|
|
5
|
+
import { BranchStep } from "./steps/BranchStep.js";
|
|
6
|
+
import { recordWarning } from "../state/translateWarnings.js";
|
|
7
|
+
import { clearLocaleDirs } from "../fs/clearLocaleDirs.js";
|
|
8
|
+
import { PollTranslationJobsStep } from "./steps/PollJobsStep.js";
|
|
9
|
+
import { DownloadTranslationsStep } from "./steps/DownloadStep.js";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
//#region src/workflows/download.ts
|
|
11
13
|
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
// If all files failed translation, exit early
|
|
79
|
-
if (pollResult.fileTracker.completed.size === 0) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Even if polling timed out, still download whatever completed successfully
|
|
84
|
-
if (!pollResult.success) {
|
|
85
|
-
pollTimedOut = true;
|
|
86
|
-
if (pollResult.fileTracker.completed.size > 0) {
|
|
87
|
-
logger.warn(chalk.yellow(`Timed out, but ${pollResult.fileTracker.completed.size} translation(s) completed successfully. Downloading completed files...`));
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
for (const file of fileQueryData) {
|
|
96
|
-
// Staging - assume all files are completed
|
|
97
|
-
fileTracker.completed.set(`${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`, file);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// Step 2: Download translations
|
|
101
|
-
const downloadStep = new DownloadTranslationsStep(gt, options);
|
|
102
|
-
const downloadResult = await downloadStep.run({
|
|
103
|
-
fileTracker,
|
|
104
|
-
resolveOutputPath,
|
|
105
|
-
forceDownload,
|
|
106
|
-
});
|
|
107
|
-
await downloadStep.wait();
|
|
108
|
-
// If polling timed out, report failure even though we downloaded what we could
|
|
109
|
-
if (pollTimedOut) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
return downloadResult;
|
|
14
|
+
* Checks the status of translations and downloads them using a workflow pattern
|
|
15
|
+
* @param fileVersionData - Mapping of file IDs to their version and name information
|
|
16
|
+
* @param jobData - Optional job data from enqueue operation
|
|
17
|
+
* @param locales - The locales to wait for
|
|
18
|
+
* @param timeoutDuration - The timeout duration for the wait in seconds
|
|
19
|
+
* @param resolveOutputPath - Function to resolve the output path for a given source path and locale
|
|
20
|
+
* @param options - Settings configuration
|
|
21
|
+
* @param forceRetranslation - Whether to force retranslation
|
|
22
|
+
* @param forceDownload - Whether to force download even if file exists
|
|
23
|
+
* @returns True if all translations are downloaded successfully, false otherwise
|
|
24
|
+
*/
|
|
25
|
+
async function runDownloadWorkflow({ fileVersionData, jobData, branchData, locales, timeoutDuration, resolveOutputPath, options, forceRetranslation, forceDownload }) {
|
|
26
|
+
if (!branchData) {
|
|
27
|
+
const branchStep = new BranchStep(gt, options);
|
|
28
|
+
const branchResult = await branchStep.run();
|
|
29
|
+
await branchStep.wait();
|
|
30
|
+
if (!branchResult) return logErrorAndExit(branchResolutionError);
|
|
31
|
+
branchData = branchResult;
|
|
32
|
+
}
|
|
33
|
+
const fileQueryData = prepareFileQueryData(fileVersionData, locales, branchData);
|
|
34
|
+
if (options.options?.experimentalClearLocaleDirs === true && fileQueryData.length > 0) {
|
|
35
|
+
const translatedFiles = new Set(fileQueryData.map((file) => {
|
|
36
|
+
const outputPath = resolveOutputPath(file.fileName, file.locale);
|
|
37
|
+
return outputPath !== null && outputPath !== file.fileName ? outputPath : null;
|
|
38
|
+
}).filter((path) => path !== null));
|
|
39
|
+
const cwd = path.dirname(options.config);
|
|
40
|
+
await clearLocaleDirs(translatedFiles, locales, options.options?.clearLocaleDirsExclude, cwd);
|
|
41
|
+
}
|
|
42
|
+
const fileTracker = {
|
|
43
|
+
completed: /* @__PURE__ */ new Map(),
|
|
44
|
+
inProgress: /* @__PURE__ */ new Map(),
|
|
45
|
+
failed: /* @__PURE__ */ new Map(),
|
|
46
|
+
skipped: /* @__PURE__ */ new Map()
|
|
47
|
+
};
|
|
48
|
+
let pollTimedOut = false;
|
|
49
|
+
if (jobData) {
|
|
50
|
+
const pollStep = new PollTranslationJobsStep(gt);
|
|
51
|
+
const pollResult = await pollStep.run({
|
|
52
|
+
fileTracker,
|
|
53
|
+
fileQueryData,
|
|
54
|
+
jobData,
|
|
55
|
+
timeoutDuration,
|
|
56
|
+
forceRetranslation
|
|
57
|
+
});
|
|
58
|
+
await pollStep.wait();
|
|
59
|
+
if (pollResult.fileTracker.failed.size > 0) {
|
|
60
|
+
logger.error(`${chalk.red(`${pollResult.fileTracker.failed.size} file(s) failed to translate:`)}\n${Array.from(pollResult.fileTracker.failed.entries()).map(([, value]) => `- ${value.fileName}`).join("\n")}`);
|
|
61
|
+
for (const [, value] of pollResult.fileTracker.failed) recordWarning("failed_translation", value.fileName, `Failed to translate for locale ${value.locale}`);
|
|
62
|
+
if (pollResult.fileTracker.completed.size === 0) return false;
|
|
63
|
+
}
|
|
64
|
+
if (!pollResult.success) {
|
|
65
|
+
pollTimedOut = true;
|
|
66
|
+
if (pollResult.fileTracker.completed.size > 0) logger.warn(chalk.yellow(`Timed out, but ${pollResult.fileTracker.completed.size} translation(s) completed successfully. Downloading completed files...`));
|
|
67
|
+
else return false;
|
|
68
|
+
}
|
|
69
|
+
} else for (const file of fileQueryData) fileTracker.completed.set(`${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`, file);
|
|
70
|
+
const downloadStep = new DownloadTranslationsStep(gt, options);
|
|
71
|
+
const downloadResult = await downloadStep.run({
|
|
72
|
+
fileTracker,
|
|
73
|
+
resolveOutputPath,
|
|
74
|
+
forceDownload
|
|
75
|
+
});
|
|
76
|
+
await downloadStep.wait();
|
|
77
|
+
if (pollTimedOut) return false;
|
|
78
|
+
return downloadResult;
|
|
113
79
|
}
|
|
114
80
|
/**
|
|
115
|
-
|
|
116
|
-
|
|
81
|
+
* Prepares the file query data from input data and locales
|
|
82
|
+
*/
|
|
117
83
|
function prepareFileQueryData(fileVersionData, locales, branchData) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return fileQueryData;
|
|
84
|
+
const fileQueryData = [];
|
|
85
|
+
for (const fileId in fileVersionData) for (const locale of locales) fileQueryData.push({
|
|
86
|
+
versionId: fileVersionData[fileId].versionId,
|
|
87
|
+
fileName: fileVersionData[fileId].fileName,
|
|
88
|
+
fileId,
|
|
89
|
+
locale,
|
|
90
|
+
branchId: branchData.currentBranch.id
|
|
91
|
+
});
|
|
92
|
+
return fileQueryData;
|
|
131
93
|
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { runDownloadWorkflow };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","names":[],"sources":["../../src/workflows/download.ts"],"sourcesContent":["import path from 'node:path';\nimport { Settings } from '../types/index.js';\nimport { gt } from '../utils/gt.js';\nimport { EnqueueFilesResult } from 'generaltranslation/types';\nimport { clearLocaleDirs } from '../fs/clearLocaleDirs.js';\nimport {\n FileStatusTracker,\n PollTranslationJobsStep,\n} from './steps/PollJobsStep.js';\nimport { DownloadTranslationsStep } from './steps/DownloadStep.js';\nimport { BranchData } from '../types/branch.js';\nimport { branchResolutionError } from '../console/index.js';\nimport { logErrorAndExit } from '../console/logging.js';\nimport { logger } from '../console/logger.js';\nimport { recordWarning } from '../state/translateWarnings.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { FileProperties } from '../types/files.js';\nimport chalk from 'chalk';\n\nexport type FileTranslationData = {\n [fileId: string]: {\n versionId: string;\n fileName: string;\n };\n};\n\n/**\n * Checks the status of translations and downloads them using a workflow pattern\n * @param fileVersionData - Mapping of file IDs to their version and name information\n * @param jobData - Optional job data from enqueue operation\n * @param locales - The locales to wait for\n * @param timeoutDuration - The timeout duration for the wait in seconds\n * @param resolveOutputPath - Function to resolve the output path for a given source path and locale\n * @param options - Settings configuration\n * @param forceRetranslation - Whether to force retranslation\n * @param forceDownload - Whether to force download even if file exists\n * @returns True if all translations are downloaded successfully, false otherwise\n */\nexport async function runDownloadWorkflow({\n fileVersionData,\n jobData,\n branchData,\n locales,\n timeoutDuration,\n resolveOutputPath,\n options,\n forceRetranslation,\n forceDownload,\n}: {\n fileVersionData: FileTranslationData;\n jobData: EnqueueFilesResult | undefined;\n branchData: BranchData | undefined;\n locales: string[];\n timeoutDuration: number;\n resolveOutputPath: (sourcePath: string, locale: string) => string | null;\n options: Settings;\n forceRetranslation?: boolean;\n forceDownload?: boolean;\n}): Promise<boolean> {\n if (!branchData) {\n // Run the branch step\n const branchStep = new BranchStep(gt, options);\n const branchResult = await branchStep.run();\n await branchStep.wait();\n if (!branchResult) {\n return logErrorAndExit(branchResolutionError);\n }\n branchData = branchResult;\n }\n // Prepare the query data\n const fileQueryData = prepareFileQueryData(\n fileVersionData,\n locales,\n branchData\n );\n\n // Clear translated files before any downloads (if enabled)\n if (\n options.options?.experimentalClearLocaleDirs === true &&\n fileQueryData.length > 0\n ) {\n const translatedFiles = new Set(\n fileQueryData\n .map((file) => {\n const outputPath = resolveOutputPath(file.fileName, file.locale);\n // Only clear if the output path is different from the source (i.e., there's a transform)\n return outputPath !== null && outputPath !== file.fileName\n ? outputPath\n : null;\n })\n .filter((path): path is string => path !== null)\n );\n\n // Derive cwd from config path\n const cwd = path.dirname(options.config);\n\n await clearLocaleDirs(\n translatedFiles,\n locales,\n options.options?.clearLocaleDirsExclude,\n cwd\n );\n }\n\n // Initialize download status\n const fileTracker: FileStatusTracker = {\n completed: new Map<string, FileProperties>(),\n inProgress: new Map<string, FileProperties>(),\n failed: new Map<string, FileProperties>(),\n skipped: new Map<string, FileProperties>(),\n };\n\n // Step 1: Poll translation jobs if jobData exists\n let pollTimedOut = false;\n if (jobData) {\n const pollStep = new PollTranslationJobsStep(gt);\n const pollResult = await pollStep.run({\n fileTracker,\n fileQueryData,\n jobData,\n timeoutDuration,\n forceRetranslation,\n });\n await pollStep.wait();\n\n if (pollResult.fileTracker.failed.size > 0) {\n logger.error(\n `${chalk.red(`${pollResult.fileTracker.failed.size} file(s) failed to translate:`)}\\n${Array.from(\n pollResult.fileTracker.failed.entries()\n )\n .map(([, value]) => `- ${value.fileName}`)\n .join('\\n')}`\n );\n for (const [, value] of pollResult.fileTracker.failed) {\n recordWarning(\n 'failed_translation',\n value.fileName,\n `Failed to translate for locale ${value.locale}`\n );\n }\n\n // If all files failed translation, exit early\n if (pollResult.fileTracker.completed.size === 0) {\n return false;\n }\n }\n\n // Even if polling timed out, still download whatever completed successfully\n if (!pollResult.success) {\n pollTimedOut = true;\n if (pollResult.fileTracker.completed.size > 0) {\n logger.warn(\n chalk.yellow(\n `Timed out, but ${pollResult.fileTracker.completed.size} translation(s) completed successfully. Downloading completed files...`\n )\n );\n } else {\n return false;\n }\n }\n } else {\n for (const file of fileQueryData) {\n // Staging - assume all files are completed\n fileTracker.completed.set(\n `${file.branchId}:${file.fileId}:${file.versionId}:${file.locale}`,\n file\n );\n }\n }\n\n // Step 2: Download translations\n const downloadStep = new DownloadTranslationsStep(gt, options);\n const downloadResult = await downloadStep.run({\n fileTracker,\n resolveOutputPath,\n forceDownload,\n });\n await downloadStep.wait();\n\n // If polling timed out, report failure even though we downloaded what we could\n if (pollTimedOut) {\n return false;\n }\n\n return downloadResult;\n}\n\n/**\n * Prepares the file query data from input data and locales\n */\nfunction prepareFileQueryData(\n fileVersionData: FileTranslationData,\n locales: string[],\n branchData: BranchData\n): FileProperties[] {\n const fileQueryData: FileProperties[] = [];\n\n for (const fileId in fileVersionData) {\n for (const locale of locales) {\n fileQueryData.push({\n versionId: fileVersionData[fileId].versionId,\n fileName: fileVersionData[fileId].fileName,\n fileId,\n locale,\n branchId: branchData.currentBranch.id,\n });\n }\n }\n\n return fileQueryData;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsCA,eAAsB,oBAAoB,EACxC,iBACA,SACA,YACA,SACA,iBACA,mBACA,SACA,oBACA,iBAWmB;AACnB,KAAI,CAAC,YAAY;EAEf,MAAM,aAAa,IAAI,WAAW,IAAI,QAAQ;EAC9C,MAAM,eAAe,MAAM,WAAW,KAAK;AAC3C,QAAM,WAAW,MAAM;AACvB,MAAI,CAAC,aACH,QAAO,gBAAgB,sBAAsB;AAE/C,eAAa;;CAGf,MAAM,gBAAgB,qBACpB,iBACA,SACA,WACD;AAGD,KACE,QAAQ,SAAS,gCAAgC,QACjD,cAAc,SAAS,GACvB;EACA,MAAM,kBAAkB,IAAI,IAC1B,cACG,KAAK,SAAS;GACb,MAAM,aAAa,kBAAkB,KAAK,UAAU,KAAK,OAAO;AAEhE,UAAO,eAAe,QAAQ,eAAe,KAAK,WAC9C,aACA;IACJ,CACD,QAAQ,SAAyB,SAAS,KAAK,CACnD;EAGD,MAAM,MAAM,KAAK,QAAQ,QAAQ,OAAO;AAExC,QAAM,gBACJ,iBACA,SACA,QAAQ,SAAS,wBACjB,IACD;;CAIH,MAAM,cAAiC;EACrC,2BAAW,IAAI,KAA6B;EAC5C,4BAAY,IAAI,KAA6B;EAC7C,wBAAQ,IAAI,KAA6B;EACzC,yBAAS,IAAI,KAA6B;EAC3C;CAGD,IAAI,eAAe;AACnB,KAAI,SAAS;EACX,MAAM,WAAW,IAAI,wBAAwB,GAAG;EAChD,MAAM,aAAa,MAAM,SAAS,IAAI;GACpC;GACA;GACA;GACA;GACA;GACD,CAAC;AACF,QAAM,SAAS,MAAM;AAErB,MAAI,WAAW,YAAY,OAAO,OAAO,GAAG;AAC1C,UAAO,MACL,GAAG,MAAM,IAAI,GAAG,WAAW,YAAY,OAAO,KAAK,+BAA+B,CAAC,IAAI,MAAM,KAC3F,WAAW,YAAY,OAAO,SAAS,CACxC,CACE,KAAK,GAAG,WAAW,KAAK,MAAM,WAAW,CACzC,KAAK,KAAK,GACd;AACD,QAAK,MAAM,GAAG,UAAU,WAAW,YAAY,OAC7C,eACE,sBACA,MAAM,UACN,kCAAkC,MAAM,SACzC;AAIH,OAAI,WAAW,YAAY,UAAU,SAAS,EAC5C,QAAO;;AAKX,MAAI,CAAC,WAAW,SAAS;AACvB,kBAAe;AACf,OAAI,WAAW,YAAY,UAAU,OAAO,EAC1C,QAAO,KACL,MAAM,OACJ,kBAAkB,WAAW,YAAY,UAAU,KAAK,wEACzD,CACF;OAED,QAAO;;OAIX,MAAK,MAAM,QAAQ,cAEjB,aAAY,UAAU,IACpB,GAAG,KAAK,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,UAAU,GAAG,KAAK,UAC1D,KACD;CAKL,MAAM,eAAe,IAAI,yBAAyB,IAAI,QAAQ;CAC9D,MAAM,iBAAiB,MAAM,aAAa,IAAI;EAC5C;EACA;EACA;EACD,CAAC;AACF,OAAM,aAAa,MAAM;AAGzB,KAAI,aACF,QAAO;AAGT,QAAO;;;;;AAMT,SAAS,qBACP,iBACA,SACA,YACkB;CAClB,MAAM,gBAAkC,EAAE;AAE1C,MAAK,MAAM,UAAU,gBACnB,MAAK,MAAM,UAAU,QACnB,eAAc,KAAK;EACjB,WAAW,gBAAgB,QAAQ;EACnC,UAAU,gBAAgB,QAAQ;EAClC;EACA;EACA,UAAU,WAAW,cAAc;EACpC,CAAC;AAIN,QAAO"}
|
|
@@ -1,59 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { gt } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { logger } from "../console/logger.js";
|
|
2
|
+
import { gt } from "../utils/gt.js";
|
|
3
|
+
import { logCollectedFiles, logErrorAndExit } from "../console/logging.js";
|
|
4
|
+
import { branchResolutionError, withOriginalError } from "../console/index.js";
|
|
5
|
+
import { BranchStep } from "./steps/BranchStep.js";
|
|
6
|
+
import { EnqueueStep } from "./steps/EnqueueStep.js";
|
|
7
|
+
//#region src/workflows/enqueue.ts
|
|
6
8
|
/**
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
await enqueueStep.wait();
|
|
38
|
-
logger.debug('Enqueue result: ' + JSON.stringify(enqueueResult, null, 2));
|
|
39
|
-
logEnqueueResult(enqueueResult, files);
|
|
40
|
-
return enqueueResult;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
return logErrorAndExit('Failed to enqueue translations. ' + error);
|
|
44
|
-
}
|
|
9
|
+
* Enqueues translations for a given set of files
|
|
10
|
+
* - Only enqueues uploaded files
|
|
11
|
+
* - Don't have to worry about double enqueuing files because dedupe on API side
|
|
12
|
+
*
|
|
13
|
+
* @param {FileTranslationData} fileVersionData - The file version data
|
|
14
|
+
* @param {TranslateFlags} options - The options for the enqueue operation
|
|
15
|
+
* @param {Settings} settings - The settings for the enqueue operation
|
|
16
|
+
* @returns {Promise<EnqueueFilesResult>} The enqueue result
|
|
17
|
+
*/
|
|
18
|
+
async function runEnqueueWorkflow({ files, options, settings }) {
|
|
19
|
+
try {
|
|
20
|
+
logCollectedFiles(files);
|
|
21
|
+
logger.debug("Files: " + JSON.stringify(files, null, 2));
|
|
22
|
+
const branchStep = new BranchStep(gt, settings);
|
|
23
|
+
const enqueueStep = new EnqueueStep(gt, settings, options.force);
|
|
24
|
+
const branchData = await branchStep.run();
|
|
25
|
+
await branchStep.wait();
|
|
26
|
+
if (!branchData) return logErrorAndExit(branchResolutionError);
|
|
27
|
+
logger.debug("Branch data: " + JSON.stringify(branchData, null, 2));
|
|
28
|
+
const enqueueResult = await enqueueStep.run(files.map((files) => ({
|
|
29
|
+
branchId: branchData.currentBranch.id,
|
|
30
|
+
...files
|
|
31
|
+
})));
|
|
32
|
+
await enqueueStep.wait();
|
|
33
|
+
logger.debug("Enqueue result: " + JSON.stringify(enqueueResult, null, 2));
|
|
34
|
+
logEnqueueResult(enqueueResult, files);
|
|
35
|
+
return enqueueResult;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return logErrorAndExit(withOriginalError("Translations could not be enqueued. Check the files, branch configuration, and API credentials, then try again.", error));
|
|
38
|
+
}
|
|
45
39
|
}
|
|
46
|
-
// ----- Helper functions ----- //
|
|
47
40
|
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
* Logs the enqueue result
|
|
42
|
+
* @param enqueueResult - The enqueue result
|
|
43
|
+
* @returns void
|
|
44
|
+
*/
|
|
52
45
|
function logEnqueueResult(enqueueResult, files) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
logger.success(enqueueResult.message);
|
|
58
|
-
}
|
|
46
|
+
if (Object.keys(enqueueResult.jobData).length === 0) logger.success(`All ${files.length} files already translated. 0 files enqueued.`);
|
|
47
|
+
else logger.success(enqueueResult.message);
|
|
59
48
|
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { runEnqueueWorkflow };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=enqueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enqueue.js","names":[],"sources":["../../src/workflows/enqueue.ts"],"sourcesContent":["import { logCollectedFiles, logErrorAndExit } from '../console/logging.js';\nimport { branchResolutionError, withOriginalError } from '../console/index.js';\nimport { Settings, TranslateFlags } from '../types/index.js';\nimport { gt } from '../utils/gt.js';\nimport { EnqueueFilesResult, FileToUpload } from 'generaltranslation/types';\nimport { EnqueueStep } from './steps/EnqueueStep.js';\nimport { BranchStep } from './steps/BranchStep.js';\nimport { logger } from '../console/logger.js';\n\n/**\n * Enqueues translations for a given set of files\n * - Only enqueues uploaded files\n * - Don't have to worry about double enqueuing files because dedupe on API side\n *\n * @param {FileTranslationData} fileVersionData - The file version data\n * @param {TranslateFlags} options - The options for the enqueue operation\n * @param {Settings} settings - The settings for the enqueue operation\n * @returns {Promise<EnqueueFilesResult>} The enqueue result\n */\nexport async function runEnqueueWorkflow({\n files,\n options,\n settings,\n}: {\n files: FileToUpload[];\n options: TranslateFlags;\n settings: Settings;\n}): Promise<EnqueueFilesResult> {\n try {\n // Log files to be enqueued\n logCollectedFiles(files);\n\n logger.debug('Files: ' + JSON.stringify(files, null, 2));\n\n // Create workflow with steps\n const branchStep = new BranchStep(gt, settings);\n // const queryFileDataStep = new QueryFileDataStep(gt);\n const enqueueStep = new EnqueueStep(gt, settings, options.force);\n\n // (1) run the branch step\n const branchData = await branchStep.run();\n await branchStep.wait();\n if (!branchData) {\n return logErrorAndExit(branchResolutionError);\n }\n logger.debug('Branch data: ' + JSON.stringify(branchData, null, 2));\n\n // (2) Enqueue the files\n const enqueueResult = await enqueueStep.run(\n files.map((files) => ({\n branchId: branchData.currentBranch.id,\n ...files,\n }))\n );\n await enqueueStep.wait();\n\n logger.debug('Enqueue result: ' + JSON.stringify(enqueueResult, null, 2));\n\n logEnqueueResult(enqueueResult, files);\n return enqueueResult;\n } catch (error) {\n return logErrorAndExit(\n withOriginalError(\n 'Translations could not be enqueued. Check the files, branch configuration, and API credentials, then try again.',\n error\n )\n );\n }\n}\n\n// ----- Helper functions ----- //\n\n/**\n * Logs the enqueue result\n * @param enqueueResult - The enqueue result\n * @returns void\n */\nfunction logEnqueueResult(\n enqueueResult: EnqueueFilesResult,\n files: FileToUpload[]\n): void {\n if (Object.keys(enqueueResult.jobData).length === 0) {\n logger.success(\n `All ${files.length} files already translated. 0 files enqueued.`\n );\n } else {\n logger.success(enqueueResult.message);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,eAAsB,mBAAmB,EACvC,OACA,SACA,YAK8B;AAC9B,KAAI;AAEF,oBAAkB,MAAM;AAExB,SAAO,MAAM,YAAY,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;EAGxD,MAAM,aAAa,IAAI,WAAW,IAAI,SAAS;EAE/C,MAAM,cAAc,IAAI,YAAY,IAAI,UAAU,QAAQ,MAAM;EAGhE,MAAM,aAAa,MAAM,WAAW,KAAK;AACzC,QAAM,WAAW,MAAM;AACvB,MAAI,CAAC,WACH,QAAO,gBAAgB,sBAAsB;AAE/C,SAAO,MAAM,kBAAkB,KAAK,UAAU,YAAY,MAAM,EAAE,CAAC;EAGnE,MAAM,gBAAgB,MAAM,YAAY,IACtC,MAAM,KAAK,WAAW;GACpB,UAAU,WAAW,cAAc;GACnC,GAAG;GACJ,EAAE,CACJ;AACD,QAAM,YAAY,MAAM;AAExB,SAAO,MAAM,qBAAqB,KAAK,UAAU,eAAe,MAAM,EAAE,CAAC;AAEzE,mBAAiB,eAAe,MAAM;AACtC,SAAO;UACA,OAAO;AACd,SAAO,gBACL,kBACE,mHACA,MACD,CACF;;;;;;;;AAWL,SAAS,iBACP,eACA,OACM;AACN,KAAI,OAAO,KAAK,cAAc,QAAQ,CAAC,WAAW,EAChD,QAAO,QACL,OAAO,MAAM,OAAO,8CACrB;KAED,QAAO,QAAQ,cAAc,QAAQ"}
|