sf-git-merge-driver 1.2.1 → 1.2.2

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/README.md CHANGED
@@ -1,23 +1,169 @@
1
1
  # Salesforce Metadata Git Merge Driver
2
2
 
3
- A custom Git merge driver designed specifically for Salesforce metadata files. This tool helps resolve merge conflicts in Salesforce XML metadata files by understanding their structure and intelligently merging changes.
3
+ [![License](https://img.shields.io/badge/License-MIT-blue)]()
4
+ [![Compatibility](https://img.shields.io/badge/Windows%20%7C%20Mac%20%7C%20Linux-Supported-success)]()
4
5
 
5
- ## Features
6
+ An intelligent Git merge driver specifically designed for Salesforce metadata files. **Eliminates hours** of manual merge conflicts resolution.
6
7
 
7
- - Intelligent merging of Salesforce XML metadata files
8
- - Handles complex metadata structures like arrays with unique identifiers
9
- - Supports both local and global installation
10
- - Easy to use with SFDX CLI plugin commands
11
- - Warning: as of now it does not preserve the order of items that are order dependant like valuesets
8
+ ## Demo
12
9
 
13
- ## Installation
10
+ ### Without sf-git-merge-driver
11
+ ![Demo without sf-git-merge-driver](./docs/media/demo-without-sf-git-merge-driver.gif)
12
+
13
+ ### With sf-git-merge-driver
14
+ ![Demo with sf-git-merge-driver](./docs/media/demo-with-sf-git-merge-driver.gif)
15
+
16
+ ## Why use this plugin?
17
+
18
+ - **Saves time**: No more manual XML conflict resolution
19
+ - **Zero-config**: Works immediately after installation
20
+ - **Reliable**: Understands Salesforce metadata structure
21
+ - **Transparent**: Seamless Git workflow integration
22
+
23
+ ## How it works
24
+
25
+ ```mermaid
26
+ sequenceDiagram
27
+ participant Dev
28
+ participant Git
29
+ participant MergeDriver
30
+
31
+ Dev->>Git: git merge
32
+ Git->>MergeDriver: Detects XML conflict
33
+ MergeDriver->>MergeDriver: Analyzes metadata structure
34
+ MergeDriver->>MergeDriver: Smart merging
35
+ MergeDriver->>Git: Returns merged result
36
+ Git->>Dev: Clean commit (no conflicts)
37
+ ```
38
+
39
+ ## Installation (30 seconds)
14
40
 
15
41
  ```bash
42
+ # Install plugin (one time, global)
16
43
  sf plugins install sf-git-merge-driver
44
+
45
+ # Configure merge driver in your project (one time, local per project)
46
+ cd my/sf/project
47
+ sf git merge driver install
17
48
  ```
18
49
 
19
50
  ## Usage
20
51
 
52
+ The merge driver activates **automatically** for conflicts on:
53
+ - [Full list of supported metadata](#configuration)
54
+
55
+ **No additional steps required!** Works during normal Git operations:
56
+ ```bash
57
+ git pull # Conflicts resolved automatically
58
+ git merge # Same here
59
+ ```
60
+
61
+ ## Configuration
62
+
63
+ Configured for these metadata files by default:
64
+ ```gitattributes
65
+ *.profile-meta.xml merge=salesforce-source
66
+ *.permissionset-meta.xml merge=salesforce-source
67
+ *.labels-meta.xml merge=salesforce-source
68
+ *.label-meta.xml merge=salesforce-source
69
+ *.applicationVisibility-meta.xml merge=salesforce-source
70
+ *.classAccess-meta.xml merge=salesforce-source
71
+ *.customMetadataTypeAccess-meta.xml merge=salesforce-source
72
+ *.customPermission-meta.xml merge=salesforce-source
73
+ *.customSettingAccess-meta.xml merge=salesforce-source
74
+ *.externalCredentialPrincipalAccess-meta.xml merge=salesforce-source
75
+ *.externalDataSourceAccess-meta.xml merge=salesforce-source
76
+ *.fieldPermission-meta.xml merge=salesforce-source
77
+ *.flowAccess-meta.xml merge=salesforce-source
78
+ *.objectPermission-meta.xml merge=salesforce-source
79
+ *.pageAccess-meta.xml merge=salesforce-source
80
+ *.recordTypeVisibility-meta.xml merge=salesforce-source
81
+ *.tabSetting-meta.xml merge=salesforce-source
82
+ *.userPermission-meta.xml merge=salesforce-source
83
+ *.objectSettings-meta.xml merge=salesforce-source
84
+ *.permissionsetgroup-meta.xml merge=salesforce-source
85
+ *.permissionSetLicenseDefinition-meta.xml merge=salesforce-source
86
+ *.mutingpermissionset-meta.xml merge=salesforce-source
87
+ *.sharingRules-meta.xml merge=salesforce-source
88
+ *.sharingCriteriaRule-meta.xml merge=salesforce-source
89
+ *.sharingGuestRule-meta.xml merge=salesforce-source
90
+ *.sharingOwnerRule-meta.xml merge=salesforce-source
91
+ *.sharingTerritoryRule-meta.xml merge=salesforce-source
92
+ *.workflow-meta.xml merge=salesforce-source
93
+ *.workflowAlert-meta.xml merge=salesforce-source
94
+ *.workflowFieldUpdate-meta.xml merge=salesforce-source
95
+ *.workflowFlowAction-meta.xml merge=salesforce-source
96
+ *.workflowKnowledgePublish-meta.xml merge=salesforce-source
97
+ *.workflowOutboundMessage-meta.xml merge=salesforce-source
98
+ *.workflowRule-meta.xml merge=salesforce-source
99
+ *.workflowSend-meta.xml merge=salesforce-source
100
+ *.workflowTask-meta.xml merge=salesforce-source
101
+ *.assignmentRules-meta.xml merge=salesforce-source
102
+ *.autoResponseRules-meta.xml merge=salesforce-source
103
+ *.escalationRules-meta.xml merge=salesforce-source
104
+ *.marketingappextension-meta.xml merge=salesforce-source
105
+ *.matchingRule-meta.xml merge=salesforce-source
106
+ *.globalValueSet-meta.xml merge=salesforce-source
107
+ *.standardValueSet-meta.xml merge=salesforce-source
108
+ *.globalValueSetTranslation-meta.xml merge=salesforce-source
109
+ *.standardValueSetTranslation-meta.xml merge=salesforce-source
110
+ *.translation-meta.xml merge=salesforce-source
111
+ *.objectTranslation-meta.xml merge=salesforce-source
112
+ ```
113
+
114
+ ## How to disable it for a specific merge
115
+
116
+ When you don't want to use the merge driver for a specific merge, just backup the `.git/info/attributes` file and put it back after the merge.
117
+ ```sh
118
+ mv .git/info/attributes .git/info/attributes.bak
119
+ git merge <branch>
120
+ mv .git/info/attributes.bak .git/info/attributes
121
+ ```
122
+
123
+ If you want to disable the merge driver for a specific file, just comment the merge driver configuration from the `.git/info/attributes` file.
124
+ ```sh
125
+ # *.profile-meta.xml merge=salesforce-source
126
+ ```
127
+
128
+ If you want to disable it for all the project, just uninstall the driver:
129
+ ```sh
130
+ sf git merge driver uninstall
131
+ ```
132
+
133
+ ## How to know if it is installed and enabled ?
134
+
135
+ You can check if the merge driver is installed by running the following command:
136
+ ```sh
137
+ git config --show-origin --get-regexp '^merge.salesforce-source(\..*)?'
138
+ ```
139
+
140
+ You can check if the merge driver is enabled by running the following command:
141
+ ```sh
142
+ grep "merge=salesforce-source" .git/info/attributes
143
+ ```
144
+
145
+ ## Troubleshooting
146
+
147
+ The plugin uses the [Salesforce CLI logging system](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_dev_cli_log_messages.htm) to log information.
148
+ You can control the logging level by setting the `SF_LOG_LEVEL` environment variable.
149
+ You can redirect the logging in the terminal using `DEBUG=sf-git-merge-driver`.
150
+
151
+ You can also use `GIT_TRACE=1` to get more information about git operations.
152
+ You can also use `GIT_MERGE_VERBOSITY=5` to get more information about the merge process.
153
+ Git environment variables are detailed [here](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables).
154
+
155
+ Example:
156
+
157
+ ```sh
158
+ DEBUG=sf-git-merge-driver
159
+ SF_LOG_LEVEL=trace # can be error | warn | info | debug | trace, default: warn
160
+ GIT_MERGE_VERBOSITY=5 # can be 0 to 5
161
+ GIT_TRACE=true
162
+ git merge ...
163
+ ```
164
+
165
+ ## Commands
166
+
21
167
  <!-- commands -->
22
168
  * [`sf git merge driver install`](#sf-git-merge-driver-install)
23
169
  * [`sf git merge driver run`](#sf-git-merge-driver-run)
@@ -48,7 +194,7 @@ EXAMPLES
48
194
  $ sf git merge driver install
49
195
  ```
50
196
 
51
- _See code: [src/commands/git/merge/driver/install.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.1/src/commands/git/merge/driver/install.ts)_
197
+ _See code: [src/commands/git/merge/driver/install.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.2/src/commands/git/merge/driver/install.ts)_
52
198
 
53
199
  ## `sf git merge driver run`
54
200
 
@@ -92,7 +238,7 @@ EXAMPLES
92
238
  - output-file is the path to the file where the merged content will be written
93
239
  ```
94
240
 
95
- _See code: [src/commands/git/merge/driver/run.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.1/src/commands/git/merge/driver/run.ts)_
241
+ _See code: [src/commands/git/merge/driver/run.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.2/src/commands/git/merge/driver/run.ts)_
96
242
 
97
243
  ## `sf git merge driver uninstall`
98
244
 
@@ -119,92 +265,8 @@ EXAMPLES
119
265
  $ sf git merge driver uninstall
120
266
  ```
121
267
 
122
- _See code: [src/commands/git/merge/driver/uninstall.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.1/src/commands/git/merge/driver/uninstall.ts)_
268
+ _See code: [src/commands/git/merge/driver/uninstall.ts](https://github.com/scolladon/sf-git-merge-driver/blob/v1.2.2/src/commands/git/merge/driver/uninstall.ts)_
123
269
  <!-- commandsstop -->
124
-
125
- ## How It Works
126
-
127
- The merge driver works by:
128
- 1. Converting XML to JSON for easier processing
129
- 2. Using a specialized three-way merge algorithm that understands Salesforce metadata structures
130
- 3. Intelligently resolving conflicts based on metadata type
131
- 4. Converting the merged result back to properly formatted XML
132
-
133
- ## Configuration
134
-
135
- The driver is configured to work with `.xml` files by default. The installation adds the following to the `.git/info/attributes` file (so it is discrete for the current repo):
136
-
137
- ```
138
- *.labels-meta.xml merge=salesforce-source
139
- *.label-meta.xml merge=salesforce-source
140
- *.profile-meta.xml merge=salesforce-source
141
- *.permissionset-meta.xml merge=salesforce-source
142
- *.applicationVisibility-meta.xml merge=salesforce-source
143
- *.classAccess-meta.xml merge=salesforce-source
144
- *.customMetadataTypeAccess-meta.xml merge=salesforce-source
145
- *.customPermission-meta.xml merge=salesforce-source
146
- *.customSettingAccess-meta.xml merge=salesforce-source
147
- *.externalCredentialPrincipalAccess-meta.xml merge=salesforce-source
148
- *.externalDataSourceAccess-meta.xml merge=salesforce-source
149
- *.fieldPermission-meta.xml merge=salesforce-source
150
- *.flowAccess-meta.xml merge=salesforce-source
151
- *.objectPermission-meta.xml merge=salesforce-source
152
- *.pageAccess-meta.xml merge=salesforce-source
153
- *.recordTypeVisibility-meta.xml merge=salesforce-source
154
- *.tabSetting-meta.xml merge=salesforce-source
155
- *.userPermission-meta.xml merge=salesforce-source
156
- *.objectSettings-meta.xml merge=salesforce-source
157
- *.permissionsetgroup-meta.xml merge=salesforce-source
158
- *.permissionSetLicenseDefinition-meta.xml merge=salesforce-source
159
- *.mutingpermissionset-meta.xml merge=salesforce-source
160
- *.sharingRules-meta.xml merge=salesforce-source
161
- *.sharingCriteriaRule-meta.xml merge=salesforce-source
162
- *.sharingGuestRule-meta.xml merge=salesforce-source
163
- *.sharingOwnerRule-meta.xml merge=salesforce-source
164
- *.sharingTerritoryRule-meta.xml merge=salesforce-source
165
- *.workflow-meta.xml merge=salesforce-source
166
- *.workflowAlert-meta.xml merge=salesforce-source
167
- *.workflowFieldUpdate-meta.xml merge=salesforce-source
168
- *.workflowFlowAction-meta.xml merge=salesforce-source
169
- *.workflowKnowledgePublish-meta.xml merge=salesforce-source
170
- *.workflowOutboundMessage-meta.xml merge=salesforce-source
171
- *.workflowRule-meta.xml merge=salesforce-source
172
- *.workflowSend-meta.xml merge=salesforce-source
173
- *.workflowTask-meta.xml merge=salesforce-source
174
- *.assignmentRules-meta.xml merge=salesforce-source
175
- *.autoResponseRules-meta.xml merge=salesforce-source
176
- *.escalationRules-meta.xml merge=salesforce-source
177
- *.marketingappextension-meta.xml merge=salesforce-source
178
- *.matchingRule-meta.xml merge=salesforce-source
179
- *.globalValueSet-meta.xml merge=salesforce-source
180
- *.standardValueSet-meta.xml merge=salesforce-source
181
- *.globalValueSetTranslation-meta.xml merge=salesforce-source
182
- *.standardValueSetTranslation-meta.xml merge=salesforce-source
183
- *.translation-meta.xml merge=salesforce-source
184
- *.objectTranslation-meta.xml merge=salesforce-source
185
- ```
186
-
187
- ## Debugging
188
-
189
- The plugin uses the [Salesforce CLI logging system](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_dev_cli_log_messages.htm) to log information.
190
- You can control the logging level by setting the `SF_LOG_LEVEL` environment variable.
191
- You can redirect the logging in the terminal using `DEBUG=sf-git-merge-driver`.
192
-
193
- You can also use `GIT_TRACE=1` to get more information about git operations.
194
- You can also use `GIT_MERGE_VERBOSITY=5` to get more information about the merge process.
195
- Git environment variables are detailed [here](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables).
196
-
197
- Example:
198
-
199
- ```sh
200
- DEBUG=sf-git-merge-driver
201
- SF_LOG_LEVEL=trace # can be error | warn | info | debug | trace, default: warn
202
- GIT_MERGE_VERBOSITY=5 # can be 0 to 5
203
- GIT_TRACE=true
204
- git merge ...
205
- ```
206
-
207
-
208
270
  ## Changelog
209
271
 
210
272
  [changelog.md](CHANGELOG.md) is available for consultation.
@@ -220,7 +282,7 @@ Versioning follows [SemVer](http://semver.org/) specification.
220
282
 
221
283
  ## Contributing
222
284
 
223
- Contributions are what make the trailblazer community such an amazing place. I regard this component as a way to inspire and learn from others. Any contributions you make are **appreciated**.
285
+ Contributions are what make the trailblazer community such an amazing place. We regard this component as a way to inspire and learn from others. Any contributions you make are **appreciated**.
224
286
 
225
287
  See [contributing.md](CONTRIBUTING.md) for sgd contribution principles.
226
288
 
@@ -1 +1,2 @@
1
1
  export declare const GIT_INFO_ATTRIBUTES_PATH = "info/attributes";
2
+ export declare const GIT_EOL = "\n";
@@ -1,2 +1,3 @@
1
1
  export const GIT_INFO_ATTRIBUTES_PATH = 'info/attributes';
2
+ export const GIT_EOL = '\n';
2
3
  //# sourceMappingURL=gitConstant.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitConstant.js","sourceRoot":"","sources":["../../src/constant/gitConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG,iBAAiB,CAAA"}
1
+ {"version":3,"file":"gitConstant.js","sourceRoot":"","sources":["../../src/constant/gitConstant.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG,iBAAiB,CAAA;AACzD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAA"}
@@ -2,29 +2,35 @@ import { __decorate } from "tslib";
2
2
  import { readFile, writeFile } from 'node:fs/promises';
3
3
  import { simpleGit } from 'simple-git';
4
4
  import { DRIVER_NAME } from '../constant/driverConstant.js';
5
+ import { GIT_EOL } from '../constant/gitConstant.js';
5
6
  import { getGitAttributesPath } from '../utils/gitUtils.js';
6
7
  import { log } from '../utils/LoggingDecorator.js';
7
8
  import { Logger } from '../utils/LoggingService.js';
8
9
  // This match lines like: "*.profile-meta.xml merge=sf-git-merge-driver"
9
- const MERGE_DRIVER_CONFIG = new RegExp(`.*\s+merge\s*=\s*${DRIVER_NAME}$`);
10
+ const MERGE_DRIVER_CONFIG = new RegExp(String.raw `.*\s+merge\s*=\s*${DRIVER_NAME}\s*$`);
10
11
  export class UninstallService {
11
12
  async uninstallMergeDriver() {
12
13
  const git = simpleGit();
13
14
  try {
14
- // Throw when the merge driver is not installed
15
+ // Throws when the merge driver is not installed
15
16
  await git.raw(['config', '--remove-section', `merge.${DRIVER_NAME}`]);
17
+ }
18
+ catch (error) {
19
+ Logger.error('Merge driver uninstallation failed to cleanup git config', error);
20
+ }
21
+ try {
16
22
  const gitAttributesPath = await getGitAttributesPath();
17
- // Throw when the file does not exist
23
+ // Throws when the file does not exist
18
24
  const gitAttributes = await readFile(gitAttributesPath, {
19
25
  encoding: 'utf8',
20
26
  });
21
27
  const filteredAttributes = gitAttributes
22
- .split('\n')
28
+ .split(GIT_EOL)
23
29
  .filter(line => !MERGE_DRIVER_CONFIG.test(line));
24
- await writeFile(gitAttributesPath, filteredAttributes.join('\n'));
30
+ await writeFile(gitAttributesPath, filteredAttributes.join(GIT_EOL));
25
31
  }
26
32
  catch (error) {
27
- Logger.error('Merge driver uninstallation failed', error);
33
+ Logger.error('Merge driver uninstallation failed to cleanup git attributes', error);
28
34
  }
29
35
  }
30
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"uninstallService.js","sourceRoot":"","sources":["../../src/service/uninstallService.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAEnD,wEAAwE;AACxE,MAAM,mBAAmB,GAAG,IAAI,MAAM,CAAC,oBAAoB,WAAW,GAAG,CAAC,CAAA;AAE1E,MAAM,OAAO,gBAAgB;IAEd,AAAN,KAAK,CAAC,oBAAoB;QAC/B,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;QACvB,IAAI,CAAC;YACH,+CAA+C;YAC/C,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,WAAW,EAAE,CAAC,CAAC,CAAA;YAErE,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,EAAE,CAAA;YACtD,qCAAqC;YACrC,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,iBAAiB,EAAE;gBACtD,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAA;YACF,MAAM,kBAAkB,GAAG,aAAa;iBACrC,KAAK,CAAC,IAAI,CAAC;iBACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAClD,MAAM,SAAS,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC;CACF;AAnBc;IADZ,GAAG;4DAmBH"}
1
+ {"version":3,"file":"uninstallService.js","sourceRoot":"","sources":["../../src/service/uninstallService.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAEnD,wEAAwE;AACxE,MAAM,mBAAmB,GAAG,IAAI,MAAM,CACpC,MAAM,CAAC,GAAG,CAAA,oBAAoB,WAAW,MAAM,CAChD,CAAA;AAED,MAAM,OAAO,gBAAgB;IAEd,AAAN,KAAK,CAAC,oBAAoB;QAC/B,MAAM,GAAG,GAAG,SAAS,EAAE,CAAA;QACvB,IAAI,CAAC;YACH,gDAAgD;YAChD,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,SAAS,WAAW,EAAE,CAAC,CAAC,CAAA;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV,0DAA0D,EAC1D,KAAK,CACN,CAAA;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,EAAE,CAAA;YACtD,sCAAsC;YACtC,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,iBAAiB,EAAE;gBACtD,QAAQ,EAAE,MAAM;aACjB,CAAC,CAAA;YACF,MAAM,kBAAkB,GAAG,aAAa;iBACrC,KAAK,CAAC,OAAO,CAAC;iBACd,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAClD,MAAM,SAAS,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CACV,8DAA8D,EAC9D,KAAK,CACN,CAAA;QACH,CAAC;IACH,CAAC;CACF;AA7Bc;IADZ,GAAG;4DA6BH"}