From 40a5e13ad4762da7e1add13b8f1061f457c61d84 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 21 Apr 2026 14:29:35 +0300 Subject: [PATCH] Updated on 2026-08-14 --- core/ui/build.gradle.kts | 72 + core/ui/ds-tokens | 1 + .../tangem/core/ui/res/generated/.tokens-hash | 1 + .../ui/res/generated/TangemDarkColorTokens.kt | 118 ++ .../ui/res/generated/TangemDimensionTokens.kt | 72 + .../res/generated/TangemLightColorTokens.kt | 118 ++ .../ui/res/generated/TangemOpacityTokens.kt | 22 + .../ui/res/generated/TangemShadowTokens.kt | 15 + .../res/generated/TangemTypographyTokens.kt | 88 + core/ui/token-gen/.gitignore | 1 + core/ui/token-gen/build-tokens.mjs | 532 +++++ core/ui/token-gen/package-lock.json | 1749 +++++++++++++++++ core/ui/token-gen/package.json | 13 + 13 files changed, 2802 insertions(+) create mode 160000 core/ui/ds-tokens create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/.tokens-hash create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDarkColorTokens.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimensionTokens.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemLightColorTokens.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemOpacityTokens.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemShadowTokens.kt create mode 100644 core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemTypographyTokens.kt create mode 100644 core/ui/token-gen/.gitignore create mode 100644 core/ui/token-gen/build-tokens.mjs create mode 100644 core/ui/token-gen/package-lock.json create mode 100644 core/ui/token-gen/package.json diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 87b86b8135..58c1e0cb0f 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -1,9 +1,71 @@ +import java.security.MessageDigest + plugins { alias(deps.plugins.android.library) alias(deps.plugins.kotlin.android) id("configuration") } +/** + * Verifies that generated Kotlin token files match the current ds-tokens submodule. + * If this fails, run: cd core/ui/token-gen && npm run build + */ +abstract class VerifyDesignTokensTask : DefaultTask() { + + @get:InputDirectory + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val tokensDir: DirectoryProperty + + @get:InputFile + @get:PathSensitive(PathSensitivity.NONE) + abstract val hashFile: RegularFileProperty + + @get:OutputFile + abstract val stampFile: RegularFileProperty + + @TaskAction + fun verify() { + val hashFileValue = hashFile.get().asFile + require(hashFileValue.exists()) { + "Design tokens hash file not found: ${hashFileValue.absolutePath}\n" + + "Run the token generator: cd core/ui/token-gen && npm run build" + } + + val tokensDirValue = tokensDir.get().asFile + require(tokensDirValue.exists() && tokensDirValue.isDirectory) { + "ds-tokens submodule not found: ${tokensDirValue.absolutePath}\n" + + "Run: git submodule update --init --recursive" + } + + val digest = MessageDigest.getInstance("SHA-256") + val jsonFiles = tokensDirValue.walkTopDown() + .filter { it.isFile && it.extension == "json" } + .sortedBy { it.relativeTo(tokensDirValue).path } + .toList() + + val nul = byteArrayOf(0) + for (file in jsonFiles) { + digest.update(file.relativeTo(tokensDirValue).invariantSeparatorsPath.toByteArray()) + digest.update(nul) + digest.update(file.readBytes()) + digest.update(nul) + } + + val actual = digest.digest() + .joinToString("") { b: Byte -> b.toInt().and(0xFF).toString(16).padStart(2, '0') } + val expected = hashFileValue.readText().trim() + + require(actual == expected) { + "Design tokens are out of date!\n" + + " ds-tokens hash: $actual\n" + + " generated hash: $expected\n" + + "Run the token generator: cd core/ui/token-gen && npm run build" + } + + stampFile.get().asFile.writeText(actual) + } +} + android { namespace = "com.tangem.core.ui" @@ -15,6 +77,16 @@ android { } } +val verifyDesignTokens = tasks.register("verifyDesignTokens") { + tokensDir.set(file("ds-tokens/tokens")) + hashFile.set(file("src/main/java/com/tangem/core/ui/res/generated/.tokens-hash")) + stampFile.set(layout.buildDirectory.file("tokens-verified.stamp")) +} + +tasks.named("preBuild") { + dependsOn(verifyDesignTokens) +} + dependencies { /** Project - Domain */ implementation(projects.domain.appTheme.models) diff --git a/core/ui/ds-tokens b/core/ui/ds-tokens new file mode 160000 index 0000000000..f4d2156236 --- /dev/null +++ b/core/ui/ds-tokens @@ -0,0 +1 @@ +Subproject commit f4d2156236d7f77b61f26250351f6bfa72262a69 diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/.tokens-hash b/core/ui/src/main/java/com/tangem/core/ui/res/generated/.tokens-hash new file mode 100644 index 0000000000..14287aaf78 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/.tokens-hash @@ -0,0 +1 @@ +ddef7c44794c12a02c136fcc17f01fe51b6372d33a6a7eda4913d2d1b1f86203 diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDarkColorTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDarkColorTokens.kt new file mode 100644 index 0000000000..0f731be297 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDarkColorTokens.kt @@ -0,0 +1,118 @@ +package com.tangem.core.ui.res.generated + +import androidx.compose.ui.graphics.Color + +/** + * Auto-generated from design tokens. Do not edit manually. + * Theme: Dark + */ +internal class TangemDarkColorTokens { + // color.text + val colorTextPrimary = Color(0xFFFFFFFF) + val colorTextSecondary = Color(0x99FFFFFF) + val colorTextTertiary = Color(0x4DFFFFFF) + val colorTextBrand = Color(0xFF0090F9) + val colorTextStaticLightPrimary = Color(0xFF000000) + val colorTextStaticLightSecondary = Color(0x99000000) + val colorTextStaticLightTertiary = Color(0x66000000) + val colorTextStaticDarkPrimary = Color(0xFFFFFFFF) + val colorTextStaticDarkSecondary = Color(0x99FFFFFF) + val colorTextStaticDarkTertiary = Color(0x4DFFFFFF) + val colorTextInversePrimary = Color(0xFF0F0F0F) + val colorTextInverseSecondary = Color(0x990F0F0F) + val colorTextInverseTertiary = Color(0x660F0F0F) + val colorTextStatusSuccess = Color(0xFF2DAE3B) + val colorTextStatusError = Color(0xFFFF5E66) + val colorTextStatusWarning = Color(0xFFEFA210) + val colorTextStatusInfo = Color(0xFF109FF0) + val colorTextAccentBlue = Color(0xFF109FF0) + val colorTextAccentViolet = Color(0xFFB07BFD) + val colorTextAccentRed = Color(0xFFFF5E66) + val colorTextAccentOrange = Color(0xFFFA6931) + val colorTextAccentYellow = Color(0xFFEFA210) + val colorTextAccentGreen = Color(0xFF2DAE3B) + + // color.bg + val colorBgPrimary = Color(0xFF0F0F0F) + val colorBgSecondary = Color(0xFF1B1B1B) + val colorBgTertiary = Color(0xFF2C2C2C) + val colorBgBrand = Color(0xFF0090F9) + val colorBgInverse = Color(0xFFF4F4F4) + val colorBgBase = Color(0xFF000000) + val colorBgOpaquePrimary = Color(0x0DFFFFFF) + val colorBgOpaqueSecondary = Color(0x1AFFFFFF) + val colorBgStatusSuccess = Color(0xFF2DA30D) + val colorBgStatusError = Color(0xFFF25508) + val colorBgStatusWarning = Color(0xFFE68A03) + val colorBgStatusInfo = Color(0xFF0090F9) + val colorBgAccentBlue = Color(0xFF0090F9) + val colorBgAccentViolet = Color(0xFFA967FD) + val colorBgAccentRed = Color(0xFFFE4142) + val colorBgAccentOrange = Color(0xFFF25508) + val colorBgAccentYellow = Color(0xFFE68A03) + val colorBgAccentGreen = Color(0xFF2DA30D) + + // color.icon + val colorIconPrimary = Color(0xFFFFFFFF) + val colorIconSecondary = Color(0x99FFFFFF) + val colorIconTertiary = Color(0x4DFFFFFF) + val colorIconBrand = Color(0xFF0090F9) + val colorIconStaticLight = Color(0xFF000000) + val colorIconStaticDark = Color(0xFFFFFFFF) + val colorIconInverse = Color(0xFF0F0F0F) + val colorIconStatusSuccess = Color(0xFF2DAE3B) + val colorIconStatusError = Color(0xFFFA6931) + val colorIconStatusWarning = Color(0xFFEFA210) + val colorIconStatusInfo = Color(0xFF109FF0) + val colorIconAccentBlue = Color(0xFF109FF0) + val colorIconAccentViolet = Color(0xFFB07BFD) + val colorIconAccentRed = Color(0xFFFF5E66) + val colorIconAccentOrange = Color(0xFFFA6931) + val colorIconAccentYellow = Color(0xFFEFA210) + val colorIconAccentGreen = Color(0xFF2DAE3B) + + // color.border + val colorBorderPrimary = Color(0x0DFFFFFF) + val colorBorderSecondary = Color(0x1AFFFFFF) + val colorBorderTertiary = Color(0x33FFFFFF) + val colorBorderBrand = Color(0xFF0090F9) + val colorBorderInversePrimary = Color(0x0D000000) + val colorBorderInverseSecondary = Color(0x1A000000) + val colorBorderInverseTertiary = Color(0x33000000) + val colorBorderStatusSuccess = Color(0xFF2DAE3B) + val colorBorderStatusError = Color(0xFFFA6931) + val colorBorderStatusWarning = Color(0xFFEFA210) + val colorBorderStatusInfo = Color(0xFF109FF0) + val colorBorderAccentBlue = Color(0xFF109FF0) + val colorBorderAccentViolet = Color(0xFFB07BFD) + val colorBorderAccentRed = Color(0xFFFF5E66) + val colorBorderAccentOrange = Color(0xFFFA6931) + val colorBorderAccentYellow = Color(0xFFEFA210) + val colorBorderAccentGreen = Color(0xFF2DAE3B) + + // color.overlay + val colorOverlayModal = Color(0xCC000000) + + // color.interaction + val colorInteractionPress = Color(0x1AFFFFFF) + val colorInteractionPressStaticLight = Color(0x1A000000) + val colorInteractionPressStaticDark = Color(0x1AFFFFFF) + val colorInteractionPressInverse = Color(0x1A000000) + + // color.material + val colorMaterialTintGlass = Color(0x66181818) + val colorMaterialTintBlur = Color(0x00000000) + val colorMaterialTintSolid = Color(0x1AFFFFFF) + val colorMaterialFillGlass = Color(0x00000000) + val colorMaterialFillBlur = Color(0x1AFFFFFF) + val colorMaterialFillSolid = Color(0xE62C2C2C) + val colorMaterialLightenGlass = Color(0x33181818) + val colorMaterialLightenBlur = Color(0x00000000) + val colorMaterialLightenSolid = Color(0x00000000) + val colorMaterialSoftLightGlass = Color(0x1A000000) + val colorMaterialSoftLightBlur = Color(0x00000000) + val colorMaterialSoftLightSolid = Color(0x00000000) + val colorMaterialBorderStart = Color(0x33FFFFFF) + val colorMaterialBorderMid = Color(0x00FFFFFF) + val colorMaterialBorderEnd = Color(0x1AFFFFFF) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimensionTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimensionTokens.kt new file mode 100644 index 0000000000..dcf1be90a8 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemDimensionTokens.kt @@ -0,0 +1,72 @@ +package com.tangem.core.ui.res.generated + +import androidx.compose.ui.unit.dp + +/** + * Auto-generated from design tokens. Do not edit manually. + */ +internal class TangemDimensionTokens { + // blur + val blurSizeCard = 48.dp + val blurSizeButton = 32.dp + + // border-radius + val borderRadius100 = 8.dp + val borderRadius150 = 12.dp + val borderRadius200 = 16.dp + val borderRadius250 = 20.dp + val borderRadius300 = 24.dp + val borderRadius400 = 32.dp + val borderRadiusNone = 0.dp + val borderRadius075 = 6.dp + val borderRadius050 = 4.dp + val borderRadiusFull = 999.dp + + // border-width + val borderWidthNone = 0.dp + val borderWidthXs = 0.5.dp + val borderWidthSm = 1.dp + val borderWidthMd = 2.dp + val borderWidthLg = 4.dp + + // size + val size100 = 8.dp + val size125 = 10.dp + val size150 = 12.dp + val size200 = 16.dp + val size250 = 20.dp + val size300 = 24.dp + val size350 = 28.dp + val size400 = 32.dp + val size450 = 36.dp + val size500 = 40.dp + val size550 = 44.dp + val size600 = 48.dp + val size700 = 56.dp + val size800 = 64.dp + val size1000 = 80.dp + val size1100 = 88.dp + val size1200 = 96.dp + val size025 = 2.dp + val size050 = 4.dp + val sizeCardSm = 128.dp + + // spacing + val spacing100 = 8.dp + val spacing150 = 12.dp + val spacing200 = 16.dp + val spacing250 = 20.dp + val spacing300 = 24.dp + val spacing350 = 28.dp + val spacing400 = 32.dp + val spacing450 = 36.dp + val spacing500 = 40.dp + val spacing550 = 44.dp + val spacing600 = 48.dp + val spacing700 = 56.dp + val spacing800 = 64.dp + val spacing1000 = 80.dp + val spacing025 = 2.dp + val spacing050 = 4.dp + val spacingNone = 0.dp +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemLightColorTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemLightColorTokens.kt new file mode 100644 index 0000000000..75c0758b25 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemLightColorTokens.kt @@ -0,0 +1,118 @@ +package com.tangem.core.ui.res.generated + +import androidx.compose.ui.graphics.Color + +/** + * Auto-generated from design tokens. Do not edit manually. + * Theme: Light + */ +internal class TangemLightColorTokens { + // color.text + val colorTextPrimary = Color(0xFF0F0F0F) + val colorTextSecondary = Color(0x990F0F0F) + val colorTextTertiary = Color(0x660F0F0F) + val colorTextBrand = Color(0xFF0090F9) + val colorTextStaticLightPrimary = Color(0xFF000000) + val colorTextStaticLightSecondary = Color(0x99000000) + val colorTextStaticLightTertiary = Color(0x66000000) + val colorTextStaticDarkPrimary = Color(0xFFFFFFFF) + val colorTextStaticDarkSecondary = Color(0x99FFFFFF) + val colorTextStaticDarkTertiary = Color(0x4DFFFFFF) + val colorTextInversePrimary = Color(0xFFFFFFFF) + val colorTextInverseSecondary = Color(0x99FFFFFF) + val colorTextInverseTertiary = Color(0x4DFFFFFF) + val colorTextStatusSuccess = Color(0xFF2DA30D) + val colorTextStatusError = Color(0xFFFE4142) + val colorTextStatusWarning = Color(0xFFE68A03) + val colorTextStatusInfo = Color(0xFF0090F9) + val colorTextAccentBlue = Color(0xFF0090F9) + val colorTextAccentViolet = Color(0xFFA967FD) + val colorTextAccentRed = Color(0xFFFE4142) + val colorTextAccentOrange = Color(0xFFF25508) + val colorTextAccentYellow = Color(0xFFE68A03) + val colorTextAccentGreen = Color(0xFF2DA30D) + + // color.bg + val colorBgPrimary = Color(0xFFF4F4F4) + val colorBgSecondary = Color(0xFFFFFFFF) + val colorBgTertiary = Color(0xFFEAEAEA) + val colorBgBrand = Color(0xFF0090F9) + val colorBgInverse = Color(0xFFF4F4F4) + val colorBgBase = Color(0xFFF4F4F4) + val colorBgOpaquePrimary = Color(0x0DFFFFFF) + val colorBgOpaqueSecondary = Color(0x1AFFFFFF) + val colorBgStatusSuccess = Color(0xFF2DA30D) + val colorBgStatusError = Color(0xFFF25508) + val colorBgStatusWarning = Color(0xFFE68A03) + val colorBgStatusInfo = Color(0xFF0090F9) + val colorBgAccentBlue = Color(0xFF0090F9) + val colorBgAccentViolet = Color(0xFFA967FD) + val colorBgAccentRed = Color(0xFFFE4142) + val colorBgAccentOrange = Color(0xFFF25508) + val colorBgAccentYellow = Color(0xFFE68A03) + val colorBgAccentGreen = Color(0xFF2DA30D) + + // color.icon + val colorIconPrimary = Color(0xFF0F0F0F) + val colorIconSecondary = Color(0x990F0F0F) + val colorIconTertiary = Color(0x660F0F0F) + val colorIconBrand = Color(0xFF0090F9) + val colorIconStaticLight = Color(0xFF000000) + val colorIconStaticDark = Color(0xFFFFFFFF) + val colorIconInverse = Color(0xFFFFFFFF) + val colorIconStatusSuccess = Color(0xFF2DA30D) + val colorIconStatusError = Color(0xFFF25508) + val colorIconStatusWarning = Color(0xFFE68A03) + val colorIconStatusInfo = Color(0xFF0090F9) + val colorIconAccentBlue = Color(0xFF0090F9) + val colorIconAccentViolet = Color(0xFFA967FD) + val colorIconAccentRed = Color(0xFFFE4142) + val colorIconAccentOrange = Color(0xFFF25508) + val colorIconAccentYellow = Color(0xFFE68A03) + val colorIconAccentGreen = Color(0xFF2DA30D) + + // color.border + val colorBorderPrimary = Color(0x0D000000) + val colorBorderSecondary = Color(0x1A000000) + val colorBorderTertiary = Color(0x33000000) + val colorBorderBrand = Color(0xFF0090F9) + val colorBorderInversePrimary = Color(0x0D000000) + val colorBorderInverseSecondary = Color(0x1A000000) + val colorBorderInverseTertiary = Color(0x33000000) + val colorBorderStatusSuccess = Color(0xFF2DA30D) + val colorBorderStatusError = Color(0xFFF25508) + val colorBorderStatusWarning = Color(0xFFE68A03) + val colorBorderStatusInfo = Color(0xFF0090F9) + val colorBorderAccentBlue = Color(0xFF0090F9) + val colorBorderAccentViolet = Color(0xFFA967FD) + val colorBorderAccentRed = Color(0xFFFE4142) + val colorBorderAccentOrange = Color(0xFFF25508) + val colorBorderAccentYellow = Color(0xFFE68A03) + val colorBorderAccentGreen = Color(0xFF2DA30D) + + // color.overlay + val colorOverlayModal = Color(0x99000000) + + // color.interaction + val colorInteractionPress = Color(0x1A000000) + val colorInteractionPressStaticLight = Color(0x1A000000) + val colorInteractionPressStaticDark = Color(0x1AFFFFFF) + val colorInteractionPressInverse = Color(0x1AFFFFFF) + + // color.material + val colorMaterialTintGlass = Color(0x00000000) + val colorMaterialTintBlur = Color(0x00000000) + val colorMaterialTintSolid = Color(0x1AFFFFFF) + val colorMaterialFillGlass = Color(0x00000000) + val colorMaterialFillBlur = Color(0x99FFFFFF) + val colorMaterialFillSolid = Color(0xE6FFFFFF) + val colorMaterialLightenGlass = Color(0x80F7F7F7) + val colorMaterialLightenBlur = Color(0x00000000) + val colorMaterialLightenSolid = Color(0x00000000) + val colorMaterialSoftLightGlass = Color(0x33000000) + val colorMaterialSoftLightBlur = Color(0x00000000) + val colorMaterialSoftLightSolid = Color(0x00000000) + val colorMaterialBorderStart = Color(0x26000000) + val colorMaterialBorderMid = Color(0x00000000) + val colorMaterialBorderEnd = Color(0x1A000000) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemOpacityTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemOpacityTokens.kt new file mode 100644 index 0000000000..0de7875fdb --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemOpacityTokens.kt @@ -0,0 +1,22 @@ +package com.tangem.core.ui.res.generated + +/** + * Auto-generated from design tokens. Do not edit manually. + */ +internal class TangemOpacityTokens { + val opacity0 = 0f + val opacity5 = 0.05f + val opacity10 = 0.1f + val opacity15 = 0.15f + val opacity20 = 0.2f + val opacity25 = 0.25f + val opacity30 = 0.3f + val opacity40 = 0.4f + val opacity50 = 0.5f + val opacity60 = 0.6f + val opacity70 = 0.7f + val opacity80 = 0.8f + val opacity90 = 0.9f + val opacity100 = 1f + val opacityDisabled = 0.4f +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemShadowTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemShadowTokens.kt new file mode 100644 index 0000000000..5677a413a4 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemShadowTokens.kt @@ -0,0 +1,15 @@ +package com.tangem.core.ui.res.generated + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +/** + * Auto-generated from design tokens. Do not edit manually. + */ +internal class TangemShadowTokens { + val shadowButtonBlur = 40.dp + val shadowButtonOffsetX = 0.dp + val shadowButtonOffsetY = 8.dp + val shadowButtonSpread = 0.dp + val shadowButtonColor = Color(0x1A000000) +} \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemTypographyTokens.kt b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemTypographyTokens.kt new file mode 100644 index 0000000000..d3fcd82486 --- /dev/null +++ b/core/ui/src/main/java/com/tangem/core/ui/res/generated/TangemTypographyTokens.kt @@ -0,0 +1,88 @@ +package com.tangem.core.ui.res.generated + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.LineBreak +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.sp +import com.tangem.core.ui.res.InterFamily + +/** + * Auto-generated from design tokens. Do not edit manually. + */ +internal class TangemTypographyTokens { + val fontDisplayMedium = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 44.sp, + lineHeight = 52.sp, + letterSpacing = (-0.92).sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + lineBreak = LineBreak.Heading, + ) + + val fontHeadingMedium = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 28.sp, + lineHeight = 33.sp, + letterSpacing = (-0.37).sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + lineBreak = LineBreak.Heading, + ) + + val fontHeadingSmall = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 20.sp, + lineHeight = 24.sp, + letterSpacing = (-0.12).sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + lineBreak = LineBreak.Heading, + ) + + val fontBodyMedium = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + lineHeight = 20.sp, + letterSpacing = 0.02.sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ) + + val fontSubheadingMedium = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 17.sp, + letterSpacing = 0.07.sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ) + + val fontCaptionMedium = TextStyle( + fontFamily = InterFamily, + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.18.sp, + lineHeightStyle = LineHeightStyle( + alignment = LineHeightStyle.Alignment.Center, + trim = LineHeightStyle.Trim.None, + ), + ) +} \ No newline at end of file diff --git a/core/ui/token-gen/.gitignore b/core/ui/token-gen/.gitignore new file mode 100644 index 0000000000..c2658d7d1b --- /dev/null +++ b/core/ui/token-gen/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/core/ui/token-gen/build-tokens.mjs b/core/ui/token-gen/build-tokens.mjs new file mode 100644 index 0000000000..0add5d002f --- /dev/null +++ b/core/ui/token-gen/build-tokens.mjs @@ -0,0 +1,532 @@ +import StyleDictionary from 'style-dictionary'; +import { register, getTransforms } from '@tokens-studio/sd-transforms'; +import crypto from 'crypto'; +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +// ── Paths ────────────────────────────────────────────────────────────────────── +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const tokensDir = path.join(__dirname, '..', 'ds-tokens', 'tokens'); +const outputDir = path.join( + __dirname, '..', 'src', 'main', 'java', 'com', 'tangem', 'core', 'ui', 'res', 'generated', +); + +const PACKAGE = 'com.tangem.core.ui.res.generated'; + +fs.mkdirSync(outputDir, { recursive: true }); + +// ── Register sd-transforms ───────────────────────────────────────────────────── +// Use CSS platform for sd-transforms to get ts/color/css/hexrgba (resolves rgba to hex). +// Compose color conversion is done in the format function instead of as a transform, +// because the color/composeColor transform interferes with rgba reference resolution. +await register(StyleDictionary, { platform: 'css' }); + +// ── Token set definitions ────────────────────────────────────────────────────── +// Reference-only sets (provide values for other tokens but not in the output) +const coreSets = [ + 'core/palette', + 'core/font', + 'core/dimension', +]; + +// Theme-independent semantic sets +const sizeSets = [ + 'semantic/size/opacity', + 'semantic/size/blur', + 'semantic/size/border', + 'semantic/size/size', + 'semantic/size/spacing', +]; + +const fontSets = [ + 'semantic/font/sizes/android', + 'semantic/font/styles', +]; + +const sharedSets = [ + 'semantic/theme/shadows', + 'semantic/theme/gradient', +]; + +// Theme-specific sets +// Note: material variant files (glass/blur/solid) define colliding paths and are excluded. +// The material color tokens come from materials/light and materials/dark instead. +const themeBuilds = { + Light: { + sets: [ + ...coreSets, ...sizeSets, ...fontSets, ...sharedSets, + 'semantic/theme/light', + 'semantic/theme/materials/light', + ], + }, + Dark: { + sets: [ + ...coreSets, ...sizeSets, ...fontSets, ...sharedSets, + 'semantic/theme/dark', + 'semantic/theme/materials/dark', + ], + }, +}; + +// For theme-independent builds (dimensions, typography, etc.) +const sharedBuildSets = [...coreSets, ...sizeSets, ...fontSets, ...sharedSets]; + +for (const [theme, { sets }] of Object.entries(themeBuilds)) { + console.log(`${theme} theme: ${sets.length} token sets`); +} + +// ── Helpers ──────────────────────────────────────────────────────────────────── + +/** Convert token path segments to a camelCase property name */ +function toCamelCase(segments) { + return segments + .map((seg, i) => { + // kebab-case → camelCase + const cleaned = seg.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase()); + if (i === 0) return cleaned; + return cleaned.charAt(0).toUpperCase() + cleaned.slice(1); + }) + .join(''); +} + +/** Check if a token is from core/palette, dimension, or gradient source sets (not for output) */ +function isSourceOnlyToken(token) { + const top = token.path[0]; + return top === 'palette' || top === 'dimension' || top === 'gradient'; +} + +/** + * Convert a resolved CSS color string to Compose Color(0xAARRGGBB). + * Handles: #RRGGBB, #AARRGGBB, rgba(r, g, b, a), rgb(r, g, b) + */ +function toComposeColor(value, tokenPath = '') { + if (typeof value !== 'string') { + throw new Error(`Unrecognized color value for ${tokenPath}: ${JSON.stringify(value)}`); + } + + // #RRGGBB + const hex6 = value.match(/^#([0-9a-fA-F]{6})$/); + if (hex6) return `Color(0xFF${hex6[1].toUpperCase()})`; + + // #AARRGGBB (8-digit hex) + const hex8 = value.match(/^#([0-9a-fA-F]{8})$/); + if (hex8) return `Color(0x${hex8[1].toUpperCase()})`; + + // rgba(r, g, b, a) + const rgba = value.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)$/); + if (rgba) { + const r = parseInt(rgba[1]).toString(16).padStart(2, '0').toUpperCase(); + const g = parseInt(rgba[2]).toString(16).padStart(2, '0').toUpperCase(); + const b = parseInt(rgba[3]).toString(16).padStart(2, '0').toUpperCase(); + const a = Math.round(parseFloat(rgba[4]) * 255).toString(16).padStart(2, '0').toUpperCase(); + return `Color(0x${a}${r}${g}${b})`; + } + + // rgb(r, g, b) + const rgb = value.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/); + if (rgb) { + const r = parseInt(rgb[1]).toString(16).padStart(2, '0').toUpperCase(); + const g = parseInt(rgb[2]).toString(16).padStart(2, '0').toUpperCase(); + const b = parseInt(rgb[3]).toString(16).padStart(2, '0').toUpperCase(); + return `Color(0xFF${r}${g}${b})`; + } + + // Transparent + if (value === 'transparent' || value === '#00000000') return 'Color(0x00000000)'; + + throw new Error(`Unrecognized color format for ${tokenPath}: "${value}"`); +} + +/** Group tokens by their first N path segments */ +function groupByPath(tokens, depth = 1) { + const groups = {}; + for (const token of tokens) { + const key = token.path.slice(0, depth).join('.'); + if (!groups[key]) groups[key] = []; + groups[key].push(token); + } + return groups; +} + +// ── Custom formats ───────────────────────────────────────────────────────────── + +/** + * Kotlin format for color tokens. + * Generates: class TangemLightColorTokens / TangemDarkColorTokens + */ +StyleDictionary.registerFormat({ + name: 'kotlin/compose-colors', + format: ({ dictionary, options }) => { + const themeName = options.themeName; // "Light" or "Dark" + const objectName = `Tangem${themeName}ColorTokens`; + + const colorTokens = dictionary.allTokens.filter( + t => t.$type === 'color' && !isSourceOnlyToken(t), + ); + + // Group by top-level category (color.text, color.bg, color.icon, etc.) + const groups = groupByPath(colorTokens, 2); + const sections = []; + + for (const [groupKey, tokens] of Object.entries(groups)) { + const comment = ` // ${groupKey}`; + const props = tokens.map(token => { + const propName = toCamelCase(token.path); + const value = toComposeColor(token.$value, token.path.join('.')); + return ` val ${propName} = ${value}`; + }); + sections.push([comment, ...props].join('\n')); + } + + return [ + `package ${PACKAGE}`, + '', + 'import androidx.compose.ui.graphics.Color', + '', + '/**', + ` * Auto-generated from design tokens. Do not edit manually.`, + ` * Theme: ${themeName}`, + ' */', + `internal class ${objectName} {`, + sections.join('\n\n'), + '}', + '', + ].join('\n'); + }, +}); + +/** + * Kotlin format for dimension tokens (spacing, size, border-radius, border-width). + */ +StyleDictionary.registerFormat({ + name: 'kotlin/compose-dimensions', + format: ({ dictionary }) => { + const dimTokens = dictionary.allTokens.filter(t => { + // Exclude font tokens — letter-spacing values are already in typography tokens as sp + if (t.path[0] === 'font') return false; + return ( + (t.$type === 'dimension' || t.$type === 'borderRadius' || t.$type === 'borderWidth') && + !isSourceOnlyToken(t) + ); + }); + + const groups = groupByPath(dimTokens, 1); + const sections = []; + + for (const [groupKey, tokens] of Object.entries(groups)) { + const comment = ` // ${groupKey}`; + const props = tokens.map(token => { + const propName = toCamelCase(token.path); + // Resolved value is in px (number), convert to dp + const raw = parseFloat(token.$value); + if (isNaN(raw)) throw new Error(`Non-numeric dimension value for ${token.path.join('.')}: "${token.$value}"`); + const dpVal = `${raw}.dp`; + return ` val ${propName} = ${dpVal}`; + }); + sections.push([comment, ...props].join('\n')); + } + + return [ + `package ${PACKAGE}`, + '', + 'import androidx.compose.ui.unit.dp', + '', + '/**', + ' * Auto-generated from design tokens. Do not edit manually.', + ' */', + 'internal class TangemDimensionTokens {', + sections.join('\n\n'), + '}', + '', + ].join('\n'); + }, +}); + +/** + * Kotlin format for opacity tokens. + */ +StyleDictionary.registerFormat({ + name: 'kotlin/compose-opacity', + format: ({ dictionary }) => { + const opacityTokens = dictionary.allTokens.filter( + t => t.$type === 'opacity' && !isSourceOnlyToken(t), + ); + + const props = opacityTokens.map(token => { + const propName = toCamelCase(token.path); + const raw = parseFloat(token.$value); + if (isNaN(raw)) throw new Error(`Non-numeric opacity value for ${token.path.join('.')}: "${token.$value}"`); + const floatVal = `${raw}f`; + return ` val ${propName} = ${floatVal}`; + }); + + return [ + `package ${PACKAGE}`, + '', + '/**', + ' * Auto-generated from design tokens. Do not edit manually.', + ' */', + 'internal class TangemOpacityTokens {', + ...props, + '}', + '', + ].join('\n'); + }, +}); + +/** + * Kotlin format for typography tokens. + */ +StyleDictionary.registerFormat({ + name: 'kotlin/compose-typography', + format: ({ dictionary }) => { + const typoTokens = dictionary.allTokens.filter( + t => t.$type === 'typography' && !isSourceOnlyToken(t), + ); + + const props = typoTokens.map(token => { + const propName = toCamelCase(token.path); + const v = token.$value; + + // v is an object: { fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, ... } + const tp = token.path.join('.'); + if (!v.fontWeight) throw new Error(`Missing fontWeight for ${tp}`); + const fontWeight = mapFontWeight(v.fontWeight); + const fontSize = parseFloat(v.fontSize); + if (isNaN(fontSize)) throw new Error(`Non-numeric fontSize for ${tp}: "${v.fontSize}"`); + const lineHeight = parseFloat(v.lineHeight); + if (isNaN(lineHeight)) throw new Error(`Non-numeric lineHeight for ${tp}: "${v.lineHeight}"`); + const letterSpacing = parseFloat(v.letterSpacing); + if (isNaN(letterSpacing)) throw new Error(`Non-numeric letterSpacing for ${tp}: "${v.letterSpacing}"`); + + // display and heading categories get LineBreak.Heading (matches TangemTypography2) + const category = token.path[1]; // display, heading, body, subheading, caption + const isHeading = category === 'display' || category === 'heading'; + + const lines = [ + ` val ${propName} = TextStyle(`, + ` fontFamily = InterFamily,`, + ` fontWeight = ${fontWeight},`, + ` fontSize = ${fontSize}.sp,`, + ` lineHeight = ${lineHeight}.sp,`, + ` letterSpacing = ${letterSpacing < 0 ? `(${letterSpacing})` : letterSpacing}.sp,`, + ` lineHeightStyle = LineHeightStyle(`, + ` alignment = LineHeightStyle.Alignment.Center,`, + ` trim = LineHeightStyle.Trim.None,`, + ` ),`, + ]; + if (isHeading) { + lines.push(` lineBreak = LineBreak.Heading,`); + } + lines.push(` )`); + + return lines.join('\n'); + }); + + return [ + `package ${PACKAGE}`, + '', + 'import androidx.compose.ui.text.TextStyle', + 'import androidx.compose.ui.text.font.FontWeight', + 'import androidx.compose.ui.text.style.LineBreak', + 'import androidx.compose.ui.text.style.LineHeightStyle', + 'import androidx.compose.ui.unit.sp', + 'import com.tangem.core.ui.res.InterFamily', + '', + '/**', + ' * Auto-generated from design tokens. Do not edit manually.', + ' */', + 'internal class TangemTypographyTokens {', + props.join('\n\n'), + '}', + '', + ].join('\n'); + }, +}); + +function mapFontWeight(value) { + const num = parseInt(value, 10); + if (!isNaN(num)) { + if (num <= 400) return 'FontWeight.Normal'; + if (num <= 500) return 'FontWeight.Medium'; + if (num <= 600) return 'FontWeight.SemiBold'; + return 'FontWeight.Bold'; + } + const lower = String(value).toLowerCase(); + if (lower.includes('semibold') || lower.includes('semi bold')) return 'FontWeight.SemiBold'; + if (lower.includes('bold')) return 'FontWeight.Bold'; + if (lower.includes('medium')) return 'FontWeight.Medium'; + return 'FontWeight.Normal'; +} + +/** + * Kotlin format for shadow tokens. + * Shadow tokens are composite (type: shadow) with object $value containing + * blur, spread, color, offsetX, offsetY, type. + */ +StyleDictionary.registerFormat({ + name: 'kotlin/compose-shadows', + format: ({ dictionary }) => { + const shadowTokens = dictionary.allTokens.filter( + t => (t.$type === 'shadow' || t.$type === 'boxShadow') && !isSourceOnlyToken(t), + ); + + const entries = shadowTokens.map(token => { + const propName = toCamelCase(token.path); + const v = token.$value; + const sp = token.path.join('.'); + if (!v) throw new Error(`Missing shadow value for ${sp}`); + const blur = parseFloat(v.blur); + if (isNaN(blur)) throw new Error(`Non-numeric blur for ${sp}: "${v.blur}"`); + const spread = parseFloat(v.spread); + if (isNaN(spread)) throw new Error(`Non-numeric spread for ${sp}: "${v.spread}"`); + const offsetX = parseFloat(v.offsetX); + if (isNaN(offsetX)) throw new Error(`Non-numeric offsetX for ${sp}: "${v.offsetX}"`); + const offsetY = parseFloat(v.offsetY); + if (isNaN(offsetY)) throw new Error(`Non-numeric offsetY for ${sp}: "${v.offsetY}"`); + if (!v.color) throw new Error(`Missing color for ${sp}`); + const colorVal = toComposeColor(v.color, sp + '.color'); + + return [ + ` val ${propName}Blur = ${blur}.dp`, + ` val ${propName}OffsetX = ${offsetX}.dp`, + ` val ${propName}OffsetY = ${offsetY}.dp`, + ` val ${propName}Spread = ${spread}.dp`, + ` val ${propName}Color = ${colorVal}`, + ].join('\n'); + }); + + return [ + `package ${PACKAGE}`, + '', + 'import androidx.compose.ui.graphics.Color', + 'import androidx.compose.ui.unit.dp', + '', + '/**', + ' * Auto-generated from design tokens. Do not edit manually.', + ' */', + 'internal class TangemShadowTokens {', + entries.join('\n\n'), + '}', + '', + ].join('\n'); + }, +}); + +// ── Build ────────────────────────────────────────────────────────────────────── + +const composePlatformTransforms = [ + ...getTransforms({ platform: 'css' }), + 'name/camel', +]; + +// Build color tokens per theme (light/dark) +for (const [themeName, { sets }] of Object.entries(themeBuilds)) { + console.log(`\nBuilding ${themeName} color tokens...`); + + const sd = new StyleDictionary({ + source: sets.map(s => path.join(tokensDir, `${s}.json`)), + preprocessors: ['tokens-studio'], + usesDtcg: true, + log: { warnings: 'disabled', errors: { brokenReferences: 'console' } }, + platforms: { + compose: { + transforms: composePlatformTransforms, + buildPath: outputDir + '/', + files: [ + { + destination: `Tangem${themeName}ColorTokens.kt`, + format: 'kotlin/compose-colors', + options: { themeName }, + filter: token => token.$type === 'color' && !isSourceOnlyToken(token), + }, + ], + }, + }, + }); + + await sd.buildAllPlatforms(); + console.log(` ✓ Tangem${themeName}ColorTokens.kt`); +} + +// Build theme-independent tokens (dimensions, opacity, typography, shadows) +console.log('\nBuilding dimension, opacity, typography, and shadow tokens...'); + +const sd = new StyleDictionary({ + source: sharedBuildSets.map(s => path.join(tokensDir, `${s}.json`)), + preprocessors: ['tokens-studio'], + usesDtcg: true, + log: { warnings: 'disabled', errors: { brokenReferences: 'console' } }, + platforms: { + compose: { + transforms: composePlatformTransforms, + buildPath: outputDir + '/', + files: [ + { + destination: 'TangemDimensionTokens.kt', + format: 'kotlin/compose-dimensions', + filter: token => { + const t = token.$type; + return ( + token.path[0] !== 'font' && + (t === 'dimension' || t === 'borderRadius' || t === 'borderWidth') && + !isSourceOnlyToken(token) + ); + }, + }, + { + destination: 'TangemOpacityTokens.kt', + format: 'kotlin/compose-opacity', + filter: token => token.$type === 'opacity' && !isSourceOnlyToken(token), + }, + { + destination: 'TangemTypographyTokens.kt', + format: 'kotlin/compose-typography', + filter: token => token.$type === 'typography' && !isSourceOnlyToken(token), + }, + { + destination: 'TangemShadowTokens.kt', + format: 'kotlin/compose-shadows', + filter: token => (token.$type === 'shadow' || token.$type === 'boxShadow') && !isSourceOnlyToken(token), + }, + ], + }, + }, +}); + +await sd.buildAllPlatforms(); +console.log(' ✓ TangemDimensionTokens.kt'); +console.log(' ✓ TangemOpacityTokens.kt'); +console.log(' ✓ TangemTypographyTokens.kt'); +console.log(' ✓ TangemShadowTokens.kt'); + +// ── Write source hash ───────────────────────────────────────────────────────── +// Hash all token JSON files so Gradle can verify generated code matches ds-tokens. +function computeTokensHash() { + const files = []; + function walk(dir) { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) walk(full); + else if (entry.name.endsWith('.json')) files.push(full); + } + } + walk(tokensDir); + files.sort(); // deterministic order + + const hash = crypto.createHash('sha256'); + for (const file of files) { + hash.update(path.relative(tokensDir, file).split(path.sep).join('/')); + hash.update('\0'); + hash.update(fs.readFileSync(file)); + hash.update('\0'); + } + return hash.digest('hex'); +} + +const tokensHash = computeTokensHash(); +fs.writeFileSync(path.join(outputDir, '.tokens-hash'), tokensHash + '\n'); +console.log(` ✓ .tokens-hash (${tokensHash.substring(0, 12)}…)`); + +console.log(`\nDone! Output: ${outputDir}`); diff --git a/core/ui/token-gen/package-lock.json b/core/ui/token-gen/package-lock.json new file mode 100644 index 0000000000..2506a02e51 --- /dev/null +++ b/core/ui/token-gen/package-lock.json @@ -0,0 +1,1749 @@ +{ + "name": "tangem-token-gen", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tangem-token-gen", + "version": "1.0.0", + "devDependencies": { + "@tokens-studio/sd-transforms": "^2.0.3", + "style-dictionary": "^5.4.0" + } + }, + "node_modules/@bundled-es-modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-Rk453EklPUPC3NRWc3VUNI/SSUjdBaFoaQvFRmNBNtMHVtOFD5AntiWg5kEE1hqcPqedYFDzxE3ZcMYPcA195w==", + "dev": true, + "license": "ISC", + "dependencies": { + "deepmerge": "^4.3.1" + } + }, + "node_modules/@bundled-es-modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-x9nR2e1pt8LF0yLPC6yz/aUoiN7qJJwZ1znLxIXCxGyH+8BI+yO/sklBdn1+QbUyWXQBM+CjfZz3IhqtgIoDVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "events": "^3.3.0", + "glob": "^13.0.6", + "path": "^0.12.7", + "stream": "^0.0.3", + "string_decoder": "^1.3.0", + "url": "^0.11.4" + } + }, + "node_modules/@bundled-es-modules/memfs": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/memfs/-/memfs-4.17.0.tgz", + "integrity": "sha512-ykdrkEmQr9BV804yd37ikXfNnvxrwYfY9Z2/EtMHFEFadEjsQXJ1zL9bVZrKNLDtm91UdUOEHso6Aweg93K6xQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "assert": "^2.1.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "memfs": "^4.17.0", + "path": "^0.12.7", + "stream": "^0.0.3", + "util": "^0.12.5" + } + }, + "node_modules/@bundled-es-modules/postcss-calc-ast-parser": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/postcss-calc-ast-parser/-/postcss-calc-ast-parser-0.1.6.tgz", + "integrity": "sha512-y65TM5zF+uaxo9OeekJ3rxwTINlQvrkbZLogYvQYVoLtxm4xEiHfZ7e/MyiWbStYyWZVZkVqsaVU6F4SUK5XUA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-calc-ast-parser": "^0.1.4" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", + "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", + "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", + "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", + "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", + "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", + "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", + "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.1", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", + "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@tokens-studio/sd-transforms": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@tokens-studio/sd-transforms/-/sd-transforms-2.0.3.tgz", + "integrity": "sha512-PyrmRb7FuJBHzsbuWNk/O06hJbaZ+RL7chmK7PRbEptaSruhANai7Kxja5CiYnTcxOj373uRMDPxoFwCHaVpvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bundled-es-modules/deepmerge": "^4.3.1", + "@bundled-es-modules/postcss-calc-ast-parser": "^0.1.6", + "@tokens-studio/types": "^0.5.1", + "colorjs.io": "^0.5.2", + "expr-eval-fork": "^3.0.1", + "is-mergeable-object": "^1.1.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "style-dictionary": "^5.0.0" + } + }, + "node_modules/@tokens-studio/types": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@tokens-studio/types/-/types-0.5.2.tgz", + "integrity": "sha512-rzMcZP0bj2E5jaa7Fj0LGgYHysoCrbrxILVbT0ohsCUH5uCHY/u6J7Qw/TE0n6gR9Js/c9ZO9T8mOoz0HdLMbA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@zip.js/zip.js": { + "version": "2.8.26", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.8.26.tgz", + "integrity": "sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=18.0.0" + } + }, + "node_modules/assert": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.1.0.tgz", + "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-nan": "^1.3.2", + "object-is": "^1.1.5", + "object.assign": "^4.1.4", + "util": "^0.12.5" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorjs.io": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz", + "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/component-emitter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-2.0.0.tgz", + "integrity": "sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expr-eval-fork": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/expr-eval-fork/-/expr-eval-fork-3.0.3.tgz", + "integrity": "sha512-BhC+hbc5lIVjygr840n5DEkW3MQq7H9o+mc1/N7Z5uIiCFVyESLL5DIE7LNq4CYUNxy+XjA+3jRrL/h0Kt2xcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-mergeable-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-mergeable-object/-/is-mergeable-object-1.1.1.tgz", + "integrity": "sha512-CPduJfuGg8h8vW74WOxHtHmtQutyQBzR+3MjQ6iDHIYdbOnm1YC7jv43SqCoU8OPGTJD4nibmiryA4kmogbGrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz", + "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memfs": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", + "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.1", + "@jsonjoy.com/fs-fsa": "4.57.1", + "@jsonjoy.com/fs-node": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.57.1", + "@jsonjoy.com/fs-node-to-fsa": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-print": "4.57.1", + "@jsonjoy.com/fs-snapshot": "4.57.1", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-unified": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/path-unified/-/path-unified-0.2.0.tgz", + "integrity": "sha512-MNKqvrKbbbb5p7XHXV6ZAsf/1f/yJQa13S/fcX0uua8ew58Tgc6jXV+16JyAbnR/clgCH+euKDxrF2STxMHdrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/path/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/path/node_modules/util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss-calc-ast-parser": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/postcss-calc-ast-parser/-/postcss-calc-ast-parser-0.1.4.tgz", + "integrity": "sha512-CebpbHc96zgFjGgdQ6BqBy6XIUgRx1xXWCAAk6oke02RZ5nxwo9KQejTg8y7uYEeI9kv8jKQPYjoe6REsY23vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^3.3.1" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stream": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.3.tgz", + "integrity": "sha512-aMsbn7VKrl4A2T7QAQQbzgN7NVc70vgF5INQrBXqn4dCXN1zy3L9HGgLO5s7PExmdrzTJ8uR/27aviW8or8/+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^2.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/style-dictionary": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/style-dictionary/-/style-dictionary-5.4.0.tgz", + "integrity": "sha512-6BzO0DV19t6KUEXYfvHJ73d3y8bBDcd0wNLfoZRX817obJ8YX5Vev8Xh3+k9601tHE8qRJ/586iLt0byuY2THw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@bundled-es-modules/deepmerge": "^4.3.1", + "@bundled-es-modules/glob": "^13.0.6", + "@bundled-es-modules/memfs": "^4.17.0", + "@zip.js/zip.js": "^2.7.44", + "chalk": "^5.3.0", + "change-case": "^5.3.0", + "colorjs.io": "^0.5.2", + "commander": "^12.1.0", + "is-plain-obj": "^4.1.0", + "json5": "^2.2.2", + "path-unified": "^0.2.0", + "prettier": "^3.3.3", + "tinycolor2": "^1.6.0" + }, + "bin": { + "style-dictionary": "bin/style-dictionary.js" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/thingies": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + } + } +} diff --git a/core/ui/token-gen/package.json b/core/ui/token-gen/package.json new file mode 100644 index 0000000000..cfb40a9fc8 --- /dev/null +++ b/core/ui/token-gen/package.json @@ -0,0 +1,13 @@ +{ + "name": "tangem-token-gen", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "node build-tokens.mjs" + }, + "devDependencies": { + "style-dictionary": "^5.4.0", + "@tokens-studio/sd-transforms": "^2.0.3" + } +}