@servicetitan/dte-unlayer 0.95.0 → 0.97.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.
@@ -1 +1 @@
1
- {"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,0BAA0B;IACvC,MAAM,CAAC,EAAE,OAAO,kBAAkB,EAAE,YAAY,CAAC;CACpD;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,uCAgNtE,CAAC"}
1
+ {"version":3,"file":"DisplayConditionModal.d.ts","sourceRoot":"","sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,0BAA0B;IACvC,MAAM,CAAC,EAAE,OAAO,kBAAkB,EAAE,YAAY,CAAC;CACpD;AAED,eAAO,MAAM,qBAAqB,GAAI,OAAO,0BAA0B,uCAgNtE,CAAC"}
@@ -41,15 +41,9 @@ export const DisplayConditionModal = (props)=>{
41
41
  });
42
42
  }, []);
43
43
  const handleClose = useCallback(()=>{
44
- if (request) {
45
- var _request_data;
46
- request.done((_request_data = request.data) !== null && _request_data !== void 0 ? _request_data : null);
47
- setRequest(null);
48
- }
44
+ setRequest(null);
49
45
  setIsOpen(false);
50
- }, [
51
- request
52
- ]);
46
+ }, []);
53
47
  const handleSave = useCallback(()=>{
54
48
  if (!request) {
55
49
  return;
@@ -169,6 +163,7 @@ export const DisplayConditionModal = (props)=>{
169
163
  style: {
170
164
  maxHeight: MODAL_CONTENT_MAX_HEIGHT,
171
165
  overflowY: 'auto',
166
+ paddingRight: 8,
172
167
  width: '100%'
173
168
  },
174
169
  children: [
@@ -190,7 +185,7 @@ export const DisplayConditionModal = (props)=>{
190
185
  }),
191
186
  /*#__PURE__*/ _jsxs(Flex, {
192
187
  direction: "row",
193
- alignItems: "center",
188
+ alignItems: "flex-end",
194
189
  gap: "3",
195
190
  style: {
196
191
  flexWrap: 'wrap'
@@ -200,13 +195,16 @@ export const DisplayConditionModal = (props)=>{
200
195
  size: "small",
201
196
  subdued: true,
202
197
  variant: "body",
198
+ style: {
199
+ paddingBottom: 10
200
+ },
203
201
  children: "Select to show or hide selected component."
204
202
  }),
205
203
  /*#__PURE__*/ _jsx("div", {
206
204
  style: {
207
205
  width: 160
208
206
  },
209
- children: /*#__PURE__*/ _jsxs(Combobox, {
207
+ children: /*#__PURE__*/ _jsxs(Combobox.Select, {
210
208
  ...{
211
209
  disableClearSelection: true
212
210
  },
@@ -225,7 +223,7 @@ export const DisplayConditionModal = (props)=>{
225
223
  onChange: handleBehaviorChange,
226
224
  children: [
227
225
  /*#__PURE__*/ _jsx(Combobox.SelectTrigger, {
228
- label: "Behavior",
226
+ label: "",
229
227
  placeholder: "Select..."
230
228
  }),
231
229
  /*#__PURE__*/ _jsx(Combobox.Content, {
@@ -244,36 +242,44 @@ export const DisplayConditionModal = (props)=>{
244
242
  })
245
243
  ]
246
244
  }),
247
- /*#__PURE__*/ _jsx(ConditionGroupsSection, {
248
- dataPointOptions: dataPointOptions,
249
- groups: state.groups,
250
- onAddGroup: addGroup,
251
- onRemoveGroup: removeGroup,
252
- onUpdateGroup: updateGroup
253
- }),
254
- !canSave && /*#__PURE__*/ _jsx(Text, {
255
- size: "small",
256
- subdued: true,
257
- variant: "body",
258
- children: "Complete each condition before saving. Data point and value are required, and numeric fields must contain a valid number."
245
+ /*#__PURE__*/ _jsx("div", {
246
+ style: {
247
+ padding: 8
248
+ },
249
+ children: /*#__PURE__*/ _jsx(ConditionGroupsSection, {
250
+ dataPointOptions: dataPointOptions,
251
+ groups: state.groups,
252
+ onAddGroup: addGroup,
253
+ onRemoveGroup: removeGroup,
254
+ onUpdateGroup: updateGroup
255
+ })
259
256
  })
260
257
  ]
261
258
  })
262
259
  }),
263
- /*#__PURE__*/ _jsxs(Dialog.Footer, {
260
+ /*#__PURE__*/ _jsx(Dialog.Footer, {
264
261
  sticky: true,
265
- children: [
266
- /*#__PURE__*/ _jsx(Dialog.CancelButton, {
267
- onClick: handleClose,
268
- children: "Cancel"
269
- }),
270
- /*#__PURE__*/ _jsx(Button, {
271
- appearance: "primary",
272
- disabled: !canSave,
273
- onClick: handleSave,
274
- children: "Save Changes"
275
- })
276
- ]
262
+ children: /*#__PURE__*/ _jsxs(Flex, {
263
+ justifyContent: "flex-end",
264
+ alignItems: "center",
265
+ gap: "3",
266
+ style: {
267
+ width: '100%'
268
+ },
269
+ children: [
270
+ /*#__PURE__*/ _jsx(Button, {
271
+ appearance: "secondary",
272
+ onClick: handleClose,
273
+ children: "Cancel"
274
+ }),
275
+ /*#__PURE__*/ _jsx(Button, {
276
+ appearance: "primary",
277
+ disabled: !canSave,
278
+ onClick: handleSave,
279
+ children: "Save Changes"
280
+ })
281
+ ]
282
+ })
277
283
  })
278
284
  ]
279
285
  }), portalTarget);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ConditionGroupsSection } from './ConditionGroupsSection';\nimport { defaultGroup, defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport { ConditionGroup as ConditionGroupType, DisplayBehavior } from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\n\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\nexport interface DisplayConditionModalProps {\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(props.schema), [props.schema]);\n\n const portalTarget = useMemo(() => {\n if (typeof document === 'undefined') {\n return null;\n }\n return document.body;\n }, []);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n setState(parsed ?? defaultState());\n setIsOpen(true);\n });\n }, []);\n\n const handleClose = useCallback(() => {\n if (request) {\n request.done(request.data ?? null);\n setRequest(null);\n }\n setIsOpen(false);\n }, [request]);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const condition = buildUnlayerDisplayCondition(state);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const removeGroup = useCallback((index: number) => {\n setState(prev => ({\n ...prev,\n groups: (() => {\n const nextGroups = prev.groups.filter((_, i) => i !== index);\n if (nextGroups.length === 0) {\n return [defaultGroup()];\n }\n if (index === 0) {\n const { logicalOperator: unusedOp, ...firstGroup } = nextGroups[0];\n return [firstGroup, ...nextGroups.slice(1)];\n }\n return nextGroups;\n })(),\n }));\n }, []);\n\n const addGroup = useCallback(() => {\n setState(prev => ({\n ...prev,\n groups: [...prev.groups, { ...defaultGroup(), logicalOperator: 'and' }],\n }));\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const canSave = useMemo(() => {\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [dataPointOptions, state.groups]);\n\n if (!portalTarget || !isOpen) {\n return null;\n }\n\n return createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Rules and Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"6\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n width: '100%',\n }}\n >\n <Flex\n direction=\"column\"\n gap=\"3\"\n style={{\n borderBottom: '1px solid #e0e0e0',\n paddingBottom: 16,\n }}\n >\n <Text size=\"medium\" variant=\"body\" style={{ fontWeight: 'bold' }}>\n When conditions are met:\n </Text>\n <Flex\n direction=\"row\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\">\n Select to show or hide selected component.\n </Text>\n <div style={{ width: 160 }}>\n <Combobox\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: BehaviorOption | null) => item?.value ?? ''}\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger\n label=\"Behavior\"\n placeholder=\"Select...\"\n />\n <Combobox.Content>\n {({ items }: { items: BehaviorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox>\n </div>\n </Flex>\n </Flex>\n <ConditionGroupsSection\n dataPointOptions={dataPointOptions}\n groups={state.groups}\n onAddGroup={addGroup}\n onRemoveGroup={removeGroup}\n onUpdateGroup={updateGroup}\n />\n {!canSave && (\n <Text size=\"small\" subdued variant=\"body\">\n Complete each condition before saving. Data point and value are\n required, and numeric fields must contain a valid number.\n </Text>\n )}\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Dialog.CancelButton onClick={handleClose}>Cancel</Dialog.CancelButton>\n <Button appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","useCallback","useEffect","useMemo","useState","createPortal","ConditionGroupsSection","defaultGroup","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","DisplayConditionModal","props","request","setRequest","isOpen","setIsOpen","state","setState","dataPointOptions","schema","portalTarget","document","body","nextRequest","existing","data","parsed","handleClose","done","handleSave","condition","updateGroup","index","group","prev","next","groups","removeGroup","nextGroups","filter","_","i","length","logicalOperator","unusedOp","firstGroup","slice","addGroup","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","canSave","conditions","dataPointKey","operator","trimmedValue","trim","fieldType","fullKey","test","open","onClose","size","Header","Content","direction","gap","style","maxHeight","overflowY","width","borderBottom","paddingBottom","variant","fontWeight","alignItems","flexWrap","subdued","div","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","map","Item","onAddGroup","onRemoveGroup","onUpdateGroup","Footer","sticky","CancelButton","onClick","appearance","disabled"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/display-conditions/DisplayConditionModal.tsx"],"sourcesContent":["import { Button, Combobox, Dialog, Flex, Text } from '@servicetitan/anvil2';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ConditionGroupsSection } from './ConditionGroupsSection';\nimport { defaultGroup, defaultState, MODAL_CONTENT_MAX_HEIGHT } from './constants';\nimport { DisplayConditionRequest, onDisplayCondition } from './displayConditionController';\nimport { buildUnlayerDisplayCondition, parseUnlayerDisplayCondition } from './nunjucks';\nimport { getSchemaDataPointOptions } from './schemaDataPoints';\nimport { ConditionGroup as ConditionGroupType, DisplayBehavior } from './types';\n\nconst BEHAVIOR_OPTIONS = [\n { label: 'Show', value: 'show' },\n { label: 'Hide', value: 'hide' },\n] as const;\nconst NUMERIC_VALUE_RE = /^-?(?:\\d+\\.?\\d*|\\.\\d+)$/;\ntype BehaviorOption = (typeof BEHAVIOR_OPTIONS)[number];\n\nexport interface DisplayConditionModalProps {\n schema?: import('../shared/schema').SchemaObject;\n}\n\nexport const DisplayConditionModal = (props: DisplayConditionModalProps) => {\n const [request, setRequest] = useState<DisplayConditionRequest | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const [state, setState] = useState(defaultState);\n\n const dataPointOptions = useMemo(() => getSchemaDataPointOptions(props.schema), [props.schema]);\n\n const portalTarget = useMemo(() => {\n if (typeof document === 'undefined') {\n return null;\n }\n return document.body;\n }, []);\n\n useEffect(() => {\n return onDisplayCondition(nextRequest => {\n setRequest(nextRequest);\n const existing = nextRequest.data;\n const parsed = parseUnlayerDisplayCondition(existing);\n setState(parsed ?? defaultState());\n setIsOpen(true);\n });\n }, []);\n\n const handleClose = useCallback(() => {\n setRequest(null);\n setIsOpen(false);\n }, []);\n\n const handleSave = useCallback(() => {\n if (!request) {\n return;\n }\n const condition = buildUnlayerDisplayCondition(state);\n if (condition) {\n request.done(condition);\n } else {\n request.done(null);\n }\n setRequest(null);\n setIsOpen(false);\n }, [request, state]);\n\n const updateGroup = useCallback((index: number, group: ConditionGroupType) => {\n setState(prev => {\n const next = [...prev.groups];\n next[index] = group;\n return { ...prev, groups: next };\n });\n }, []);\n\n const removeGroup = useCallback((index: number) => {\n setState(prev => ({\n ...prev,\n groups: (() => {\n const nextGroups = prev.groups.filter((_, i) => i !== index);\n if (nextGroups.length === 0) {\n return [defaultGroup()];\n }\n if (index === 0) {\n const { logicalOperator: unusedOp, ...firstGroup } = nextGroups[0];\n return [firstGroup, ...nextGroups.slice(1)];\n }\n return nextGroups;\n })(),\n }));\n }, []);\n\n const addGroup = useCallback(() => {\n setState(prev => ({\n ...prev,\n groups: [...prev.groups, { ...defaultGroup(), logicalOperator: 'and' }],\n }));\n }, []);\n\n const selectedBehavior = useMemo(\n () => BEHAVIOR_OPTIONS.find(opt => opt.value === state.behavior) ?? BEHAVIOR_OPTIONS[0],\n [state.behavior],\n );\n\n const handleBehaviorChange = useCallback((item: BehaviorOption | null) => {\n if (item) {\n setState(prev => ({ ...prev, behavior: item.value as DisplayBehavior }));\n }\n }, []);\n\n const canSave = useMemo(() => {\n for (const group of state.groups) {\n for (const condition of group.conditions) {\n if (!condition.dataPointKey) {\n return false;\n }\n if (condition.operator === 'is_empty' || condition.operator === 'is_not_empty') {\n continue;\n }\n const trimmedValue = condition.value.trim();\n if (!trimmedValue) {\n return false;\n }\n const fieldType =\n dataPointOptions.find(opt => opt.fullKey === condition.dataPointKey)\n ?.fieldType ?? 'string';\n if (fieldType === 'number' && !NUMERIC_VALUE_RE.test(trimmedValue)) {\n return false;\n }\n }\n }\n return state.groups.length > 0;\n }, [dataPointOptions, state.groups]);\n\n if (!portalTarget || !isOpen) {\n return null;\n }\n\n return createPortal(\n <Dialog open={isOpen} onClose={handleClose} size=\"xlarge\">\n <Dialog.Header>Rules and Conditions</Dialog.Header>\n <Dialog.Content>\n <Flex\n direction=\"column\"\n gap=\"6\"\n style={{\n maxHeight: MODAL_CONTENT_MAX_HEIGHT,\n overflowY: 'auto',\n paddingRight: 8,\n width: '100%',\n }}\n >\n <Flex\n direction=\"column\"\n gap=\"3\"\n style={{\n borderBottom: '1px solid #e0e0e0',\n paddingBottom: 16,\n }}\n >\n <Text size=\"medium\" variant=\"body\" style={{ fontWeight: 'bold' }}>\n When conditions are met:\n </Text>\n <Flex\n direction=\"row\"\n alignItems=\"flex-end\"\n gap=\"3\"\n style={{ flexWrap: 'wrap' }}\n >\n <Text size=\"small\" subdued variant=\"body\" style={{ paddingBottom: 10 }}>\n Select to show or hide selected component.\n </Text>\n <div style={{ width: 160 }}>\n <Combobox.Select\n {...({ disableClearSelection: true } as object)}\n itemToKey={(item: BehaviorOption | null) => item?.value ?? ''}\n itemToString={(item: BehaviorOption | null) =>\n item?.label ?? ''\n }\n items={[...BEHAVIOR_OPTIONS]}\n selectedItem={selectedBehavior}\n onChange={handleBehaviorChange}\n >\n <Combobox.SelectTrigger label=\"\" placeholder=\"Select...\" />\n <Combobox.Content>\n {({ items }: { items: BehaviorOption[] }) => (\n <Combobox.List>\n {items.map((item, i) => (\n <Combobox.Item\n index={i}\n item={item}\n key={item.value}\n >\n {item.label}\n </Combobox.Item>\n ))}\n </Combobox.List>\n )}\n </Combobox.Content>\n </Combobox.Select>\n </div>\n </Flex>\n </Flex>\n <div style={{ padding: 8 }}>\n <ConditionGroupsSection\n dataPointOptions={dataPointOptions}\n groups={state.groups}\n onAddGroup={addGroup}\n onRemoveGroup={removeGroup}\n onUpdateGroup={updateGroup}\n />\n </div>\n </Flex>\n </Dialog.Content>\n <Dialog.Footer sticky>\n <Flex\n justifyContent=\"flex-end\"\n alignItems=\"center\"\n gap=\"3\"\n style={{ width: '100%' }}\n >\n <Button appearance=\"secondary\" onClick={handleClose}>\n Cancel\n </Button>\n <Button appearance=\"primary\" disabled={!canSave} onClick={handleSave}>\n Save Changes\n </Button>\n </Flex>\n </Dialog.Footer>\n </Dialog>,\n portalTarget,\n );\n};\n"],"names":["Button","Combobox","Dialog","Flex","Text","useCallback","useEffect","useMemo","useState","createPortal","ConditionGroupsSection","defaultGroup","defaultState","MODAL_CONTENT_MAX_HEIGHT","onDisplayCondition","buildUnlayerDisplayCondition","parseUnlayerDisplayCondition","getSchemaDataPointOptions","BEHAVIOR_OPTIONS","label","value","NUMERIC_VALUE_RE","DisplayConditionModal","props","request","setRequest","isOpen","setIsOpen","state","setState","dataPointOptions","schema","portalTarget","document","body","nextRequest","existing","data","parsed","handleClose","handleSave","condition","done","updateGroup","index","group","prev","next","groups","removeGroup","nextGroups","filter","_","i","length","logicalOperator","unusedOp","firstGroup","slice","addGroup","selectedBehavior","find","opt","behavior","handleBehaviorChange","item","canSave","conditions","dataPointKey","operator","trimmedValue","trim","fieldType","fullKey","test","open","onClose","size","Header","Content","direction","gap","style","maxHeight","overflowY","paddingRight","width","borderBottom","paddingBottom","variant","fontWeight","alignItems","flexWrap","subdued","div","Select","disableClearSelection","itemToKey","itemToString","items","selectedItem","onChange","SelectTrigger","placeholder","List","map","Item","padding","onAddGroup","onRemoveGroup","onUpdateGroup","Footer","sticky","justifyContent","appearance","onClick","disabled"],"mappings":";AAAA,SAASA,MAAM,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,IAAI,EAAEC,IAAI,QAAQ,uBAAuB;AAC5E,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAQ;AAClE,SAASC,YAAY,QAAQ,YAAY;AACzC,SAASC,sBAAsB,QAAQ,2BAA2B;AAClE,SAASC,YAAY,EAAEC,YAAY,EAAEC,wBAAwB,QAAQ,cAAc;AACnF,SAAkCC,kBAAkB,QAAQ,+BAA+B;AAC3F,SAASC,4BAA4B,EAAEC,4BAA4B,QAAQ,aAAa;AACxF,SAASC,yBAAyB,QAAQ,qBAAqB;AAG/D,MAAMC,mBAAmB;IACrB;QAAEC,OAAO;QAAQC,OAAO;IAAO;IAC/B;QAAED,OAAO;QAAQC,OAAO;IAAO;CAClC;AACD,MAAMC,mBAAmB;AAOzB,OAAO,MAAMC,wBAAwB,CAACC;IAClC,MAAM,CAACC,SAASC,WAAW,GAAGjB,SAAyC;IACvE,MAAM,CAACkB,QAAQC,UAAU,GAAGnB,SAAS;IACrC,MAAM,CAACoB,OAAOC,SAAS,GAAGrB,SAASI;IAEnC,MAAMkB,mBAAmBvB,QAAQ,IAAMU,0BAA0BM,MAAMQ,MAAM,GAAG;QAACR,MAAMQ,MAAM;KAAC;IAE9F,MAAMC,eAAezB,QAAQ;QACzB,IAAI,OAAO0B,aAAa,aAAa;YACjC,OAAO;QACX;QACA,OAAOA,SAASC,IAAI;IACxB,GAAG,EAAE;IAEL5B,UAAU;QACN,OAAOQ,mBAAmBqB,CAAAA;YACtBV,WAAWU;YACX,MAAMC,WAAWD,YAAYE,IAAI;YACjC,MAAMC,SAAStB,6BAA6BoB;YAC5CP,SAASS,mBAAAA,oBAAAA,SAAU1B;YACnBe,UAAU;QACd;IACJ,GAAG,EAAE;IAEL,MAAMY,cAAclC,YAAY;QAC5BoB,WAAW;QACXE,UAAU;IACd,GAAG,EAAE;IAEL,MAAMa,aAAanC,YAAY;QAC3B,IAAI,CAACmB,SAAS;YACV;QACJ;QACA,MAAMiB,YAAY1B,6BAA6Ba;QAC/C,IAAIa,WAAW;YACXjB,QAAQkB,IAAI,CAACD;QACjB,OAAO;YACHjB,QAAQkB,IAAI,CAAC;QACjB;QACAjB,WAAW;QACXE,UAAU;IACd,GAAG;QAACH;QAASI;KAAM;IAEnB,MAAMe,cAActC,YAAY,CAACuC,OAAeC;QAC5ChB,SAASiB,CAAAA;YACL,MAAMC,OAAO;mBAAID,KAAKE,MAAM;aAAC;YAC7BD,IAAI,CAACH,MAAM,GAAGC;YACd,OAAO;gBAAE,GAAGC,IAAI;gBAAEE,QAAQD;YAAK;QACnC;IACJ,GAAG,EAAE;IAEL,MAAME,cAAc5C,YAAY,CAACuC;QAC7Bf,SAASiB,CAAAA,OAAS,CAAA;gBACd,GAAGA,IAAI;gBACPE,QAAQ,AAAC,CAAA;oBACL,MAAME,aAAaJ,KAAKE,MAAM,CAACG,MAAM,CAAC,CAACC,GAAGC,IAAMA,MAAMT;oBACtD,IAAIM,WAAWI,MAAM,KAAK,GAAG;wBACzB,OAAO;4BAAC3C;yBAAe;oBAC3B;oBACA,IAAIiC,UAAU,GAAG;wBACb,MAAM,EAAEW,iBAAiBC,QAAQ,EAAE,GAAGC,YAAY,GAAGP,UAAU,CAAC,EAAE;wBAClE,OAAO;4BAACO;+BAAeP,WAAWQ,KAAK,CAAC;yBAAG;oBAC/C;oBACA,OAAOR;gBACX,CAAA;YACJ,CAAA;IACJ,GAAG,EAAE;IAEL,MAAMS,WAAWtD,YAAY;QACzBwB,SAASiB,CAAAA,OAAS,CAAA;gBACd,GAAGA,IAAI;gBACPE,QAAQ;uBAAIF,KAAKE,MAAM;oBAAE;wBAAE,GAAGrC,cAAc;wBAAE4C,iBAAiB;oBAAM;iBAAE;YAC3E,CAAA;IACJ,GAAG,EAAE;IAEL,MAAMK,mBAAmBrD,QACrB;YAAMW;eAAAA,CAAAA,yBAAAA,iBAAiB2C,IAAI,CAACC,CAAAA,MAAOA,IAAI1C,KAAK,KAAKQ,MAAMmC,QAAQ,eAAzD7C,oCAAAA,yBAA8DA,gBAAgB,CAAC,EAAE;OACvF;QAACU,MAAMmC,QAAQ;KAAC;IAGpB,MAAMC,uBAAuB3D,YAAY,CAAC4D;QACtC,IAAIA,MAAM;YACNpC,SAASiB,CAAAA,OAAS,CAAA;oBAAE,GAAGA,IAAI;oBAAEiB,UAAUE,KAAK7C,KAAK;gBAAoB,CAAA;QACzE;IACJ,GAAG,EAAE;IAEL,MAAM8C,UAAU3D,QAAQ;QACpB,KAAK,MAAMsC,SAASjB,MAAMoB,MAAM,CAAE;YAC9B,KAAK,MAAMP,aAAaI,MAAMsB,UAAU,CAAE;oBAYlCrC;gBAXJ,IAAI,CAACW,UAAU2B,YAAY,EAAE;oBACzB,OAAO;gBACX;gBACA,IAAI3B,UAAU4B,QAAQ,KAAK,cAAc5B,UAAU4B,QAAQ,KAAK,gBAAgB;oBAC5E;gBACJ;gBACA,MAAMC,eAAe7B,UAAUrB,KAAK,CAACmD,IAAI;gBACzC,IAAI,CAACD,cAAc;oBACf,OAAO;gBACX;oBAEIxC;gBADJ,MAAM0C,YACF1C,CAAAA,oCAAAA,yBAAAA,iBAAiB+B,IAAI,CAACC,CAAAA,MAAOA,IAAIW,OAAO,KAAKhC,UAAU2B,YAAY,eAAnEtC,6CAAAA,uBACM0C,SAAS,cADf1C,8CAAAA,mCACmB;gBACvB,IAAI0C,cAAc,YAAY,CAACnD,iBAAiBqD,IAAI,CAACJ,eAAe;oBAChE,OAAO;gBACX;YACJ;QACJ;QACA,OAAO1C,MAAMoB,MAAM,CAACM,MAAM,GAAG;IACjC,GAAG;QAACxB;QAAkBF,MAAMoB,MAAM;KAAC;IAEnC,IAAI,CAAChB,gBAAgB,CAACN,QAAQ;QAC1B,OAAO;IACX;IAEA,qBAAOjB,2BACH,MAACP;QAAOyE,MAAMjD;QAAQkD,SAASrC;QAAasC,MAAK;;0BAC7C,KAAC3E,OAAO4E,MAAM;0BAAC;;0BACf,KAAC5E,OAAO6E,OAAO;0BACX,cAAA,MAAC5E;oBACG6E,WAAU;oBACVC,KAAI;oBACJC,OAAO;wBACHC,WAAWtE;wBACXuE,WAAW;wBACXC,cAAc;wBACdC,OAAO;oBACX;;sCAEA,MAACnF;4BACG6E,WAAU;4BACVC,KAAI;4BACJC,OAAO;gCACHK,cAAc;gCACdC,eAAe;4BACnB;;8CAEA,KAACpF;oCAAKyE,MAAK;oCAASY,SAAQ;oCAAOP,OAAO;wCAAEQ,YAAY;oCAAO;8CAAG;;8CAGlE,MAACvF;oCACG6E,WAAU;oCACVW,YAAW;oCACXV,KAAI;oCACJC,OAAO;wCAAEU,UAAU;oCAAO;;sDAE1B,KAACxF;4CAAKyE,MAAK;4CAAQgB,OAAO;4CAACJ,SAAQ;4CAAOP,OAAO;gDAAEM,eAAe;4CAAG;sDAAG;;sDAGxE,KAACM;4CAAIZ,OAAO;gDAAEI,OAAO;4CAAI;sDACrB,cAAA,MAACrF,SAAS8F,MAAM;gDACX,GAAI;oDAAEC,uBAAuB;gDAAK,CAAC;gDACpCC,WAAW,CAAChC;wDAAgCA;2DAAAA,CAAAA,cAAAA,iBAAAA,2BAAAA,KAAM7C,KAAK,cAAX6C,yBAAAA,cAAe;;gDAC3DiC,cAAc,CAACjC;wDACXA;2DAAAA,CAAAA,cAAAA,iBAAAA,2BAAAA,KAAM9C,KAAK,cAAX8C,yBAAAA,cAAe;;gDAEnBkC,OAAO;uDAAIjF;iDAAiB;gDAC5BkF,cAAcxC;gDACdyC,UAAUrC;;kEAEV,KAAC/D,SAASqG,aAAa;wDAACnF,OAAM;wDAAGoF,aAAY;;kEAC7C,KAACtG,SAAS8E,OAAO;kEACZ,CAAC,EAAEoB,KAAK,EAA+B,iBACpC,KAAClG,SAASuG,IAAI;0EACTL,MAAMM,GAAG,CAAC,CAACxC,MAAMZ,kBACd,KAACpD,SAASyG,IAAI;wEACV9D,OAAOS;wEACPY,MAAMA;kFAGLA,KAAK9C,KAAK;uEAFN8C,KAAK7C,KAAK;;;;;;;;;;sCAYnD,KAAC0E;4BAAIZ,OAAO;gCAAEyB,SAAS;4BAAE;sCACrB,cAAA,KAACjG;gCACGoB,kBAAkBA;gCAClBkB,QAAQpB,MAAMoB,MAAM;gCACpB4D,YAAYjD;gCACZkD,eAAe5D;gCACf6D,eAAenE;;;;;;0BAK/B,KAACzC,OAAO6G,MAAM;gBAACC,MAAM;0BACjB,cAAA,MAAC7G;oBACG8G,gBAAe;oBACftB,YAAW;oBACXV,KAAI;oBACJC,OAAO;wBAAEI,OAAO;oBAAO;;sCAEvB,KAACtF;4BAAOkH,YAAW;4BAAYC,SAAS5E;sCAAa;;sCAGrD,KAACvC;4BAAOkH,YAAW;4BAAUE,UAAU,CAAClD;4BAASiD,SAAS3E;sCAAY;;;;;;QAMlFR;AAER,EAAE"}