@bagelink/vue 1.2.107 → 1.2.111

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.
@@ -308,9 +308,7 @@ function getAllFields(schema: any[]): any[] {
308
308
 
309
309
  // Extract options if they exist in attrs
310
310
  if (field.attrs && field.attrs.options && field.attrs.options.length > 0) {
311
- // Add options from attrs to the field's options array
312
311
  field.options = field.attrs.options
313
- console.log(`Added options for field ${field.id}:`, field.options)
314
312
  }
315
313
 
316
314
  allFields.push(field)
@@ -335,11 +333,9 @@ function getAllFields(schema: any[]): any[] {
335
333
  // Add the array field itself (phones, emails)
336
334
  addFieldIfNew(child)
337
335
 
338
- // Add the child fields of the array with qualified names
339
336
  if (Array.isArray(child.attrs.schema)) {
340
337
  child.attrs.schema.forEach((schemaItem: SchemaItem) => {
341
338
  if (schemaItem && schemaItem.id && schemaItem.label) {
342
- // Create a qualified field name for the array item
343
339
  const qualifiedField = {
344
340
  ...schemaItem,
345
341
  id: `${child.id}.${schemaItem.id}`,
@@ -347,7 +343,6 @@ function getAllFields(schema: any[]): any[] {
347
343
  isArrayField: true
348
344
  }
349
345
 
350
- // Make sure to copy options if they exist
351
346
  if (schemaItem.options) {
352
347
  qualifiedField.options = schemaItem.options
353
348
  } else if (schemaItem.attrs && schemaItem.attrs.options) {
@@ -359,7 +354,6 @@ function getAllFields(schema: any[]): any[] {
359
354
  })
360
355
  }
361
356
  } else {
362
- // Regular non-array field
363
357
  addFieldIfNew(child)
364
358
  }
365
359
  }
@@ -552,7 +546,7 @@ function checkMappingComplete() {
552
546
  // If no strictly required fields, we just need at least one mapping or default value
553
547
  if (requiredFields.length === 0) {
554
548
  mappingComplete.value = Object.keys(fieldMapping).some(key => !!fieldMapping[key])
555
- || Object.keys(defaultValues).length > 0
549
+ || Object.keys(defaultValues).length > 0
556
550
  return
557
551
  }
558
552
 
@@ -878,7 +872,6 @@ function handleSelectChange(event: Event, fieldId: string) {
878
872
  const { addFile, browse, fileQueue } = useFileUpload()
879
873
 
880
874
  async function handleFilesUploaded() {
881
- console.log('fileQueue', fileQueue.value)
882
875
  file.value = fileQueue.value[0].file
883
876
  if (!file.value) return
884
877
  isLoading.value = true
@@ -911,22 +904,13 @@ function hasDefaultValue(fieldId: string): boolean {
911
904
  // Function to open transformation dialog
912
905
  function openTransformDialog(field: SchemaItem) {
913
906
  try {
914
- console.log('Opening transform dialog for field:', field.id, field)
915
-
916
- // Make sure to set options property from attrs if needed
917
907
  if (!field.options) {
918
908
  field.options = []
919
909
  }
920
910
 
921
911
  if (field.attrs && field.attrs.options) {
922
- console.log('Copying options from attrs for field:', field.id)
923
- field.options = Array.isArray(field.attrs.options)
924
- ? field.attrs.options
925
- : []
912
+ field.options = field.attrs.options
926
913
  }
927
-
928
- console.log('Field options after processing:', field.options)
929
-
930
914
  selectedTransformField.value = field
931
915
  if (!transformations[field.id]) {
932
916
  transformations[field.id] = []
@@ -1052,28 +1036,6 @@ function autoPopulateTransformations(fieldId: string) {
1052
1036
  }
1053
1037
  }
1054
1038
 
1055
- // Add a debug function to log field options
1056
- function debugFieldOptions() {
1057
- console.log('Checking all fields for options:')
1058
- schemaFields.value.forEach((field) => {
1059
- console.log(`Field ${field.id} (${field.label}):`, {
1060
- directOptions: field.options,
1061
- hasDirectOptions: field.options && field.options.length > 0,
1062
- attrOptions: field.attrs?.options,
1063
- hasAttrOptions: field.attrs && field.attrs.options && field.attrs.options.length > 0,
1064
- visibleButton: (field.options && field.options.length > 0) || (field.attrs && field.attrs.options && field.attrs.options.length > 0)
1065
- })
1066
- })
1067
- }
1068
-
1069
- // Run debug function on schema load
1070
- watchEffect(() => {
1071
- if (props.schema && props.schema.length > 0) {
1072
- console.log('Schema loaded, checking options')
1073
- debugFieldOptions()
1074
- }
1075
- })
1076
-
1077
1039
  // Function to detect date format from string
1078
1040
  function detectDateFormat(value: string): RegExp | null {
1079
1041
  // Common date formats
@@ -1090,7 +1052,6 @@ function detectDateFormat(value: string): RegExp | null {
1090
1052
  return format
1091
1053
  }
1092
1054
  }
1093
-
1094
1055
  return null
1095
1056
  }
1096
1057
 
@@ -1182,24 +1143,19 @@ function convertValueByType(value: any, dataType: string): any {
1182
1143
  }
1183
1144
  }
1184
1145
 
1185
- // Function to detect the most likely data type from a value
1186
1146
  function detectDataType(value: any): string {
1187
1147
  if (value === null || value === undefined) {
1188
1148
  return DATA_TYPES.STRING
1189
1149
  }
1190
-
1191
1150
  if (typeof value === 'number' || (typeof value === 'string' && !Number.isNaN(Number(value)))) {
1192
1151
  if (isExcelSerialDate(Number(value))) {
1193
1152
  return DATA_TYPES.DATE
1194
1153
  }
1195
1154
  return DATA_TYPES.NUMBER
1196
1155
  }
1197
-
1198
1156
  if (typeof value === 'boolean' || (typeof value === 'string' && ['true', 'false', 'yes', 'no'].includes(value.toLowerCase()))) {
1199
1157
  return DATA_TYPES.BOOLEAN
1200
1158
  }
1201
-
1202
- // Check if it's a date
1203
1159
  if (value instanceof Date) {
1204
1160
  return DATA_TYPES.DATETIME
1205
1161
  }
@@ -1554,16 +1510,16 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1554
1510
  </script>
1555
1511
 
1556
1512
  <template>
1557
- <div class="upload-data-container">
1558
- <h2 v-text="props.title || 'Upload and Map Data'" />
1513
+ <Card class="upload-data-container h-100p grid overflow-hidden list-wrap ">
1514
+ <h2 class="line-height-1 m-0 pb-2 txt-center" v-text="props.title || 'Upload and Map Data'" />
1559
1515
  <DragOver
1560
1516
  v-if="!file"
1561
1517
  accept=".csv,.xls,.xlsx"
1562
1518
  @addFiles="addFile"
1563
1519
  @click="browse(false)"
1564
1520
  >
1565
- <Card class="flex flex-column items-center justify-center outline-dashed outline-3 hover">
1566
- <Icon name="upload_file" size="5" />
1521
+ <Card class="flex flex-column items-center justify-center outline-dashed outline-3 bg-input hover h-100p justify-content-center">
1522
+ <Icon name="upload" size="5" />
1567
1523
  <p>Drag and drop an Excel or CSV file here</p>
1568
1524
  <p>or click to select a file</p>
1569
1525
  <p class="txt-12 color-gray">
@@ -1579,118 +1535,109 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1579
1535
  </div>
1580
1536
 
1581
1537
  <!-- Step 2: Sheet selection and configuration -->
1582
- <div v-if="file && !isLoading && sheetNames.length > 0" class="config-section">
1583
- <div class="file-info mb-1">
1584
- <div class="file-chip">
1585
- {{ file.name }}
1586
- </div>
1587
- <Btn thin round value="Change File" @click="file = null" />
1538
+ <div class="overflow h-100p">
1539
+ <div v-if="file && !isLoading && sheetNames.length > 0" class="config-section flex gap-05 pb-2">
1540
+ <Btn v-tooltip="'Change File'" :value="file.name" thin round iconEnd="edit" @click="file = null" />
1541
+ <SelectInput v-if="sheetNames.length > 1" v-model="selectedSheet" :options="sheetNames" label="Select Sheet" />
1542
+ <CheckInput v-model="hasHeaders" label="Mark this if file has a header row" class="m-0" />
1588
1543
  </div>
1589
- <SelectInput v-if="sheetNames.length > 1" v-model="selectedSheet" :options="sheetNames" label="Select Sheet" />
1590
1544
 
1591
- <div class="header-config">
1592
- <label>File has headers?</label>
1593
- <CheckInput v-model="hasHeaders" label="First row contains column names" />
1594
- </div>
1595
- </div>
1545
+ <!-- Step 3: Field Mapping -->
1546
+ <div v-if="file && !isLoading && fileHeaders.length > 0">
1547
+ <!-- <h3 class="mt-0">
1548
+ Map Fields
1549
+ </h3> -->
1550
+ <p class="label pb-1 border-bottom mb-1">
1551
+ Match each required field to a column from your file, set default values, or configure transformations
1552
+ </p>
1596
1553
 
1597
- <!-- Step 3: Field Mapping -->
1598
- <Card v-if="file && !isLoading && fileHeaders.length > 0">
1599
- <h3 class="mt-0">
1600
- Map Fields
1601
- </h3>
1602
- <p class="instructions">
1603
- Match each required field to a column from your file, set default values, or configure transformations
1604
- </p>
1605
-
1606
- <div class="mapping-table">
1607
- <table class="tbl">
1608
- <thead>
1609
- <tr>
1610
- <th>Schema Field</th>
1611
- <th>File Column</th>
1612
- <th>Default Value</th>
1613
- <th>Data Type</th>
1614
- <th>Actions</th>
1615
- </tr>
1616
- </thead>
1617
- <tbody>
1618
- <tr v-for="field in schemaFields" :key="field.id" :class="{ 'array-field-row': field.isArrayField || field.$el === 'array' }">
1619
- <td>
1620
- <div class="field-label">
1621
- {{ field.label }}
1622
- <span v-if="field.isArrayField">↳</span>
1623
- <Pill v-if="field.$el === 'array'" outline thin value="Array" />
1624
- <!-- <span v-if="field.$el === 'array'" class="array-parent-indicator">[Array]</span> -->
1625
- <span v-if="isFieldRequired(field)">*</span>
1626
- <span v-if="getFieldDescription(field).isConditional">†</span>
1627
- </div>
1628
- <div v-if="field.disabled" class="field-disabled-reason">
1629
- {{ field.disabledReason }}
1630
- </div>
1631
- <div v-if="getFieldDescription(field).isConditional">
1632
- {{ getFieldDescription(field).description }}
1633
- </div>
1634
- </td>
1635
- <td>
1636
- <SelectInput
1637
- v-model="fieldMapping[field.id]"
1638
- :options="fileHeaders"
1639
- :required="isFieldRequired(field)"
1640
- :disabled="field.disabled"
1641
- @change="handleSelectChange($event, field.id)"
1554
+ <div class="mapping-table">
1555
+ <div class="grid grid-wrap-5 gap-1 bold pb-1">
1556
+ <p>Schema Field</p>
1557
+ <p>Column from File</p>
1558
+ <p>Default Value</p>
1559
+ <p>Data Type</p>
1560
+ <p>Actions</p>
1561
+ </div>
1562
+
1563
+ <div v-for="field in schemaFields" :key="field.id" class="grid grid-wrap-5 gap-1" :class="{ 'array-field-row': field.isArrayField || field.$el === 'array' }">
1564
+ <div>
1565
+ <div class="field-label">
1566
+ {{ field.label }}
1567
+ <span v-if="field.isArrayField">↳</span>
1568
+ <Pill v-if="field.$el === 'array'" class="txt10 ms-05" round thin value="Array" />
1569
+ <!-- <span v-if="field.$el === 'array'" class="array-parent-indicator">[Array]</span> -->
1570
+ <span v-if="isFieldRequired(field)">*</span>
1571
+ <span v-if="getFieldDescription(field).isConditional">†</span>
1572
+ </div>
1573
+ <div v-if="field.disabled" class="field-disabled-reason">
1574
+ {{ field.disabledReason }}
1575
+ </div>
1576
+ <div v-if="getFieldDescription(field).isConditional">
1577
+ {{ getFieldDescription(field).description }}
1578
+ </div>
1579
+ </div>
1580
+ <td class="fileColSelect">
1581
+ <SelectInput
1582
+ v-model="fieldMapping[field.id]"
1583
+ icon="table_chart"
1584
+ :options="fileHeaders"
1585
+ :required="isFieldRequired(field)"
1586
+ :disabled="field.disabled"
1587
+ @change="handleSelectChange($event, field.id)"
1588
+ />
1589
+ </td>
1590
+ <div>
1591
+ <!-- Default Value Input -->
1592
+ <div class="default-value-container hideLabel">
1593
+ {{ initDefaultValue(field.id) }}
1594
+ <component
1595
+ :is="renderField(getFieldWithDefaults(field))"
1642
1596
  />
1643
- </td>
1644
- <td>
1645
- <!-- Default Value Input -->
1646
- <div class="default-value-container">
1647
- {{ initDefaultValue(field.id) }}
1648
- <component
1649
- :is="renderField(getFieldWithDefaults(field))"
1650
- />
1651
- </div>
1652
- </td>
1653
- <td>
1654
- <SelectInput
1655
- v-model="fieldDataTypes[field.id]"
1656
- :options="dataTypeOptions"
1657
- :disabled="!fieldMapping[field.id] && !defaultValues[field.id]"
1597
+ </div>
1598
+ </div>
1599
+ <div>
1600
+ <SelectInput
1601
+ v-model="fieldDataTypes[field.id]"
1602
+ :options="dataTypeOptions"
1603
+ :disabled="!fieldMapping[field.id] && !defaultValues[field.id]"
1604
+ />
1605
+ </div>
1606
+ <div>
1607
+ <div class="flex gap-05">
1608
+ <Btn
1609
+ v-tooltip="'Transform'"
1610
+ thin
1611
+ :disabled="field.disabled"
1612
+ icon="transform"
1613
+ @click="openTransformDialog(field)"
1658
1614
  />
1659
- </td>
1660
- <td>
1661
- <div class="action-buttons-cell">
1662
- <Btn
1663
- v-tooltip="'Transform'"
1664
- thin
1665
- :disabled="field.disabled"
1666
- icon="transform"
1667
- @click="openTransformDialog(field)"
1668
- />
1669
- <Btn v-if="field.$el === 'array'" v-tooltip="'Related File'" thin icon="attach_file" :disabled="field.disabled" @click="openRelatedDialog(field)" />
1670
- </div>
1671
- </td>
1672
- </tr>
1673
- </tbody>
1674
- </table>
1675
- </div>
1615
+ <Btn v-if="field.$el === 'array'" v-tooltip="'Related File'" thin icon="attach_file" :disabled="field.disabled" @click="openRelatedDialog(field)" />
1616
+ </div>
1617
+ </div>
1618
+ </div>
1619
+ </div>
1676
1620
 
1677
- <div v-if="mappingComplete" class="action-buttons">
1678
- <Btn @click="showPreview">
1679
- Preview Data
1680
- </Btn>
1681
- </div>
1682
- <div v-else class="action-buttons">
1683
- <div class="mapping-incomplete-message">
1684
- Please map the required fields to continue
1621
+ <div v-if="mappingComplete" class="action-buttons">
1622
+ <Btn @click="showPreview">
1623
+ Preview Data
1624
+ </Btn>
1625
+ </div>
1626
+ <div v-else class="action-buttons">
1627
+ <div class="mapping-incomplete-message">
1628
+ Please map the required fields to continue
1629
+ </div>
1685
1630
  </div>
1686
1631
  </div>
1687
- </Card>
1632
+ </div>
1688
1633
 
1689
1634
  <!-- Transformation Modal -->
1690
1635
  <Modal v-model:visible="showTransformDialog" title="Configure Transformations" width="800">
1691
1636
  <div v-if="selectedTransformField">
1692
- <p>Create transformations for <strong>{{ selectedTransformField.label }}</strong></p>
1693
- <Btn icon="auto_awesome" thin value="Autodetect" @click="autoPopulateTransformations(selectedTransformField.id)" />
1637
+ <div class="flex space-between gap-1 mb-1">
1638
+ <p>Create transformations for <strong>{{ selectedTransformField.label }}</strong></p>
1639
+ <Btn icon="auto_awesome" thin value="Autodetect" @click="autoPopulateTransformations(selectedTransformField.id)" />
1640
+ </div>
1694
1641
  <table>
1695
1642
  <thead>
1696
1643
  <tr>
@@ -1746,22 +1693,26 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1746
1693
  </tr>
1747
1694
  </tbody>
1748
1695
  </table>
1749
- <Btn thin value="Close" @click="showTransformDialog = false" />
1696
+ <div class="flex pt-05">
1697
+ <Btn class="ms-auto" value="Close" @click="showTransformDialog = false" />
1698
+ </div>
1750
1699
  </div>
1751
1700
  </Modal>
1752
1701
 
1753
1702
  <!-- Related File Modal -->
1754
1703
  <Modal v-model:visible="showRelatedDialog" title="Configure Related Data" width="900">
1755
1704
  <div v-if="selectedRelationField">
1756
- <p>Upload a file with related data for {{ selectedRelationField.label }}</p>
1705
+ <p class="pb-05">
1706
+ Upload a file with related data for {{ selectedRelationField.label }}
1707
+ </p>
1757
1708
 
1758
- <div v-if="!relatedFiles[selectedRelationField.id]">
1709
+ <div v-if="!relatedFiles[selectedRelationField.id]" class="mb-05">
1759
1710
  <DragOver
1760
1711
  accept=".csv,.xls,.xlsx"
1761
1712
  @addFiles="(files) => { if (files[0]) processRelatedFile(selectedRelationField!.id, files[0]) }"
1762
1713
  >
1763
- <Card class="flex flex-column items-center justify-center outline-dashed outline-3 hover">
1764
- <Icon name="upload_file" size="5" />
1714
+ <Card class="flex flex-column items-center justify-center outline-dashed outline-3 hover bg-input">
1715
+ <Icon name="upload" size="5" />
1765
1716
  <p>Drag and drop an Excel or CSV file here</p>
1766
1717
  <p>or click to select a file</p>
1767
1718
  <p class="txt-12 color-gray">
@@ -1841,7 +1792,9 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1841
1792
  </table>
1842
1793
  </div>
1843
1794
  </div>
1844
- <Btn value="Close" @click="showRelatedDialog = false" />
1795
+ <div class="flex pt-05">
1796
+ <Btn class="ms-auto" value="Close" @click="showRelatedDialog = false" />
1797
+ </div>
1845
1798
  </div>
1846
1799
  </Modal>
1847
1800
 
@@ -1960,5 +1913,25 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1960
1913
  </div>
1961
1914
  </div>
1962
1915
  </Modal>
1963
- </div>
1916
+ </Card>
1964
1917
  </template>
1918
+
1919
+ <style>
1920
+ .fileColSelect{
1921
+ --input-bg: var(--bgl-green-light);
1922
+ }
1923
+ .fileColSelect .bgl_icon-font{
1924
+ color: var(--bgl-green);
1925
+ line-height: 0;
1926
+ }
1927
+ .hideLabel label{
1928
+ font-size: 0 !important;
1929
+ }
1930
+ .mapping-table .selectinput-btn:disabled{
1931
+ background: var(--input-bg) !important;
1932
+ cursor: not-allowed !important;
1933
+ }
1934
+ .field-label{
1935
+ --pill-height: 20px;
1936
+ }
1937
+ </style>
@@ -1,6 +1,8 @@
1
1
  <script setup lang="ts">
2
2
  import type { UploadInputProps } from '@bagelink/vue'
3
3
  import { Btn, IMAGE_FORMATS_REGEXP, Icon, Card, Image, pathKeyToURL } from '@bagelink/vue'
4
+ import { watchDebounced } from '@vueuse/core'
5
+ import { toValue } from 'vue'
4
6
  import { useFileUpload } from './useFileUpload'
5
7
 
6
8
  const props = withDefaults(defineProps<UploadInputProps>(), {
@@ -19,6 +21,7 @@ const {
19
21
  fileToUrl,
20
22
  addFile,
21
23
  browse,
24
+ pk
22
25
  } = useFileUpload({
23
26
  disabled: props.disabled,
24
27
  dirPath: props.dirPath,
@@ -43,9 +46,24 @@ async function handleDrop(e: DragEvent) {
43
46
  emit('addFileStart')
44
47
  addFile(e.dataTransfer?.files)
45
48
  await flushQueue()
46
- emit('update:modelValue', pathKeys.value)
49
+ // emit('update:modelValue', pathKeys.value)
47
50
  isDragOver = false
48
51
  }
52
+
53
+ watchDebounced(() => toValue(pk), (value) => {
54
+ if (props.multiple) emit('update:modelValue', value)
55
+ else emit('update:modelValue', value[0] || undefined)
56
+ }, { deep: true, immediate: true })
57
+
58
+ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
59
+ if (`${newVal}` === `${oldVal}`) return
60
+ if (newVal === undefined) return
61
+ if (Array.isArray(newVal)) {
62
+ pk.value = newVal
63
+ } else {
64
+ pk.value = [newVal]
65
+ }
66
+ }, { immediate: true, debounce: 500 })
49
67
  </script>
50
68
 
51
69
  <template>
@@ -1,5 +1,4 @@
1
1
  import type { ArrayFieldVal, Attributes, BaseBagelField, BglFormSchemaT, Field, IconType, InputBagelField, Option, Path, SchemaChild, SelectBagelField, UploadInputProps } from '@bagelink/vue'
2
- // import type { UploadInputProps } from '../components/form/inputs/Upload/upload.types'
3
2
 
4
3
  interface InputOptions<T, P extends Path<T>> extends Partial<BaseBagelField<T, P>> {
5
4
  defaultValue?: string | number
@@ -1,23 +0,0 @@
1
- export interface TimeUnit {
2
- singular: string;
3
- plural: string;
4
- }
5
- export type TranslationValue = string | TimeUnit;
6
- export interface LanguageTranslations {
7
- [key: string]: TranslationValue;
8
- }
9
- export type AvailableTimeLanguages = 'en' | 'es' | 'fr' | 'he';
10
- export type DayFormatTypes = 'DD' | 'DDD' | 'DDDD';
11
- export type MonthFormatTypes = 'MM' | 'MMM' | 'MMMM';
12
- export type YearFormatTypes = 'YY' | 'YYYY';
13
- export type HourFormatTypes = 'HH';
14
- export type MinuteFormatTypes = 'mm';
15
- export type SecondFormatTypes = 'ss';
16
- export type MillisecondFormatTypes = 'sss';
17
- export type AmPmFormatTypes = 'AmPm';
18
- export type DateFormatSeparatorTypes = '/' | '-' | ' ' | ':' | '.';
19
- export type CommonDateFormats = `${DayFormatTypes}${DateFormatSeparatorTypes}${MonthFormatTypes}${DateFormatSeparatorTypes}${YearFormatTypes}` | 'DD.MM.YY' | 'DD.MM.YYYY' | 'DD/MM/YY' | 'DD/MM/YYYY' | 'MM.DD.YY' | 'MM.DD.YYYY' | 'MM/DD/YY' | 'MM/DD/YYYY' | 'YYYY-MM-DD' | 'YY-MM-DD' | 'DD MMM YYYY' | 'DD MMMM YYYY' | 'DDD, DD MMM' | 'DDDD, DD MMMM' | 'MMM DD' | 'MMMM DD';
20
- export type CommonTimeFormats = 'HH:mm' | 'HH:mm:ss' | 'HH:mm:ss:sss' | 'HH:MM' | 'HH:mm AmPm';
21
- export type CommonDateTimeFormats = `${CommonDateFormats} ${CommonTimeFormats}` | `${CommonTimeFormats}, ${CommonDateFormats}` | 'YYYY-MM-DD HH:MM';
22
- export type DateTimeAcceptedFormats = CommonDateFormats | CommonTimeFormats | CommonDateTimeFormats;
23
- //# sourceMappingURL=timeago.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"timeago.d.ts","sourceRoot":"","sources":["../../src/types/timeago.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE9D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAA;AAClD,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAA;AACpD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,CAAA;AAC3C,MAAM,MAAM,eAAe,GAAG,IAAI,CAAA;AAClC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAA;AACpC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAA;AACpC,MAAM,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAC1C,MAAM,MAAM,eAAe,GAAG,MAAM,CAAA;AAEpC,MAAM,MAAM,wBAAwB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAGlE,MAAM,MAAM,iBAAiB,GAC1B,GAAG,cAAc,GAAG,wBAAwB,GAAG,gBAAgB,GAAG,wBAAwB,GAAG,eAAe,EAAE,GAC9G,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GACrD,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GACrD,YAAY,GAAG,UAAU,GACzB,aAAa,GAAG,cAAc,GAC9B,aAAa,GAAG,eAAe,GAC/B,QAAQ,GAAG,SAAS,CAAA;AAEvB,MAAM,MAAM,iBAAiB,GAC1B,OAAO,GAAG,UAAU,GAAG,cAAc,GACrC,OAAO,GACP,YAAY,CAAA;AAGf,MAAM,MAAM,qBAAqB,GAC9B,GAAG,iBAAiB,IAAI,iBAAiB,EAAE,GAC3C,GAAG,iBAAiB,KAAK,iBAAiB,EAAE,GAC5C,kBAAkB,CAAA;AAGrB,MAAM,MAAM,uBAAuB,GAChC,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,CAAA"}