@hanzogui/static 4.3.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/check-dep-versions.cjs +1 -1
- package/dist/checkDeps.cjs +11 -11
- package/dist/constants.cjs +2 -2
- package/dist/exports.cjs +2 -2
- package/dist/extractor/babelParse.cjs +1 -1
- package/dist/extractor/bundle.cjs +23 -39
- package/dist/extractor/bundleConfig.cjs +51 -48
- package/dist/extractor/createExtractor.cjs +39 -39
- package/dist/extractor/createLogger.cjs +1 -1
- package/dist/extractor/extractHelpers.cjs +1 -1
- package/dist/extractor/extractMediaStyle.cjs +7 -7
- package/dist/extractor/extractToClassNames.cjs +9 -9
- package/dist/extractor/extractToNative.cjs +7 -7
- package/dist/extractor/{getGuiConfigPathFromOptionsConfig.cjs → getHanzoguiConfigPathFromOptionsConfig.cjs} +5 -5
- package/dist/extractor/getPrefixLogs.cjs +1 -1
- package/dist/extractor/getStaticBindingsForScope.cjs +2 -2
- package/dist/extractor/hasTopLevelAwait.cjs +62 -0
- package/dist/extractor/{loadGui.cjs → loadHanzogui.cjs} +97 -141
- package/dist/extractor/regenerateConfig.cjs +20 -20
- package/dist/extractor/{watchGuiConfig.cjs → watchHanzoguiConfig.cjs} +15 -15
- package/dist/getPragmaOptions.cjs +6 -6
- package/dist/helpers/{requireGuiCore.cjs → requireHanzoguiCore.cjs} +12 -12
- package/dist/registerRequire.cjs +58 -20
- package/dist/worker.cjs +3 -3
- package/package.json +22 -22
- package/src/check-dep-versions.ts +1 -5
- package/src/checkDeps.ts +28 -30
- package/src/constants.ts +2 -2
- package/src/exports.ts +2 -2
- package/src/extractor/babelParse.ts +1 -0
- package/src/extractor/bundle.ts +16 -18
- package/src/extractor/bundleConfig.ts +62 -62
- package/src/extractor/createEvaluator.ts +2 -2
- package/src/extractor/createExtractor.ts +62 -55
- package/src/extractor/createLogger.ts +5 -3
- package/src/extractor/esbuildTsconfigPaths.ts +1 -1
- package/src/extractor/extractHelpers.ts +15 -12
- package/src/extractor/extractMediaStyle.ts +19 -13
- package/src/extractor/extractToClassNames.ts +11 -11
- package/src/extractor/extractToNative.ts +13 -13
- package/src/extractor/{getGuiConfigPathFromOptionsConfig.ts → getHanzoguiConfigPathFromOptionsConfig.ts} +3 -3
- package/src/extractor/getPrefixLogs.ts +3 -3
- package/src/extractor/getStaticBindingsForScope.ts +2 -2
- package/src/extractor/hasTopLevelAwait.ts +28 -0
- package/src/extractor/{loadGui.ts → loadHanzogui.ts} +86 -83
- package/src/extractor/regenerateConfig.ts +34 -24
- package/src/extractor/{watchGuiConfig.ts → watchHanzoguiConfig.ts} +10 -10
- package/src/getPragmaOptions.ts +6 -6
- package/src/helpers/requireHanzoguiCore.ts +28 -0
- package/src/registerRequire.ts +79 -34
- package/src/server.ts +2 -2
- package/src/types.ts +13 -10
- package/src/worker.ts +7 -7
- package/types/check-dep-versions.d.ts.map +1 -1
- package/types/checkDeps.d.ts.map +1 -1
- package/types/constants.d.ts.map +1 -1
- package/types/exports.d.ts +2 -2
- package/types/exports.d.ts.map +1 -1
- package/types/extractor/babelParse.d.ts.map +1 -1
- package/types/extractor/bundle.d.ts +2 -2
- package/types/extractor/bundle.d.ts.map +1 -1
- package/types/extractor/bundleConfig.d.ts +12 -12
- package/types/extractor/bundleConfig.d.ts.map +1 -1
- package/types/extractor/createEvaluator.d.ts +2 -2
- package/types/extractor/createEvaluator.d.ts.map +1 -1
- package/types/extractor/createExtractor.d.ts +5 -5
- package/types/extractor/createExtractor.d.ts.map +1 -1
- package/types/extractor/createLogger.d.ts +2 -2
- package/types/extractor/createLogger.d.ts.map +1 -1
- package/types/extractor/extractHelpers.d.ts +8 -8
- package/types/extractor/extractHelpers.d.ts.map +1 -1
- package/types/extractor/extractMediaStyle.d.ts +4 -4
- package/types/extractor/extractMediaStyle.d.ts.map +1 -1
- package/types/extractor/extractToClassNames.d.ts +2 -2
- package/types/extractor/extractToClassNames.d.ts.map +1 -1
- package/types/extractor/extractToNative.d.ts +3 -3
- package/types/extractor/extractToNative.d.ts.map +1 -1
- package/types/extractor/getHanzoguiConfigPathFromOptionsConfig.d.ts +3 -0
- package/types/extractor/getHanzoguiConfigPathFromOptionsConfig.d.ts.map +1 -0
- package/types/extractor/getPrefixLogs.d.ts +2 -2
- package/types/extractor/getPrefixLogs.d.ts.map +1 -1
- package/types/extractor/hasTopLevelAwait.d.ts +2 -0
- package/types/extractor/hasTopLevelAwait.d.ts.map +1 -0
- package/types/extractor/loadHanzogui.d.ts +22 -0
- package/types/extractor/loadHanzogui.d.ts.map +1 -0
- package/types/extractor/regenerateConfig.d.ts +4 -4
- package/types/extractor/regenerateConfig.d.ts.map +1 -1
- package/types/extractor/watchHanzoguiConfig.d.ts +5 -0
- package/types/extractor/watchHanzoguiConfig.d.ts.map +1 -0
- package/types/helpers/requireHanzoguiCore.d.ts +3 -0
- package/types/helpers/requireHanzoguiCore.d.ts.map +1 -0
- package/types/registerRequire.d.ts +3 -3
- package/types/registerRequire.d.ts.map +1 -1
- package/types/server.d.ts +2 -2
- package/types/server.d.ts.map +1 -1
- package/types/types.d.ts +10 -10
- package/types/types.d.ts.map +1 -1
- package/types/worker.d.ts +4 -4
- package/types/worker.d.ts.map +1 -1
- package/src/helpers/requireGuiCore.ts +0 -28
- package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts +0 -3
- package/types/extractor/getGuiConfigPathFromOptionsConfig.d.ts.map +0 -1
- package/types/extractor/loadGui.d.ts +0 -22
- package/types/extractor/loadGui.d.ts.map +0 -1
- package/types/extractor/watchGuiConfig.d.ts +0 -5
- package/types/extractor/watchGuiConfig.d.ts.map +0 -1
- package/types/helpers/requireGuiCore.d.ts +0 -3
- package/types/helpers/requireGuiCore.d.ts.map +0 -1
|
@@ -1,65 +1,75 @@
|
|
|
1
1
|
import { dirname, join } from 'node:path'
|
|
2
2
|
|
|
3
3
|
import { generateThemes, writeGeneratedThemes } from '@hanzogui/generate-themes'
|
|
4
|
-
import type {
|
|
4
|
+
import type { HanzoguiOptions } from '@hanzogui/types'
|
|
5
5
|
import * as FS from 'fs-extra'
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import type {
|
|
7
|
+
import { requireHanzoguiCore } from '../helpers/requireHanzoguiCore'
|
|
8
|
+
import type { HanzoguiPlatform } from '../types'
|
|
9
9
|
import type { BundledConfig } from './bundleConfig'
|
|
10
10
|
import { getBundledConfig } from './bundleConfig'
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
const confFile = join(
|
|
12
|
+
const hanzoguiDir = join(process.cwd(), '.hanzogui')
|
|
13
|
+
const confFile = join(hanzoguiDir, 'hanzogui.config.json')
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Sort of a super-set of bundleConfig(), this code needs some refactoring ideally
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export async function regenerateConfig(
|
|
20
|
-
|
|
20
|
+
hanzoguiOptions: HanzoguiOptions,
|
|
21
21
|
configIn?: BundledConfig | null,
|
|
22
22
|
rebuild = false
|
|
23
23
|
) {
|
|
24
24
|
try {
|
|
25
25
|
// this has a side effect of rebuilding config and css!
|
|
26
26
|
// need to improve code here:
|
|
27
|
-
const config = configIn ?? (await getBundledConfig(
|
|
27
|
+
const config = configIn ?? (await getBundledConfig(hanzoguiOptions, rebuild))
|
|
28
28
|
if (!config) return
|
|
29
|
-
const out = transformConfig(config,
|
|
29
|
+
const out = transformConfig(config, hanzoguiOptions.platform || 'web')
|
|
30
30
|
|
|
31
31
|
await FS.ensureDir(dirname(confFile))
|
|
32
32
|
await FS.writeJSON(confFile, out, {
|
|
33
33
|
spaces: 2,
|
|
34
34
|
})
|
|
35
35
|
} catch (err) {
|
|
36
|
-
if (process.env.DEBUG?.includes('
|
|
36
|
+
if (process.env.DEBUG?.includes('hanzogui') || process.env.IS_TAMAGUI_DEV) {
|
|
37
37
|
console.warn('regenerateConfig error', err)
|
|
38
38
|
}
|
|
39
39
|
// ignore for now
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export function regenerateConfigSync(
|
|
43
|
+
export function regenerateConfigSync(
|
|
44
|
+
_hanzoguiOptions: HanzoguiOptions,
|
|
45
|
+
config: BundledConfig
|
|
46
|
+
) {
|
|
44
47
|
try {
|
|
45
48
|
FS.ensureDirSync(dirname(confFile))
|
|
46
|
-
FS.writeJSONSync(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
FS.writeJSONSync(
|
|
50
|
+
confFile,
|
|
51
|
+
transformConfig(config, _hanzoguiOptions.platform || 'web'),
|
|
52
|
+
{
|
|
53
|
+
spaces: 2,
|
|
54
|
+
}
|
|
55
|
+
)
|
|
49
56
|
} catch (err) {
|
|
50
|
-
if (process.env.DEBUG?.includes('
|
|
57
|
+
if (process.env.DEBUG?.includes('hanzogui') || process.env.IS_TAMAGUI_DEV) {
|
|
51
58
|
console.warn('regenerateConfig error', err)
|
|
52
59
|
}
|
|
53
60
|
// ignore for now
|
|
54
61
|
}
|
|
55
62
|
}
|
|
56
63
|
|
|
57
|
-
export async function
|
|
58
|
-
|
|
64
|
+
export async function generateHanzoguiThemes(
|
|
65
|
+
hanzoguiOptions: HanzoguiOptions,
|
|
66
|
+
force = false
|
|
67
|
+
) {
|
|
68
|
+
if (!hanzoguiOptions.themeBuilder) {
|
|
59
69
|
return
|
|
60
70
|
}
|
|
61
71
|
|
|
62
|
-
const { input, output } =
|
|
72
|
+
const { input, output } = hanzoguiOptions.themeBuilder
|
|
63
73
|
const inPath = resolveRelativePath(input)
|
|
64
74
|
const outPath = resolveRelativePath(output)
|
|
65
75
|
const generatedOutput = await generateThemes(inPath)
|
|
@@ -80,7 +90,7 @@ export async function generateGuiThemes(guiOptions: GuiOptions, force = false) {
|
|
|
80
90
|
})())
|
|
81
91
|
|
|
82
92
|
if (hasChanged) {
|
|
83
|
-
await writeGeneratedThemes(
|
|
93
|
+
await writeGeneratedThemes(hanzoguiDir, outPath, generatedOutput)
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
return hasChanged
|
|
@@ -100,20 +110,20 @@ function cloneDeepSafe(x: any, excludeKeys = {}) {
|
|
|
100
110
|
)
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
function transformConfig(config: BundledConfig, platform:
|
|
113
|
+
function transformConfig(config: BundledConfig, platform: HanzoguiPlatform) {
|
|
104
114
|
if (!config) {
|
|
105
115
|
return null
|
|
106
116
|
}
|
|
107
117
|
|
|
108
|
-
const { getVariableValue } =
|
|
118
|
+
const { getVariableValue } = requireHanzoguiCore(platform)
|
|
109
119
|
|
|
110
120
|
// ensure we don't mangle anything in the original
|
|
111
121
|
const next = cloneDeepSafe(config, {
|
|
112
122
|
validStyles: true,
|
|
113
123
|
}) as BundledConfig
|
|
114
124
|
|
|
115
|
-
const { components, nameToPaths,
|
|
116
|
-
const { themes, tokens } =
|
|
125
|
+
const { components, nameToPaths, hanzoguiConfig } = next
|
|
126
|
+
const { themes, tokens } = hanzoguiConfig
|
|
117
127
|
|
|
118
128
|
// reduce down to usable, smaller json
|
|
119
129
|
|
|
@@ -162,12 +172,12 @@ function transformConfig(config: BundledConfig, platform: GuiPlatform) {
|
|
|
162
172
|
shorthands: _shorthands,
|
|
163
173
|
userShorthands,
|
|
164
174
|
...cleanedConfig
|
|
165
|
-
} = next.
|
|
175
|
+
} = next.hanzoguiConfig
|
|
166
176
|
|
|
167
177
|
return {
|
|
168
178
|
components,
|
|
169
179
|
nameToPaths,
|
|
170
|
-
|
|
180
|
+
hanzoguiConfig: {
|
|
171
181
|
...cleanedConfig,
|
|
172
182
|
// Output userShorthands as shorthands (excludes built-ins)
|
|
173
183
|
shorthands: userShorthands,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { esbuildWatchFiles, generateThemesAndLog, getOptions } from './
|
|
1
|
+
import type { HanzoguiOptions } from '@hanzogui/types'
|
|
2
|
+
import { esbuildWatchFiles, generateThemesAndLog, getOptions } from './loadHanzogui'
|
|
3
3
|
import { regenerateConfig } from './regenerateConfig'
|
|
4
4
|
|
|
5
5
|
let isWatching = false
|
|
6
6
|
|
|
7
|
-
export async function
|
|
7
|
+
export async function watchHanzoguiConfig(hanzoguiOptions: HanzoguiOptions) {
|
|
8
8
|
if (process.env.NODE_ENV === 'production') {
|
|
9
9
|
return {
|
|
10
10
|
dispose() {},
|
|
@@ -17,22 +17,22 @@ export async function watchGuiConfig(guiOptions: GuiOptions) {
|
|
|
17
17
|
|
|
18
18
|
isWatching = true
|
|
19
19
|
|
|
20
|
-
const options = await getOptions({
|
|
20
|
+
const options = await getOptions({ hanzoguiOptions })
|
|
21
21
|
|
|
22
|
-
if (!options.
|
|
22
|
+
if (!options.hanzoguiOptions.config) {
|
|
23
23
|
isWatching = false
|
|
24
24
|
throw new Error(`No config`)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const disposeConfigWatcher = await esbuildWatchFiles(
|
|
28
|
-
options.
|
|
28
|
+
options.hanzoguiOptions.config,
|
|
29
29
|
async () => {
|
|
30
|
-
await generateThemesAndLog(options.
|
|
31
|
-
await regenerateConfig(options.
|
|
30
|
+
await generateThemesAndLog(options.hanzoguiOptions)
|
|
31
|
+
await regenerateConfig(options.hanzoguiOptions, null, true)
|
|
32
32
|
}
|
|
33
33
|
)
|
|
34
34
|
|
|
35
|
-
const themeBuilderInput = options.
|
|
35
|
+
const themeBuilderInput = options.hanzoguiOptions.themeBuilder?.input
|
|
36
36
|
let disposeThemesWatcher: Function | undefined
|
|
37
37
|
|
|
38
38
|
if (themeBuilderInput) {
|
|
@@ -43,7 +43,7 @@ export async function watchGuiConfig(guiOptions: GuiOptions) {
|
|
|
43
43
|
// ok
|
|
44
44
|
}
|
|
45
45
|
disposeThemesWatcher = await esbuildWatchFiles(inputPath, async () => {
|
|
46
|
-
await generateThemesAndLog(options.
|
|
46
|
+
await generateThemesAndLog(options.hanzoguiOptions)
|
|
47
47
|
})
|
|
48
48
|
}
|
|
49
49
|
|
package/src/getPragmaOptions.ts
CHANGED
|
@@ -14,7 +14,7 @@ export function getPragmaOptions({ source, path }: { source: string; path: strin
|
|
|
14
14
|
}
|
|
15
15
|
pragma =
|
|
16
16
|
trimmed
|
|
17
|
-
.match(/(\/\/|\/\*)\s?!?\s?(
|
|
17
|
+
.match(/(\/\/|\/\*)\s?!?\s?(hanzogui-ignore|debug|debug-verbose)(\n|\s|$).*/)?.[2]
|
|
18
18
|
.trim() || ''
|
|
19
19
|
if (pragma) {
|
|
20
20
|
pragma = pragma.replace('!', '').trim()
|
|
@@ -23,7 +23,7 @@ export function getPragmaOptions({ source, path }: { source: string; path: strin
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
switch (pragma) {
|
|
26
|
-
case '
|
|
26
|
+
case 'hanzogui-ignore':
|
|
27
27
|
shouldDisable = true
|
|
28
28
|
break
|
|
29
29
|
|
|
@@ -36,17 +36,17 @@ export function getPragmaOptions({ source, path }: { source: string; path: strin
|
|
|
36
36
|
break
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
if (process.env.
|
|
40
|
-
if (path.includes(process.env.
|
|
39
|
+
if (process.env.TAMAGUI_DEBUG_FILE) {
|
|
40
|
+
if (path.includes(process.env.TAMAGUI_DEBUG_FILE)) {
|
|
41
41
|
shouldPrintDebug = 'verbose'
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
if (process.env.DEBUG?.includes('
|
|
45
|
+
if (process.env.DEBUG?.includes('hanzogui')) {
|
|
46
46
|
shouldPrintDebug ||= true
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
if (process.env.DEBUG?.includes('
|
|
49
|
+
if (process.env.DEBUG?.includes('hanzogui-verbose')) {
|
|
50
50
|
shouldPrintDebug = 'verbose'
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// this allows us to swap between core native and web in the same process:
|
|
2
|
+
|
|
3
|
+
import type { HanzoguiPlatform } from '../types'
|
|
4
|
+
|
|
5
|
+
export function requireHanzoguiCore(
|
|
6
|
+
platform: HanzoguiPlatform,
|
|
7
|
+
ogRequire: Function = require
|
|
8
|
+
): typeof import('@hanzogui/core') {
|
|
9
|
+
if (!platform) {
|
|
10
|
+
throw new Error(`No platform given to requireHanzoguiCore`)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// avoid tree shaking out themes
|
|
14
|
+
const og1 = process.env.TAMAGUI_IS_SERVER
|
|
15
|
+
const og2 = process.env.TAMAGUI_KEEP_THEMES
|
|
16
|
+
process.env.TAMAGUI_IS_SERVER ||= '1'
|
|
17
|
+
process.env.TAMAGUI_KEEP_THEMES ||= '1'
|
|
18
|
+
|
|
19
|
+
const exported = ogRequire(
|
|
20
|
+
platform === 'native' ? '@hanzogui/core/native' : '@hanzogui/core'
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
// restore back
|
|
24
|
+
process.env.TAMAGUI_IS_SERVER = og1
|
|
25
|
+
process.env.TAMAGUI_KEEP_THEMES = og2
|
|
26
|
+
|
|
27
|
+
return exported
|
|
28
|
+
}
|
package/src/registerRequire.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { register } from 'esbuild-register/dist/node'
|
|
2
2
|
|
|
3
3
|
import { esbuildIgnoreFilesRegex } from './extractor/bundle'
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
4
|
+
import { requireHanzoguiCore } from './helpers/requireHanzoguiCore'
|
|
5
|
+
import type { HanzoguiPlatform } from './types'
|
|
6
6
|
|
|
7
7
|
const nameToPaths = {}
|
|
8
8
|
|
|
@@ -23,8 +23,38 @@ export function setRequireResult(name: string, result: any) {
|
|
|
23
23
|
compiled[name] = result
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
function getStaticExtractionStub(path: string) {
|
|
27
|
+
switch (path) {
|
|
28
|
+
case 'expo-constants':
|
|
29
|
+
return {
|
|
30
|
+
__esModule: true,
|
|
31
|
+
default: {
|
|
32
|
+
executionEnvironment: null,
|
|
33
|
+
},
|
|
34
|
+
ExecutionEnvironment: {
|
|
35
|
+
Bare: 'bare',
|
|
36
|
+
Standalone: 'standalone',
|
|
37
|
+
StoreClient: 'storeClient',
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
case 'expo-updates':
|
|
41
|
+
return {
|
|
42
|
+
__esModule: true,
|
|
43
|
+
default: {
|
|
44
|
+
isEnabled: false,
|
|
45
|
+
isUsingEmbeddedAssets: true,
|
|
46
|
+
},
|
|
47
|
+
checkForUpdateAsync: async () => ({ isAvailable: false }),
|
|
48
|
+
fetchUpdateAsync: async () => ({ isNew: false }),
|
|
49
|
+
reloadAsync: async () => {},
|
|
50
|
+
}
|
|
51
|
+
default:
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
26
56
|
export function registerRequire(
|
|
27
|
-
platform:
|
|
57
|
+
platform: HanzoguiPlatform,
|
|
28
58
|
{ proxyWormImports } = {
|
|
29
59
|
proxyWormImports: false,
|
|
30
60
|
}
|
|
@@ -32,23 +62,22 @@ export function registerRequire(
|
|
|
32
62
|
// already registered
|
|
33
63
|
if (isRegistered) {
|
|
34
64
|
return {
|
|
35
|
-
|
|
65
|
+
hanzoguiRequire: require,
|
|
36
66
|
unregister: () => {},
|
|
37
67
|
}
|
|
38
68
|
}
|
|
39
69
|
|
|
40
70
|
// capture original resolve BEFORE esbuild-register patches it
|
|
41
|
-
// so we can use Node's native exports resolution for @
|
|
71
|
+
// so we can use Node's native exports resolution for @hanzogui packages
|
|
42
72
|
const originalResolveFilename = Module._resolveFilename
|
|
43
73
|
|
|
44
74
|
const { unregister } = register({
|
|
45
75
|
hookIgnoreNodeModules: false,
|
|
46
|
-
// don't transform @
|
|
76
|
+
// don't transform @hanzogui packages - they have pre-built dist files
|
|
47
77
|
hookMatcher: (filename) => {
|
|
48
78
|
if (
|
|
49
|
-
filename.includes('@
|
|
50
|
-
|
|
51
|
-
/\/(hanzo\/gui|gui)\/code\/(core|ui|packages)\//.test(filename)
|
|
79
|
+
filename.includes('@hanzogui') ||
|
|
80
|
+
/\/hanzogui\/code\/(core|ui|packages)\//.test(filename)
|
|
52
81
|
) {
|
|
53
82
|
return false
|
|
54
83
|
}
|
|
@@ -58,10 +87,10 @@ export function registerRequire(
|
|
|
58
87
|
|
|
59
88
|
// esbuild-register's registerTsconfigPaths replaces Module._resolveFilename
|
|
60
89
|
// but tsconfig paths resolution bypasses Node's package exports
|
|
61
|
-
// we need to restore Node's native resolution for @
|
|
90
|
+
// we need to restore Node's native resolution for @hanzogui packages
|
|
62
91
|
const tsconfigPatchedResolve = Module._resolveFilename
|
|
63
92
|
Module._resolveFilename = function (request: string, ...args: any[]) {
|
|
64
|
-
// for @
|
|
93
|
+
// for @hanzogui packages, use Node's native resolution (respects exports)
|
|
65
94
|
if (request.startsWith('@hanzogui/')) {
|
|
66
95
|
return originalResolveFilename.call(this, request, ...args)
|
|
67
96
|
}
|
|
@@ -75,15 +104,20 @@ export function registerRequire(
|
|
|
75
104
|
|
|
76
105
|
isRegistered = true
|
|
77
106
|
|
|
78
|
-
Module.prototype.require =
|
|
107
|
+
Module.prototype.require = hanzoguiRequire
|
|
108
|
+
|
|
109
|
+
function hanzoguiRequire(this: any, path: string) {
|
|
110
|
+
const staticExtractionStub = getStaticExtractionStub(path)
|
|
111
|
+
if (staticExtractionStub) {
|
|
112
|
+
return staticExtractionStub
|
|
113
|
+
}
|
|
79
114
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return og.apply(this, ['@hanzo/gui/native'])
|
|
115
|
+
if (path === 'hanzogui' && platform === 'native') {
|
|
116
|
+
return og.apply(this, ['hanzogui/native'])
|
|
83
117
|
}
|
|
84
118
|
|
|
85
119
|
if (path === '@hanzogui/core') {
|
|
86
|
-
return
|
|
120
|
+
return requireHanzoguiCore(platform, (path) => {
|
|
87
121
|
return og.apply(this, [path])
|
|
88
122
|
})
|
|
89
123
|
}
|
|
@@ -121,16 +155,27 @@ export function registerRequire(
|
|
|
121
155
|
}
|
|
122
156
|
|
|
123
157
|
if (!whitelisted[path]) {
|
|
124
|
-
if (proxyWormImports && !path.includes('.
|
|
125
|
-
// allow
|
|
158
|
+
if (proxyWormImports && !path.includes('.hanzogui-dynamic-eval')) {
|
|
159
|
+
// allow hanzogui and its sub-packages through - they re-export components
|
|
126
160
|
// with staticConfig needed for dynamic eval optimization.
|
|
127
|
-
// also allow requires FROM within
|
|
161
|
+
// also allow requires FROM within hanzogui packages (relative imports like ./Separator.cjs)
|
|
128
162
|
const callerFile = this?.filename || this?.id || ''
|
|
129
|
-
const
|
|
130
|
-
callerFile.includes('@
|
|
131
|
-
|
|
132
|
-
callerFile
|
|
133
|
-
|
|
163
|
+
const isFromHanzoguiPkg =
|
|
164
|
+
callerFile.includes('@hanzogui') || callerFile.includes('node_modules/hanzogui/')
|
|
165
|
+
const isFromStaticLoader =
|
|
166
|
+
!callerFile ||
|
|
167
|
+
callerFile === '.' ||
|
|
168
|
+
callerFile === '[eval]' ||
|
|
169
|
+
callerFile.endsWith('/[eval]') ||
|
|
170
|
+
callerFile.includes('/code/compiler/static/') ||
|
|
171
|
+
callerFile.includes('/.hanzogui/')
|
|
172
|
+
|
|
173
|
+
if (
|
|
174
|
+
path === 'hanzogui' ||
|
|
175
|
+
path.startsWith('@hanzogui/') ||
|
|
176
|
+
isFromHanzoguiPkg ||
|
|
177
|
+
isFromStaticLoader
|
|
178
|
+
) {
|
|
134
179
|
return og.apply(this, [path])
|
|
135
180
|
}
|
|
136
181
|
return proxyWorm
|
|
@@ -165,15 +210,15 @@ export function registerRequire(
|
|
|
165
210
|
return out
|
|
166
211
|
} catch (err: any) {
|
|
167
212
|
if (
|
|
168
|
-
!process.env.
|
|
169
|
-
path.includes('
|
|
213
|
+
!process.env.TAMAGUI_ENABLE_WARN_DYNAMIC_LOAD &&
|
|
214
|
+
path.includes('hanzogui-dynamic-eval')
|
|
170
215
|
) {
|
|
171
216
|
// ok, dynamic eval fails
|
|
172
217
|
return
|
|
173
218
|
}
|
|
174
219
|
if (allowedIgnores[path] || IGNORES === 'true') {
|
|
175
220
|
// ignore
|
|
176
|
-
} else if (!process.env.
|
|
221
|
+
} else if (!process.env.TAMAGUI_SHOW_FULL_BUNDLE_ERRORS && !process.env.DEBUG) {
|
|
177
222
|
if (hasWarnedForModules.has(path)) {
|
|
178
223
|
// ignore
|
|
179
224
|
} else {
|
|
@@ -186,7 +231,7 @@ export function registerRequire(
|
|
|
186
231
|
*/
|
|
187
232
|
|
|
188
233
|
console.warn(
|
|
189
|
-
` [
|
|
234
|
+
` [hanzogui] skipped "${path}" (set TAMAGUI_IGNORE_BUNDLE_ERRORS="${path}" to silence)`
|
|
190
235
|
)
|
|
191
236
|
}
|
|
192
237
|
|
|
@@ -195,11 +240,11 @@ export function registerRequire(
|
|
|
195
240
|
}
|
|
196
241
|
|
|
197
242
|
return {
|
|
198
|
-
|
|
243
|
+
hanzoguiRequire,
|
|
199
244
|
unregister: () => {
|
|
200
245
|
if (hasWarnedForModules.size) {
|
|
201
246
|
console.info(
|
|
202
|
-
` [
|
|
247
|
+
` [hanzogui] skipped loading ${hasWarnedForModules.size} module, see: https://hanzogui.dev/docs/intro/errors#warning-001`
|
|
203
248
|
)
|
|
204
249
|
hasWarnedForModules.clear()
|
|
205
250
|
}
|
|
@@ -211,9 +256,9 @@ export function registerRequire(
|
|
|
211
256
|
}
|
|
212
257
|
}
|
|
213
258
|
|
|
214
|
-
const IGNORES =
|
|
215
|
-
|
|
216
|
-
|
|
259
|
+
const IGNORES = process.env.TAMAGUI_IGNORE_BUNDLE_ERRORS
|
|
260
|
+
const extraIgnores =
|
|
261
|
+
IGNORES === 'true' ? [] : process.env.TAMAGUI_IGNORE_BUNDLE_ERRORS?.split(',')
|
|
217
262
|
|
|
218
263
|
const knownIgnorableModules = {
|
|
219
264
|
'@gorhom/bottom-sheet': true,
|
|
@@ -221,7 +266,7 @@ const knownIgnorableModules = {
|
|
|
221
266
|
solito: true,
|
|
222
267
|
'expo-linear-gradient': true,
|
|
223
268
|
'@expo/vector-icons': true,
|
|
224
|
-
'
|
|
269
|
+
'hanzogui/linear-gradient': true,
|
|
225
270
|
// animation libraries not needed for static extraction
|
|
226
271
|
'@emotion/is-prop-valid': true,
|
|
227
272
|
'framer-motion': true,
|
package/src/server.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { HanzoguiOptions } from './types'
|
|
2
2
|
|
|
3
3
|
import net from 'node:net'
|
|
4
4
|
|
|
5
|
-
export async function startServer(options:
|
|
5
|
+
export async function startServer(options: HanzoguiOptions) {
|
|
6
6
|
const port = await getAvailablePort()
|
|
7
7
|
const server = net.createServer()
|
|
8
8
|
server.unref()
|
package/src/types.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { NodePath } from '@babel/traverse'
|
|
2
2
|
import type * as t from '@babel/types'
|
|
3
|
-
import type { PseudoStyles, StaticConfig,
|
|
3
|
+
import type { PseudoStyles, StaticConfig, HanzoguiConfig } from '@hanzogui/core'
|
|
4
4
|
import type { StyleObject } from '@hanzogui/helpers'
|
|
5
|
-
import type {
|
|
5
|
+
import type { HanzoguiOptions } from '@hanzogui/types'
|
|
6
6
|
import type { ViewStyle } from 'react-native'
|
|
7
7
|
|
|
8
8
|
import type { LoadedComponents } from './extractor/bundleConfig'
|
|
9
9
|
|
|
10
|
-
export type
|
|
10
|
+
export type HanzoguiPlatform = 'native' | 'web'
|
|
11
11
|
|
|
12
|
-
export type {
|
|
12
|
+
export type { HanzoguiOptions, HanzoguiBuildOptions } from '@hanzogui/types'
|
|
13
13
|
|
|
14
14
|
export type { StyleObject } from '@hanzogui/helpers'
|
|
15
15
|
|
|
@@ -33,7 +33,7 @@ export interface Logger {
|
|
|
33
33
|
|
|
34
34
|
export type ExtractorOptions = {
|
|
35
35
|
logger?: Logger
|
|
36
|
-
platform?:
|
|
36
|
+
platform?: HanzoguiPlatform
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export type ExtractedAttrAttr = {
|
|
@@ -58,7 +58,7 @@ export type ExtractedTernaryAttr = {
|
|
|
58
58
|
export type ExtractedAttr = ExtractedAttrAttr | ExtractedTernaryAttr | ExtractedAttrStyle
|
|
59
59
|
|
|
60
60
|
export type ExtractTagProps = {
|
|
61
|
-
parserProps:
|
|
61
|
+
parserProps: HanzoguiOptionsWithFileInfo
|
|
62
62
|
attrs: ExtractedAttr[]
|
|
63
63
|
node: t.JSXOpeningElement
|
|
64
64
|
attemptEval: (exprNode: t.Node, evalFn?: ((node: t.Node) => any) | undefined) => any
|
|
@@ -70,16 +70,19 @@ export type ExtractTagProps = {
|
|
|
70
70
|
filePath: string
|
|
71
71
|
completeProps: Record<string, any>
|
|
72
72
|
staticConfig: StaticConfig
|
|
73
|
-
config:
|
|
73
|
+
config: HanzoguiConfig
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export type
|
|
76
|
+
export type HanzoguiOptionsWithFileInfo = HanzoguiOptions & {
|
|
77
77
|
sourcePath?: string
|
|
78
78
|
allLoadedComponents: LoadedComponents[]
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
export type ExtractorParseProps = Omit<
|
|
82
|
-
|
|
81
|
+
export type ExtractorParseProps = Omit<
|
|
82
|
+
HanzoguiOptionsWithFileInfo,
|
|
83
|
+
'allLoadedComponents'
|
|
84
|
+
> & {
|
|
85
|
+
platform: HanzoguiPlatform
|
|
83
86
|
shouldPrintDebug?: boolean | 'verbose'
|
|
84
87
|
onExtractTag: (props: ExtractTagProps) => void
|
|
85
88
|
getFlattenedNode?: (props: { isTextView: boolean; tag: string }) => string
|
package/src/worker.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Worker thread implementation for
|
|
2
|
+
* Worker thread implementation for Hanzogui extraction
|
|
3
3
|
* Used by both piscina (async) and synckit (sync for babel)
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ import { createExtractor } from './extractor/createExtractor'
|
|
|
8
8
|
import type { ExtractedResponse } from './extractor/extractToClassNames'
|
|
9
9
|
import { extractToClassNames as extractToClassNamesImpl } from './extractor/extractToClassNames'
|
|
10
10
|
import { extractToNative as extractToNativeImpl } from './extractor/extractToNative'
|
|
11
|
-
import type {
|
|
11
|
+
import type { HanzoguiOptions } from './types'
|
|
12
12
|
|
|
13
13
|
// Create extractors lazily to avoid loading unused ones
|
|
14
14
|
let webExtractor: ReturnType<typeof createExtractor> | null = null
|
|
@@ -35,7 +35,7 @@ export interface ExtractToClassNamesTask {
|
|
|
35
35
|
type: 'extractToClassNames'
|
|
36
36
|
source: string
|
|
37
37
|
sourcePath: string
|
|
38
|
-
options:
|
|
38
|
+
options: HanzoguiOptions
|
|
39
39
|
shouldPrintDebug: boolean | 'verbose'
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ export interface ExtractToNativeTask {
|
|
|
43
43
|
type: 'extractToNative'
|
|
44
44
|
sourceFileName: string
|
|
45
45
|
sourceCode: string
|
|
46
|
-
options:
|
|
46
|
+
options: HanzoguiOptions
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export interface ClearCacheTask {
|
|
@@ -68,14 +68,14 @@ export async function runTask(task: WorkerTask): Promise<WorkerResult> {
|
|
|
68
68
|
// only skip if both extraction AND debug attrs are disabled (fully disabled)
|
|
69
69
|
const isFullyDisabled =
|
|
70
70
|
task.options.disableExtraction && task.options.disableDebugAttr
|
|
71
|
-
if (!isFullyDisabled && !task.options['
|
|
71
|
+
if (!isFullyDisabled && !task.options['_disableLoadHanzogui']) {
|
|
72
72
|
const cacheKey = JSON.stringify({
|
|
73
73
|
config: task.options.config,
|
|
74
74
|
components: task.options.components,
|
|
75
75
|
})
|
|
76
76
|
|
|
77
77
|
if (!configCache.has(cacheKey)) {
|
|
78
|
-
configCache.set(cacheKey, getWebExtractor().
|
|
78
|
+
configCache.set(cacheKey, getWebExtractor().loadHanzogui(task.options))
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
await configCache.get(cacheKey)
|
|
@@ -100,7 +100,7 @@ export async function runTask(task: WorkerTask): Promise<WorkerResult> {
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
if (!configCache.has(cacheKey)) {
|
|
103
|
-
configCache.set(cacheKey, getNativeExtractor().
|
|
103
|
+
configCache.set(cacheKey, getNativeExtractor().loadHanzogui(task.options))
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
await configCache.get(cacheKey)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-dep-versions.d.ts","sourceRoot":"","sources":["../src/check-dep-versions.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"check-dep-versions.d.ts","sourceRoot":"","sources":["../src/check-dep-versions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8oBH,+CAA+C;AAC/C,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,SAAS;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,SAAS;YAAE,YAAY,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC9C,EAAE,CAAA;CACJ,CAAA;AAED,qBAAa,IAAI;IACf,4GAA4G;IAC5G,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAE3C;;;;;;;;;;OAUG;gBACS,IAAI,EAAE,MAAM;IAKjB,iBAAiB,IAAI,MAAM;IAI3B,eAAe,IAAI,SAAS,UAAU,EAAE;IAMxC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAc9C,IAAW,0BAA0B,IAAI,OAAO,CAE/C;CACF"}
|
package/types/checkDeps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkDeps.d.ts","sourceRoot":"","sources":["../src/checkDeps.ts"],"names":[],"mappings":"AAIA,oBAAY,eAAe;IACzB,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,oBAAoB,yBAAyB;IAC7C,gBAAgB,qBAAqB;IACrC,WAAW,gBAAgB;CAC5B;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,eAAe,EAAE,EAAE,CAAA;IACzC,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACtC,CAAA;
|
|
1
|
+
{"version":3,"file":"checkDeps.d.ts","sourceRoot":"","sources":["../src/checkDeps.ts"],"names":[],"mappings":"AAIA,oBAAY,eAAe;IACzB,YAAY,iBAAiB;IAC7B,eAAe,oBAAoB;IACnC,oBAAoB,yBAAyB;IAC7C,gBAAgB,qBAAqB;IACrC,WAAW,gBAAgB;CAC5B;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,eAAe,EAAE,EAAE,CAAA;IACzC,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACtC,CAAA;AA+TD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,iBA8B3C"}
|
package/types/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAG1C,eAAO,MAAM,SAAS,MAAM,CAAA;AAG5B,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,gBAAgB,CAAA;AAG1C,eAAO,MAAM,SAAS,MAAM,CAAA;AAG5B,eAAO,MAAM,QAAQ,KAAmD,CAAA;AAExE,eAAO,MAAM,WAAW,eAA8B,CAAA;AAEtD,eAAO,MAAM,YAAY,qBAC+C,CAAA"}
|
package/types/exports.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export * from './extractor/extractToClassNames';
|
|
|
7
7
|
export * from './extractor/concatClassName';
|
|
8
8
|
export * from './extractor/extractToNative';
|
|
9
9
|
export * from './extractor/extractHelpers';
|
|
10
|
-
export * from './extractor/
|
|
11
|
-
export * from './extractor/
|
|
10
|
+
export * from './extractor/loadHanzogui';
|
|
11
|
+
export * from './extractor/watchHanzoguiConfig';
|
|
12
12
|
export * from './extractor/createLogger';
|
|
13
13
|
export * from './registerRequire';
|
|
14
14
|
export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat';
|
package/types/exports.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,
|
|
1
|
+
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACrF,cAAc,oBAAoB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babelParse.d.ts","sourceRoot":"","sources":["../../src/extractor/babelParse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"babelParse.d.ts","sourceRoot":"","sources":["../../src/extractor/babelParse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,KAAK,CAAC,MAAM,cAAc,CAAA;AAkBtC,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,aAGtC,CAAA;AAIF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,CAW3E"}
|