babel-plugin-essor 0.0.15-beta.12 → 0.0.15-beta.14
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 +143 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +143 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -21185,16 +21185,16 @@ function g(e) {
|
|
|
21185
21185
|
function k(e) {
|
|
21186
21186
|
return e === null;
|
|
21187
21187
|
}
|
|
21188
|
-
function
|
|
21188
|
+
function N(e) {
|
|
21189
21189
|
return typeof e == "symbol";
|
|
21190
21190
|
}
|
|
21191
|
-
function
|
|
21191
|
+
function L(e) {
|
|
21192
21192
|
return p.call(e) === "[object Map]";
|
|
21193
21193
|
}
|
|
21194
21194
|
function O(e) {
|
|
21195
21195
|
return e == null;
|
|
21196
21196
|
}
|
|
21197
|
-
var
|
|
21197
|
+
var H = (e) => ["string", "number", "boolean", "symbol", "undefined"].includes(typeof e) || k(e);
|
|
21198
21198
|
var _ = (e) => p.call(e) === "[object Object]";
|
|
21199
21199
|
function B(e) {
|
|
21200
21200
|
return typeof e == "undefined";
|
|
@@ -21220,22 +21220,22 @@ function s(e) {
|
|
|
21220
21220
|
for (let n of e.split(",")) t11[n] = 1;
|
|
21221
21221
|
return (n) => n in t11;
|
|
21222
21222
|
}
|
|
21223
|
-
var
|
|
21224
|
-
s(
|
|
21225
|
-
s(`${
|
|
21223
|
+
var T = "itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly";
|
|
21224
|
+
s(T);
|
|
21225
|
+
s(`${T},async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`);
|
|
21226
21226
|
s("accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap");
|
|
21227
21227
|
s("xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan");
|
|
21228
|
-
var
|
|
21229
|
-
var
|
|
21228
|
+
var we = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot";
|
|
21229
|
+
var Te = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view";
|
|
21230
21230
|
var Se = "annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics";
|
|
21231
21231
|
var ve = "beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,keyup,mousedown,mousemove,mouseout,mouseover,mouseup,pointerdown,pointermove,pointerout,pointerover,pointerup,touchend,touchmove,touchstart";
|
|
21232
21232
|
var Ae = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr";
|
|
21233
21233
|
var Ee = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr";
|
|
21234
|
-
s(
|
|
21235
|
-
var
|
|
21234
|
+
s(we);
|
|
21235
|
+
var Me = s(Te);
|
|
21236
21236
|
s(Se);
|
|
21237
21237
|
s(Ae);
|
|
21238
|
-
var
|
|
21238
|
+
var Le = s(Ee);
|
|
21239
21239
|
var Oe = s(ve);
|
|
21240
21240
|
|
|
21241
21241
|
// src/constants.ts
|
|
@@ -21245,7 +21245,8 @@ var DEFAULT_OPTIONS = {
|
|
|
21245
21245
|
symbol: "$",
|
|
21246
21246
|
props: true,
|
|
21247
21247
|
hmr: true,
|
|
21248
|
-
styled: false
|
|
21248
|
+
styled: false,
|
|
21249
|
+
enableFor: false
|
|
21249
21250
|
};
|
|
21250
21251
|
var IMPORTS_MAPS = [
|
|
21251
21252
|
// Reactive API
|
|
@@ -21262,6 +21263,7 @@ var IMPORTS_MAPS = [
|
|
|
21262
21263
|
"Portal",
|
|
21263
21264
|
// Template related
|
|
21264
21265
|
"mapNodes",
|
|
21266
|
+
"mapArray",
|
|
21265
21267
|
"template",
|
|
21266
21268
|
"delegateEvents",
|
|
21267
21269
|
// styled
|
|
@@ -22068,7 +22070,7 @@ function createTree(path, parentNode) {
|
|
|
22068
22070
|
const tagName = getTagName(path.node);
|
|
22069
22071
|
treeNode.tag = tagName;
|
|
22070
22072
|
treeNode.type = determineNodeType(tagName);
|
|
22071
|
-
treeNode.selfClosing =
|
|
22073
|
+
treeNode.selfClosing = Le(tagName);
|
|
22072
22074
|
if (parentNode) {
|
|
22073
22075
|
const parentIsComponent = parentNode.type === 1 /* COMPONENT */;
|
|
22074
22076
|
if (parentIsComponent) {
|
|
@@ -22278,7 +22280,7 @@ function determineNodeType(tagName) {
|
|
|
22278
22280
|
if (isComponent) {
|
|
22279
22281
|
return 1 /* COMPONENT */;
|
|
22280
22282
|
}
|
|
22281
|
-
if (
|
|
22283
|
+
if (Me(tagName)) {
|
|
22282
22284
|
return 5 /* SVG */;
|
|
22283
22285
|
}
|
|
22284
22286
|
return 0 /* NORMAL */;
|
|
@@ -22548,7 +22550,7 @@ function findIndexPosition(targetIndex, indexMap) {
|
|
|
22548
22550
|
if (u(indexMap)) {
|
|
22549
22551
|
return indexMap.indexOf(targetIndex);
|
|
22550
22552
|
}
|
|
22551
|
-
if (
|
|
22553
|
+
if (L(indexMap)) {
|
|
22552
22554
|
const position = indexMap.get(targetIndex);
|
|
22553
22555
|
return g(position) ? position : -1;
|
|
22554
22556
|
}
|
|
@@ -22815,34 +22817,16 @@ function generateIndexMap({
|
|
|
22815
22817
|
}) {
|
|
22816
22818
|
const indexSet = /* @__PURE__ */ new Set();
|
|
22817
22819
|
for (const item of children) {
|
|
22818
|
-
if (!O(item.parentIndex))
|
|
22819
|
-
|
|
22820
|
-
}
|
|
22821
|
-
if (!O(item.before)) {
|
|
22822
|
-
indexSet.add(item.before);
|
|
22823
|
-
}
|
|
22820
|
+
if (!O(item.parentIndex)) indexSet.add(item.parentIndex);
|
|
22821
|
+
if (!O(item.before)) indexSet.add(item.before);
|
|
22824
22822
|
}
|
|
22825
22823
|
for (const item of props) {
|
|
22826
|
-
if (!O(item.parentIndex))
|
|
22827
|
-
indexSet.add(item.parentIndex);
|
|
22828
|
-
}
|
|
22824
|
+
if (!O(item.parentIndex)) indexSet.add(item.parentIndex);
|
|
22829
22825
|
}
|
|
22830
|
-
|
|
22831
|
-
|
|
22832
|
-
if (!O(item.nodeIndex)) {
|
|
22833
|
-
indexSet.add(item.nodeIndex);
|
|
22834
|
-
}
|
|
22835
|
-
}
|
|
22826
|
+
for (const item of operations) {
|
|
22827
|
+
if (!O(item.nodeIndex)) indexSet.add(item.nodeIndex);
|
|
22836
22828
|
}
|
|
22837
|
-
|
|
22838
|
-
{
|
|
22839
|
-
for (const index of indexMap) {
|
|
22840
|
-
if (!Number.isInteger(index) || index < 1) {
|
|
22841
|
-
re(`Invalid index in index map: ${index}. All indices must be positive integers.`);
|
|
22842
|
-
}
|
|
22843
|
-
}
|
|
22844
|
-
}
|
|
22845
|
-
return indexMap;
|
|
22829
|
+
return Array.from(indexSet).sort((a, b) => a - b);
|
|
22846
22830
|
}
|
|
22847
22831
|
function createRefStatement(nodesId, nodeIndex, value) {
|
|
22848
22832
|
const elementRef = core.types.memberExpression(nodesId, core.types.numericLiteral(nodeIndex), true);
|
|
@@ -23002,7 +22986,123 @@ function createInsertArguments(dynamicContent, nodesIdentifier, indexMap) {
|
|
|
23002
22986
|
function generateDynamicChildrenCode(dynamicChildren, statements, state, nodesId, indexMap) {
|
|
23003
22987
|
addImport(importMap.insert);
|
|
23004
22988
|
for (const dynamicContent of dynamicChildren) {
|
|
23005
|
-
|
|
22989
|
+
let node = dynamicContent.node;
|
|
22990
|
+
let mapCall = null;
|
|
22991
|
+
if (core.types.isCallExpression(node) && core.types.isMemberExpression(node.callee) && core.types.isIdentifier(node.callee.property) && node.callee.property.name === "map" && node.arguments.length > 0) {
|
|
22992
|
+
mapCall = node;
|
|
22993
|
+
} else if (core.types.isArrowFunctionExpression(node) && core.types.isCallExpression(node.body) && core.types.isMemberExpression(node.body.callee) && core.types.isIdentifier(node.body.callee.property) && node.body.callee.property.name === "map" && node.body.arguments.length > 0) {
|
|
22994
|
+
mapCall = node.body;
|
|
22995
|
+
}
|
|
22996
|
+
if (mapCall && state.opts.enableFor !== false) {
|
|
22997
|
+
const listExpr = mapCall.callee.object;
|
|
22998
|
+
const mapFn = mapCall.arguments[0];
|
|
22999
|
+
if (core.types.isExpression(listExpr) && (core.types.isArrowFunctionExpression(mapFn) || core.types.isFunctionExpression(mapFn))) {
|
|
23000
|
+
addImport(importMap.createComponent);
|
|
23001
|
+
addImport(importMap.For);
|
|
23002
|
+
let keyFnExpr = null;
|
|
23003
|
+
let transformedMapFn = mapFn;
|
|
23004
|
+
const mapFnBody = core.types.isArrowFunctionExpression(mapFn) ? mapFn.body : null;
|
|
23005
|
+
const mapFnParams = mapFn.params;
|
|
23006
|
+
let itemParamName = null;
|
|
23007
|
+
if (mapFnParams.length > 0 && core.types.isIdentifier(mapFnParams[0])) {
|
|
23008
|
+
itemParamName = mapFnParams[0].name;
|
|
23009
|
+
}
|
|
23010
|
+
if (itemParamName && mapFnBody) {
|
|
23011
|
+
if (core.types.isCallExpression(mapFnBody)) {
|
|
23012
|
+
const callee = mapFnBody.callee;
|
|
23013
|
+
const args = mapFnBody.arguments;
|
|
23014
|
+
const isCreateComponentCall = core.types.isIdentifier(callee) && callee.name.includes("createComponent") || core.types.isMemberExpression(callee) && core.types.isIdentifier(callee.property) && callee.property.name === "createComponent";
|
|
23015
|
+
if (isCreateComponentCall && args.length >= 2) {
|
|
23016
|
+
const componentRef = args[0];
|
|
23017
|
+
const propsArg = args[1];
|
|
23018
|
+
if (core.types.isExpression(componentRef) && core.types.isObjectExpression(propsArg)) {
|
|
23019
|
+
const newProps = [];
|
|
23020
|
+
for (const prop of propsArg.properties) {
|
|
23021
|
+
if (core.types.isObjectProperty(prop) && core.types.isIdentifier(prop.key) && prop.key.name === "key" && core.types.isExpression(prop.value)) {
|
|
23022
|
+
keyFnExpr = core.types.arrowFunctionExpression(
|
|
23023
|
+
[core.types.identifier(itemParamName)],
|
|
23024
|
+
prop.value
|
|
23025
|
+
);
|
|
23026
|
+
} else if (core.types.isObjectProperty(prop) || core.types.isSpreadElement(prop)) {
|
|
23027
|
+
newProps.push(prop);
|
|
23028
|
+
}
|
|
23029
|
+
}
|
|
23030
|
+
const newPropsObj = core.types.objectExpression(newProps);
|
|
23031
|
+
const directCall = core.types.callExpression(componentRef, [newPropsObj]);
|
|
23032
|
+
transformedMapFn = core.types.arrowFunctionExpression(mapFnParams, directCall);
|
|
23033
|
+
}
|
|
23034
|
+
}
|
|
23035
|
+
} else if (core.types.isJSXElement(mapFnBody)) {
|
|
23036
|
+
const opening = mapFnBody.openingElement;
|
|
23037
|
+
const tagName = opening.name;
|
|
23038
|
+
let componentRef = null;
|
|
23039
|
+
if (core.types.isJSXIdentifier(tagName) && /^[A-Z]/.test(tagName.name)) {
|
|
23040
|
+
componentRef = core.types.identifier(tagName.name);
|
|
23041
|
+
} else if (core.types.isJSXMemberExpression(tagName)) {
|
|
23042
|
+
const convertJSXName = (name) => {
|
|
23043
|
+
if (core.types.isJSXIdentifier(name)) return core.types.identifier(name.name);
|
|
23044
|
+
if (core.types.isJSXMemberExpression(name))
|
|
23045
|
+
return core.types.memberExpression(
|
|
23046
|
+
convertJSXName(name.object),
|
|
23047
|
+
convertJSXName(name.property)
|
|
23048
|
+
);
|
|
23049
|
+
throw new Error("Unsupported JSX Member Expression");
|
|
23050
|
+
};
|
|
23051
|
+
componentRef = core.types.memberExpression(
|
|
23052
|
+
convertJSXName(tagName.object),
|
|
23053
|
+
convertJSXName(tagName.property)
|
|
23054
|
+
);
|
|
23055
|
+
}
|
|
23056
|
+
if (componentRef) {
|
|
23057
|
+
const newProps = [];
|
|
23058
|
+
for (const attr of opening.attributes) {
|
|
23059
|
+
if (core.types.isJSXAttribute(attr)) {
|
|
23060
|
+
const nameNode = attr.name;
|
|
23061
|
+
const name = core.types.isJSXIdentifier(nameNode) ? nameNode.name : nameNode.name.name;
|
|
23062
|
+
let valueExpr = core.types.booleanLiteral(true);
|
|
23063
|
+
if (attr.value) {
|
|
23064
|
+
if (core.types.isJSXExpressionContainer(attr.value)) {
|
|
23065
|
+
if (core.types.isExpression(attr.value.expression)) {
|
|
23066
|
+
valueExpr = attr.value.expression;
|
|
23067
|
+
} else {
|
|
23068
|
+
continue;
|
|
23069
|
+
}
|
|
23070
|
+
} else if (core.types.isStringLiteral(attr.value)) {
|
|
23071
|
+
valueExpr = attr.value;
|
|
23072
|
+
}
|
|
23073
|
+
}
|
|
23074
|
+
if (name === "key") {
|
|
23075
|
+
keyFnExpr = core.types.arrowFunctionExpression([core.types.identifier(itemParamName)], valueExpr);
|
|
23076
|
+
} else {
|
|
23077
|
+
newProps.push(core.types.objectProperty(core.types.identifier(name), valueExpr));
|
|
23078
|
+
}
|
|
23079
|
+
} else if (core.types.isJSXSpreadAttribute(attr)) {
|
|
23080
|
+
newProps.push(core.types.spreadElement(attr.argument));
|
|
23081
|
+
}
|
|
23082
|
+
}
|
|
23083
|
+
const newPropsObj = core.types.objectExpression(newProps);
|
|
23084
|
+
const directCall = core.types.callExpression(componentRef, [newPropsObj]);
|
|
23085
|
+
transformedMapFn = core.types.arrowFunctionExpression(mapFnParams, directCall);
|
|
23086
|
+
}
|
|
23087
|
+
}
|
|
23088
|
+
}
|
|
23089
|
+
const propsProperties = [
|
|
23090
|
+
core.types.objectProperty(core.types.identifier("each"), core.types.arrowFunctionExpression([], listExpr)),
|
|
23091
|
+
core.types.objectProperty(core.types.identifier("children"), transformedMapFn)
|
|
23092
|
+
];
|
|
23093
|
+
if (keyFnExpr) {
|
|
23094
|
+
propsProperties.push(core.types.objectProperty(core.types.identifier("keyFn"), keyFnExpr));
|
|
23095
|
+
}
|
|
23096
|
+
const propsObject = core.types.objectExpression(propsProperties);
|
|
23097
|
+
const newExpr = core.types.callExpression(state.imports.createComponent, [
|
|
23098
|
+
state.imports.For,
|
|
23099
|
+
propsObject
|
|
23100
|
+
]);
|
|
23101
|
+
dynamicContent.node = newExpr;
|
|
23102
|
+
node = newExpr;
|
|
23103
|
+
}
|
|
23104
|
+
}
|
|
23105
|
+
const processedNode = processIIFEExpression(node);
|
|
23006
23106
|
const insertArgs = createInsertArguments(
|
|
23007
23107
|
__spreadProps(__spreadValues({}, dynamicContent), { node: processedNode }),
|
|
23008
23108
|
nodesId,
|
|
@@ -23389,7 +23489,7 @@ var handleExpression = (node, result) => {
|
|
|
23389
23489
|
}
|
|
23390
23490
|
const firstChild = node.children[0];
|
|
23391
23491
|
result.templates.push("");
|
|
23392
|
-
if (
|
|
23492
|
+
if (H(firstChild)) {
|
|
23393
23493
|
const { state } = getContext();
|
|
23394
23494
|
addImport(importMap.escapeHTML);
|
|
23395
23495
|
result.dynamics.push({
|
|
@@ -23494,10 +23594,10 @@ function processAttributes(props) {
|
|
|
23494
23594
|
if (prop.startsWith(EVENT_ATTR_NAME) || prop.startsWith(UPDATE_PREFIX)) {
|
|
23495
23595
|
continue;
|
|
23496
23596
|
}
|
|
23497
|
-
if (
|
|
23597
|
+
if (H(value)) {
|
|
23498
23598
|
if (value === true) {
|
|
23499
23599
|
staticAttrs += ` ${prop}`;
|
|
23500
|
-
} else if (
|
|
23600
|
+
} else if (N(value)) {
|
|
23501
23601
|
staticAttrs += ` ${prop}="${value.toString()}"`;
|
|
23502
23602
|
} else if (value !== false) {
|
|
23503
23603
|
staticAttrs += ` ${prop}="${value}"`;
|