@litsx/babel-preset-litsx 0.2.0 → 0.3.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/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/internal/transform-litsx-components.cjs +316 -40
- package/dist/internal/transform-litsx-components.cjs.map +1 -1
- package/dist/internal/transform-litsx-renderer-props.cjs +383 -0
- package/dist/internal/transform-litsx-renderer-props.cjs.map +1 -0
- package/dist/pipeline.cjs +2 -0
- package/dist/pipeline.cjs.map +1 -1
- package/package.json +10 -5
- package/src/internal/transform-litsx-components.js +186 -38
- package/src/internal/transform-litsx-param-rewrites.js +72 -1
- package/src/internal/transform-litsx-program.js +32 -0
- package/src/internal/transform-litsx-renderer-props.js +360 -0
- package/src/internal/transform-litsx-wrapper-utils.js +30 -1
- package/src/pipeline.js +2 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import jsxSyntaxPlugin from "@babel/plugin-syntax-jsx";
|
|
2
|
+
import { decodeVirtualAttributeName } from "@litsx/jsx-authoring";
|
|
3
|
+
|
|
4
|
+
let t;
|
|
5
|
+
|
|
6
|
+
function createHostReferenceExpression() {
|
|
7
|
+
return t.conditionalExpression(
|
|
8
|
+
t.binaryExpression(
|
|
9
|
+
"===",
|
|
10
|
+
t.unaryExpression("typeof", t.thisExpression(), true),
|
|
11
|
+
t.stringLiteral("undefined")
|
|
12
|
+
),
|
|
13
|
+
t.nullLiteral(),
|
|
14
|
+
t.thisExpression()
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function stringifyJsxName(nameNode) {
|
|
19
|
+
if (t.isJSXIdentifier(nameNode)) {
|
|
20
|
+
return nameNode.name;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (t.isJSXMemberExpression(nameNode)) {
|
|
24
|
+
return `${stringifyJsxName(nameNode.object)}.${nameNode.property.name}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (t.isJSXNamespacedName(nameNode)) {
|
|
28
|
+
return `${nameNode.namespace.name}:${nameNode.name.name}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return "unknown";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getTag(node) {
|
|
35
|
+
const name = stringifyJsxName(node.name);
|
|
36
|
+
const isCapitalized =
|
|
37
|
+
name.charAt(0) === name.charAt(0).toUpperCase() &&
|
|
38
|
+
name.charAt(0) !== name.charAt(0).toLowerCase();
|
|
39
|
+
const isComponent =
|
|
40
|
+
node.name.type !== "JSXIdentifier" || isCapitalized || name.includes("-");
|
|
41
|
+
return { name, isComponent };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function unwrapExpression(node) {
|
|
45
|
+
let current = node;
|
|
46
|
+
|
|
47
|
+
while (current) {
|
|
48
|
+
if (t.isParenthesizedExpression?.(current)) {
|
|
49
|
+
current = current.expression;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (
|
|
54
|
+
t.isTSAsExpression?.(current) ||
|
|
55
|
+
t.isTSSatisfiesExpression?.(current) ||
|
|
56
|
+
t.isTypeCastExpression?.(current) ||
|
|
57
|
+
t.isTSNonNullExpression?.(current)
|
|
58
|
+
) {
|
|
59
|
+
current = current.expression;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return current;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getFunctionNodeFromBinding(binding) {
|
|
70
|
+
if (!binding?.path) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (binding.path.isFunctionDeclaration()) {
|
|
75
|
+
return binding.path.node;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (binding.path.isVariableDeclarator()) {
|
|
79
|
+
const init = unwrapExpression(binding.path.node.init);
|
|
80
|
+
if (t.isArrowFunctionExpression(init) || t.isFunctionExpression(init)) {
|
|
81
|
+
return init;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function mergeBooleanResults(results) {
|
|
89
|
+
return results.some(Boolean);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function jsxTreeNeedsRendererContext(node, scope, seenBindings = new Set()) {
|
|
93
|
+
if (!node) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (t.isJSXFragment(node)) {
|
|
98
|
+
return mergeBooleanResults(
|
|
99
|
+
node.children.map((child) => jsxChildNeedsRendererContext(child, scope, seenBindings))
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!t.isJSXElement(node)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const { isComponent } = getTag(node.openingElement);
|
|
108
|
+
if (isComponent) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const childNeedsContext = mergeBooleanResults(
|
|
113
|
+
node.children.map((child) => jsxChildNeedsRendererContext(child, scope, seenBindings))
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (childNeedsContext) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return mergeBooleanResults(
|
|
121
|
+
node.openingElement.attributes.map((attr) => {
|
|
122
|
+
if (!t.isJSXAttribute(attr) || !t.isJSXExpressionContainer(attr.value)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return expressionNeedsRendererContext(attr.value.expression, scope, seenBindings);
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function jsxChildNeedsRendererContext(child, scope, seenBindings) {
|
|
131
|
+
if (t.isJSXElement(child) || t.isJSXFragment(child)) {
|
|
132
|
+
return jsxTreeNeedsRendererContext(child, scope, seenBindings);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (t.isJSXExpressionContainer(child)) {
|
|
136
|
+
return expressionNeedsRendererContext(child.expression, scope, seenBindings);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function functionBodyNeedsRendererContext(body, scope, seenBindings = new Set()) {
|
|
143
|
+
if (!body) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (t.isBlockStatement(body)) {
|
|
148
|
+
return mergeBooleanResults(
|
|
149
|
+
body.body.map((statement) => statementNeedsRendererContext(statement, scope, seenBindings))
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return expressionNeedsRendererContext(body, scope, seenBindings);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function statementNeedsRendererContext(statement, scope, seenBindings) {
|
|
157
|
+
if (t.isReturnStatement(statement)) {
|
|
158
|
+
return expressionNeedsRendererContext(statement.argument, scope, seenBindings);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (t.isIfStatement(statement)) {
|
|
162
|
+
return mergeBooleanResults([
|
|
163
|
+
statementNeedsRendererContext(statement.consequent, scope, seenBindings),
|
|
164
|
+
statement.alternate
|
|
165
|
+
? statementNeedsRendererContext(statement.alternate, scope, seenBindings)
|
|
166
|
+
: false,
|
|
167
|
+
]);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (t.isBlockStatement(statement)) {
|
|
171
|
+
return functionBodyNeedsRendererContext(statement, scope, seenBindings);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function callExpressionNeedsRendererContext(node, scope, seenBindings) {
|
|
178
|
+
const callee = unwrapExpression(node.callee);
|
|
179
|
+
if (!t.isIdentifier(callee)) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const binding = scope.getBinding(callee.name);
|
|
184
|
+
const functionNode = getFunctionNodeFromBinding(binding);
|
|
185
|
+
if (!functionNode) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (seenBindings.has(binding)) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const nextSeenBindings = new Set(seenBindings);
|
|
194
|
+
nextSeenBindings.add(binding);
|
|
195
|
+
return functionBodyNeedsRendererContext(functionNode.body, binding.path.scope, nextSeenBindings);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function expressionNeedsRendererContext(node, scope, seenBindings = new Set()) {
|
|
199
|
+
const expression = unwrapExpression(node);
|
|
200
|
+
if (!expression) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (t.isJSXElement(expression) || t.isJSXFragment(expression)) {
|
|
205
|
+
return jsxTreeNeedsRendererContext(expression, scope, seenBindings);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (t.isConditionalExpression(expression)) {
|
|
209
|
+
return mergeBooleanResults([
|
|
210
|
+
expressionNeedsRendererContext(expression.consequent, scope, seenBindings),
|
|
211
|
+
expressionNeedsRendererContext(expression.alternate, scope, seenBindings),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (t.isLogicalExpression(expression)) {
|
|
216
|
+
return mergeBooleanResults([
|
|
217
|
+
expressionNeedsRendererContext(expression.left, scope, seenBindings),
|
|
218
|
+
expressionNeedsRendererContext(expression.right, scope, seenBindings),
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (t.isSequenceExpression(expression)) {
|
|
223
|
+
return mergeBooleanResults(
|
|
224
|
+
expression.expressions.map((part) => expressionNeedsRendererContext(part, scope, seenBindings))
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (t.isArrayExpression(expression)) {
|
|
229
|
+
return mergeBooleanResults(
|
|
230
|
+
expression.elements.filter(Boolean).map((part) => expressionNeedsRendererContext(part, scope, seenBindings))
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (t.isCallExpression(expression)) {
|
|
235
|
+
return callExpressionNeedsRendererContext(expression, scope, seenBindings);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function isBindableFunctionReference(expressionPath) {
|
|
242
|
+
const expression = unwrapExpression(expressionPath.node);
|
|
243
|
+
if (
|
|
244
|
+
t.isArrowFunctionExpression(expression) ||
|
|
245
|
+
t.isFunctionExpression(expression)
|
|
246
|
+
) {
|
|
247
|
+
return functionBodyNeedsRendererContext(expression.body, expressionPath.scope);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (t.isIdentifier(expression)) {
|
|
251
|
+
const binding = expressionPath.scope.getBinding(expression.name);
|
|
252
|
+
const functionNode = getFunctionNodeFromBinding(binding);
|
|
253
|
+
if (!functionNode) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
return functionBodyNeedsRendererContext(functionNode.body, binding.path.scope, new Set([binding]));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function shouldBindRendererContext(attributePath, rawName, expressionPath) {
|
|
263
|
+
if (typeof rawName !== "string" || rawName[0] !== ".") {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const openingElement = attributePath.parentPath;
|
|
268
|
+
if (!openingElement?.isJSXOpeningElement()) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const { isComponent } = getTag(openingElement.node);
|
|
273
|
+
if (!isComponent) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return isBindableFunctionReference(expressionPath);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function ensureRendererBindingImport(programPath) {
|
|
281
|
+
const bodyPaths = programPath.get("body");
|
|
282
|
+
const runtimeImports = bodyPaths.filter(
|
|
283
|
+
(path) =>
|
|
284
|
+
path.isImportDeclaration() &&
|
|
285
|
+
path.node.source.value === "@litsx/litsx/internal/runtime-render-context"
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
const importSpecifier = t.importSpecifier(
|
|
289
|
+
t.identifier("bindRendererContext"),
|
|
290
|
+
t.identifier("bindRendererContext")
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
for (const importPath of runtimeImports) {
|
|
294
|
+
const { specifiers } = importPath.node;
|
|
295
|
+
const hasImport = specifiers.some(
|
|
296
|
+
(specifier) =>
|
|
297
|
+
t.isImportSpecifier(specifier) &&
|
|
298
|
+
t.isIdentifier(specifier.imported, { name: "bindRendererContext" })
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
if (hasImport) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
specifiers.push(importSpecifier);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
programPath.unshiftContainer("body", t.importDeclaration(
|
|
310
|
+
[importSpecifier],
|
|
311
|
+
t.stringLiteral("@litsx/litsx/internal/runtime-render-context")
|
|
312
|
+
));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export default function transformLitsxRendererProps(api) {
|
|
316
|
+
api.assertVersion?.(7);
|
|
317
|
+
t = api.types;
|
|
318
|
+
|
|
319
|
+
return {
|
|
320
|
+
name: "transform-litsx-renderer-props",
|
|
321
|
+
inherits: jsxSyntaxPlugin.default || jsxSyntaxPlugin,
|
|
322
|
+
visitor: {
|
|
323
|
+
Program: {
|
|
324
|
+
enter(_, state) {
|
|
325
|
+
state.__litsxNeedsRendererBindingImport = false;
|
|
326
|
+
},
|
|
327
|
+
exit(programPath, state) {
|
|
328
|
+
if (state.__litsxNeedsRendererBindingImport) {
|
|
329
|
+
ensureRendererBindingImport(programPath);
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
JSXAttribute(path, state) {
|
|
334
|
+
const { node } = path;
|
|
335
|
+
if (node.value?.type !== "JSXExpressionContainer") {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const rawName = decodeVirtualAttributeName(node.name.name) ?? node.name.name;
|
|
340
|
+
const expressionPath = path.get("value.expression");
|
|
341
|
+
if (!expressionPath?.node) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (!shouldBindRendererContext(path, rawName, expressionPath)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
state.__litsxNeedsRendererBindingImport = true;
|
|
350
|
+
node.value.expression = t.callExpression(
|
|
351
|
+
t.identifier("bindRendererContext"),
|
|
352
|
+
[
|
|
353
|
+
createHostReferenceExpression(),
|
|
354
|
+
expressionPath.node,
|
|
355
|
+
]
|
|
356
|
+
);
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
let t;
|
|
2
2
|
|
|
3
|
+
function isCapitalizedComponentName(name) {
|
|
4
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const first = name[0];
|
|
9
|
+
return first === first.toUpperCase() && first !== first.toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
export function setWrapperUtilsBabelTypes(nextTypes) {
|
|
4
13
|
t = nextTypes;
|
|
5
14
|
}
|
|
@@ -67,6 +76,7 @@ export function maybeTransformWrappedVariableDeclarator({
|
|
|
67
76
|
{
|
|
68
77
|
...resolvedPluginOptions,
|
|
69
78
|
...wrapperMeta.options,
|
|
79
|
+
state,
|
|
70
80
|
typeResolver: state?.__litsxTypeResolver,
|
|
71
81
|
warn: (warning) => {
|
|
72
82
|
state?.__litsxWarnings?.push(warning);
|
|
@@ -129,12 +139,17 @@ export function handlePotentialComponentExport({
|
|
|
129
139
|
exportName = declaration.declarations[0].id.name;
|
|
130
140
|
}
|
|
131
141
|
|
|
142
|
+
if (exportName && !isCapitalizedComponentName(exportName)) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
132
146
|
const classNode = transformFunction(
|
|
133
147
|
declarationPath,
|
|
134
148
|
exportPath.findParent((p) => p.isProgram()),
|
|
135
149
|
exportName,
|
|
136
150
|
{
|
|
137
151
|
...state?.__litsxResolvedPluginOptions,
|
|
152
|
+
state,
|
|
138
153
|
typeResolver,
|
|
139
154
|
warn: (warning) => {
|
|
140
155
|
state?.__litsxWarnings?.push(warning);
|
|
@@ -170,6 +185,10 @@ export function handlePotentialComponentExport({
|
|
|
170
185
|
: undefined;
|
|
171
186
|
const programPath = exportPath.findParent((p) => p.isProgram());
|
|
172
187
|
|
|
188
|
+
if (exportName && !isCapitalizedComponentName(exportName)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
173
192
|
if (initPath.isCallExpression()) {
|
|
174
193
|
const wrapperMeta = getWrapperMetadata(initPath);
|
|
175
194
|
if (!wrapperMeta) return false;
|
|
@@ -184,6 +203,7 @@ export function handlePotentialComponentExport({
|
|
|
184
203
|
{
|
|
185
204
|
...state?.__litsxResolvedPluginOptions,
|
|
186
205
|
...wrapperMeta.options,
|
|
206
|
+
state,
|
|
187
207
|
typeResolver,
|
|
188
208
|
warn: (warning) => {
|
|
189
209
|
state?.__litsxWarnings?.push(warning);
|
|
@@ -196,7 +216,11 @@ export function handlePotentialComponentExport({
|
|
|
196
216
|
exportPath.scope.removeBinding(exportName);
|
|
197
217
|
}
|
|
198
218
|
|
|
199
|
-
exportPath.replaceWith(
|
|
219
|
+
exportPath.replaceWith(
|
|
220
|
+
isDefault
|
|
221
|
+
? t.exportDefaultDeclaration(classNode)
|
|
222
|
+
: t.exportNamedDeclaration(classNode, [])
|
|
223
|
+
);
|
|
200
224
|
exportPath.requeue();
|
|
201
225
|
pruneWrapperImports(wrapperMeta);
|
|
202
226
|
updateTransformState?.(state, classNode);
|
|
@@ -217,6 +241,10 @@ export function handlePotentialComponentExport({
|
|
|
217
241
|
? wrapperMeta.functionPath.node.id.name
|
|
218
242
|
: undefined;
|
|
219
243
|
|
|
244
|
+
if (!inferredName || !isCapitalizedComponentName(inferredName)) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
220
248
|
const classNode = transformFunction(
|
|
221
249
|
wrapperMeta.functionPath,
|
|
222
250
|
programPath,
|
|
@@ -224,6 +252,7 @@ export function handlePotentialComponentExport({
|
|
|
224
252
|
{
|
|
225
253
|
...state?.__litsxResolvedPluginOptions,
|
|
226
254
|
...wrapperMeta.options,
|
|
255
|
+
state,
|
|
227
256
|
typeResolver,
|
|
228
257
|
warn: (warning) => {
|
|
229
258
|
state?.__litsxWarnings?.push(warning);
|
package/src/pipeline.js
CHANGED
|
@@ -3,6 +3,7 @@ import transformLitsxScopedElements from "@litsx/babel-plugin-transform-litsx-sc
|
|
|
3
3
|
import transformLitsxDomRefs from "./internal/transform-litsx-dom-refs.js";
|
|
4
4
|
import transformLitsxHooks from "./internal/transform-litsx-hooks.js";
|
|
5
5
|
import transformLitsxComponents from "./internal/transform-litsx-components.js";
|
|
6
|
+
import transformLitsxRendererProps from "./internal/transform-litsx-renderer-props.js";
|
|
6
7
|
|
|
7
8
|
const NATIVE_TRANSFORM_OPTION_KEYS = [
|
|
8
9
|
"defaultDomMode",
|
|
@@ -55,6 +56,7 @@ function shouldIncludeFeaturePlugin(sourceFeatures, key) {
|
|
|
55
56
|
|
|
56
57
|
export function createLitsxPresetPlugins(options = {}, sourceFeatures = null) {
|
|
57
58
|
const plugins = [
|
|
59
|
+
[transformLitsxRendererProps, options.transformLitsxRendererProps || {}],
|
|
58
60
|
[transformLitsxComponents, normalizeTransformLitsxOptions(options)],
|
|
59
61
|
];
|
|
60
62
|
|