gbs-add-block 1.2.9 → 1.2.10
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 +11 -2
- package/index.cjs +123 -80
- package/package.json +1 -1
- /package/source/{components → beta-components}/combobox/README.md +0 -0
- /package/source/{components → beta-components}/combobox/__tests__/core.test.ts +0 -0
- /package/source/{components → beta-components}/combobox/core/filter.ts +0 -0
- /package/source/{components → beta-components}/combobox/core/index.ts +0 -0
- /package/source/{components → beta-components}/combobox/core/types.ts +0 -0
- /package/source/{components → beta-components}/combobox/core/virtual.ts +0 -0
- /package/source/{components → beta-components}/combobox/index.ts +0 -0
- /package/source/{components → beta-components}/combobox/react/Listbox.tsx +0 -0
- /package/source/{components → beta-components}/combobox/react/MultiSelect.tsx +0 -0
- /package/source/{components → beta-components}/combobox/react/Popover.tsx +0 -0
- /package/source/{components → beta-components}/combobox/react/Select.tsx +0 -0
- /package/source/{components → beta-components}/combobox/react/icons.tsx +0 -0
- /package/source/{components → beta-components}/combobox/react/locale.ts +0 -0
- /package/source/{components → beta-components}/combobox/react/props.ts +0 -0
- /package/source/{components → beta-components}/combobox/react/useCombobox.ts +0 -0
- /package/source/{components → beta-components}/combobox/styles.css +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/README.md +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/__tests__/core.test.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/__tests__/export.test.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/columnHelper.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/columns.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/filtering.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/grid.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/index.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/rows.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/sorting.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/state.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/store.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/types.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/values.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/core/virtual.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/csv.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/download.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/pdf.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/table.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/xlsx.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/export/zip.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/index.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Cell.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/ColumnMenu.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/DataGrid.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/FilterForm.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/HeaderRow.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Pagination.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Popover.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Row.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Toolbar.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/Viewport.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/context.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/hooks.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/icons.tsx +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/keyboard.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/react/locale.ts +0 -0
- /package/source/{components/datagridbeta → beta-components/datagrid}/styles.css +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GBS Building Blocks 2.0 (v1.2.
|
|
1
|
+
# GBS Building Blocks 2.0 (v1.2.10)
|
|
2
2
|
|
|
3
3
|
Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
|
|
4
4
|
|
|
@@ -6,7 +6,16 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
|
|
|
6
6
|
|
|
7
7
|
For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://gramprokit.vercel.app)
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Beta Components
|
|
10
|
+
|
|
11
|
+
DataGrid and Combobox use the redesigned core API and design system. Install them with the beta flag:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx gbs-add-block -a DataGrid -beta
|
|
15
|
+
npx gbs-add-block -a Combobox -beta
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## What's New 🎉 (Ver 1.2.10)
|
|
10
19
|
|
|
11
20
|
- Update Candidate for next major change 2.0.0
|
|
12
21
|
|
package/index.cjs
CHANGED
|
@@ -32,11 +32,13 @@ const CONFIG = {
|
|
|
32
32
|
"DataGrid",
|
|
33
33
|
"BreadCrumb",
|
|
34
34
|
"Bargraph",
|
|
35
|
-
"UsePaginatedData",
|
|
36
|
-
"UseUploader",
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
"UsePaginatedData",
|
|
36
|
+
"UseUploader",
|
|
37
|
+
],
|
|
38
|
+
betaComponents: [
|
|
39
|
+
"DataGrid",
|
|
40
|
+
"Combobox",
|
|
41
|
+
],
|
|
40
42
|
// Define component dependencies
|
|
41
43
|
dependencies: {
|
|
42
44
|
FormRenderer: ["Select", "MultiSelect", "Input", "DatePicker"],
|
|
@@ -44,8 +46,19 @@ const CONFIG = {
|
|
|
44
46
|
docs: "https://gramprokit.vercel.app/",
|
|
45
47
|
};
|
|
46
48
|
|
|
47
|
-
const SOURCE_PATH = path.join(__dirname, "source", "components");
|
|
48
|
-
const
|
|
49
|
+
const SOURCE_PATH = path.join(__dirname, "source", "components");
|
|
50
|
+
const BETA_SOURCE_PATH = path.join(__dirname, "source", "beta-components");
|
|
51
|
+
const DEFAULT_DEST_PATH = path.join(process.cwd(), "component-lib");
|
|
52
|
+
|
|
53
|
+
const normalizeComponent = (component, availableComponents) =>
|
|
54
|
+
availableComponents.find(
|
|
55
|
+
(available) => available.toLowerCase() === component.toLowerCase(),
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const getAvailableComponents = (beta = false) =>
|
|
59
|
+
beta ? CONFIG.betaComponents : CONFIG.components;
|
|
60
|
+
|
|
61
|
+
const getSourcePath = (beta = false) => (beta ? BETA_SOURCE_PATH : SOURCE_PATH);
|
|
49
62
|
|
|
50
63
|
const copyCommonFiles = async (destPath) => {
|
|
51
64
|
const commonFiles = [
|
|
@@ -68,14 +81,16 @@ const checkComponentExists = (component, destPath) => {
|
|
|
68
81
|
return fs.existsSync(componentPath);
|
|
69
82
|
};
|
|
70
83
|
|
|
71
|
-
const copyComponent = async (component, destPath) => {
|
|
72
|
-
try {
|
|
73
|
-
const componentSrc = path.join(
|
|
84
|
+
const copyComponent = async (component, destPath, beta = false) => {
|
|
85
|
+
try {
|
|
86
|
+
const componentSrc = path.join(getSourcePath(beta), component.toLowerCase());
|
|
74
87
|
const componentDest = path.join(destPath, component.toLowerCase());
|
|
75
88
|
|
|
76
|
-
if (!fs.existsSync(componentSrc)) {
|
|
77
|
-
throw new Error(
|
|
78
|
-
|
|
89
|
+
if (!fs.existsSync(componentSrc)) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Component ${component} not found in ${beta ? "beta " : ""}source directory.`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
79
94
|
|
|
80
95
|
await fs.copy(componentSrc, componentDest, { overwrite: true });
|
|
81
96
|
console.log(
|
|
@@ -91,15 +106,17 @@ const copyComponent = async (component, destPath) => {
|
|
|
91
106
|
}
|
|
92
107
|
};
|
|
93
108
|
|
|
94
|
-
const installComponentWithDependencies = async (component, destPath) => {
|
|
109
|
+
const installComponentWithDependencies = async (component, destPath, beta = false) => {
|
|
95
110
|
// Get dependencies for the component
|
|
96
111
|
const dependencies = CONFIG.dependencies[component] || [];
|
|
97
112
|
const componentsToInstall = new Set([component, ...dependencies]);
|
|
98
113
|
|
|
99
114
|
// Check which components need to be installed
|
|
100
|
-
const pendingInstalls =
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
const pendingInstalls = beta
|
|
116
|
+
? Array.from(componentsToInstall)
|
|
117
|
+
: Array.from(componentsToInstall).filter(
|
|
118
|
+
(comp) => !checkComponentExists(comp, destPath),
|
|
119
|
+
);
|
|
103
120
|
|
|
104
121
|
if (pendingInstalls.length === 0) {
|
|
105
122
|
console.log(
|
|
@@ -110,7 +127,7 @@ const installComponentWithDependencies = async (component, destPath) => {
|
|
|
110
127
|
|
|
111
128
|
// Install all pending components
|
|
112
129
|
for (const comp of pendingInstalls) {
|
|
113
|
-
await copyComponent(comp, destPath);
|
|
130
|
+
await copyComponent(comp, destPath, beta);
|
|
114
131
|
}
|
|
115
132
|
|
|
116
133
|
if (dependencies.length > 0) {
|
|
@@ -123,7 +140,7 @@ const installComponentWithDependencies = async (component, destPath) => {
|
|
|
123
140
|
console.log(`\nFor documentation visit: ${CONFIG.docs}`);
|
|
124
141
|
};
|
|
125
142
|
|
|
126
|
-
const installMultipleComponents = async (components, destPath) => {
|
|
143
|
+
const installMultipleComponents = async (components, destPath, beta = false) => {
|
|
127
144
|
const allComponentsToInstall = new Set();
|
|
128
145
|
|
|
129
146
|
// Collect all components and their dependencies
|
|
@@ -134,9 +151,11 @@ const installMultipleComponents = async (components, destPath) => {
|
|
|
134
151
|
});
|
|
135
152
|
|
|
136
153
|
// Filter out already installed components
|
|
137
|
-
const pendingInstalls =
|
|
138
|
-
|
|
139
|
-
|
|
154
|
+
const pendingInstalls = beta
|
|
155
|
+
? Array.from(allComponentsToInstall)
|
|
156
|
+
: Array.from(allComponentsToInstall).filter(
|
|
157
|
+
(comp) => !checkComponentExists(comp, destPath),
|
|
158
|
+
);
|
|
140
159
|
|
|
141
160
|
if (pendingInstalls.length === 0) {
|
|
142
161
|
console.log(
|
|
@@ -149,7 +168,7 @@ const installMultipleComponents = async (components, destPath) => {
|
|
|
149
168
|
|
|
150
169
|
// Install all pending components
|
|
151
170
|
for (const comp of pendingInstalls) {
|
|
152
|
-
await copyComponent(comp, destPath);
|
|
171
|
+
await copyComponent(comp, destPath, beta);
|
|
153
172
|
}
|
|
154
173
|
|
|
155
174
|
// Show dependency information
|
|
@@ -169,7 +188,7 @@ const installMultipleComponents = async (components, destPath) => {
|
|
|
169
188
|
console.log(`\nFor documentation visit: ${CONFIG.docs}`);
|
|
170
189
|
};
|
|
171
190
|
|
|
172
|
-
const interactiveComponentSelector = async () => {
|
|
191
|
+
const interactiveComponentSelector = async (beta = false) => {
|
|
173
192
|
return new Promise((resolve) => {
|
|
174
193
|
const rl = readline.createInterface({
|
|
175
194
|
input: process.stdin,
|
|
@@ -186,7 +205,9 @@ const interactiveComponentSelector = async () => {
|
|
|
186
205
|
"Use ↑/↓ arrow keys to navigate, SPACE to select/deselect, ENTER to install\n",
|
|
187
206
|
);
|
|
188
207
|
|
|
189
|
-
|
|
208
|
+
const availableComponents = getAvailableComponents(beta);
|
|
209
|
+
|
|
210
|
+
availableComponents.forEach((component, index) => {
|
|
190
211
|
const isSelected = selectedComponents.has(component);
|
|
191
212
|
const isCurrentIndex = index === currentIndex;
|
|
192
213
|
const deps = CONFIG.dependencies[component]
|
|
@@ -216,13 +237,13 @@ const interactiveComponentSelector = async () => {
|
|
|
216
237
|
break;
|
|
217
238
|
case "\u001b[B": // Down arrow
|
|
218
239
|
currentIndex = Math.min(
|
|
219
|
-
|
|
240
|
+
getAvailableComponents(beta).length - 1,
|
|
220
241
|
currentIndex + 1,
|
|
221
242
|
);
|
|
222
243
|
renderMenu();
|
|
223
244
|
break;
|
|
224
245
|
case " ": // Space bar
|
|
225
|
-
const component =
|
|
246
|
+
const component = getAvailableComponents(beta)[currentIndex];
|
|
226
247
|
if (selectedComponents.has(component)) {
|
|
227
248
|
selectedComponents.delete(component);
|
|
228
249
|
} else {
|
|
@@ -265,21 +286,29 @@ const parseMultipleComponents = (componentString) => {
|
|
|
265
286
|
.filter((comp) => comp.length > 0);
|
|
266
287
|
};
|
|
267
288
|
|
|
268
|
-
const validateComponents = (components) => {
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
console.
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
289
|
+
const validateComponents = (components, beta = false) => {
|
|
290
|
+
const availableComponents = getAvailableComponents(beta);
|
|
291
|
+
const invalidComponents = components.filter(
|
|
292
|
+
(comp) => !availableComponents.includes(comp),
|
|
293
|
+
);
|
|
294
|
+
if (invalidComponents.length > 0) {
|
|
295
|
+
console.error(`Invalid components: ${invalidComponents.join(", ")}`);
|
|
296
|
+
console.log(`\nAvailable ${beta ? "beta " : ""}components:`);
|
|
297
|
+
availableComponents.forEach((comp) => console.log(`- ${comp}`));
|
|
298
|
+
if (!beta) {
|
|
299
|
+
console.log("\nRedesigned beta components (install with -beta):");
|
|
300
|
+
CONFIG.betaComponents.forEach((comp) => console.log(`- ${comp}`));
|
|
301
|
+
}
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const main = async () => {
|
|
308
|
+
const args = hideBin(process.argv).map((arg) =>
|
|
309
|
+
arg === "-beta" ? "--beta" : arg,
|
|
310
|
+
);
|
|
311
|
+
const argv = yargs(args)
|
|
283
312
|
.option("add", {
|
|
284
313
|
alias: "a",
|
|
285
314
|
describe:
|
|
@@ -291,32 +320,44 @@ const main = async () => {
|
|
|
291
320
|
describe: "Interactive component selection mode",
|
|
292
321
|
type: "boolean",
|
|
293
322
|
})
|
|
294
|
-
.option("list", {
|
|
295
|
-
alias: "l",
|
|
296
|
-
describe: "List available components",
|
|
297
|
-
type: "boolean",
|
|
298
|
-
})
|
|
299
|
-
.
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
.option("list", {
|
|
324
|
+
alias: "l",
|
|
325
|
+
describe: "List available components",
|
|
326
|
+
type: "boolean",
|
|
327
|
+
})
|
|
328
|
+
.option("beta", {
|
|
329
|
+
describe: "Install redesigned beta components",
|
|
330
|
+
type: "boolean",
|
|
331
|
+
default: false,
|
|
332
|
+
})
|
|
333
|
+
.example("$0 -a Button", "Install a single component")
|
|
334
|
+
.example("$0 -a Button,Card,Modal", "Install multiple components")
|
|
335
|
+
.example("$0 -a DataGrid -beta", "Install the redesigned beta DataGrid")
|
|
336
|
+
.example("$0 -a Combobox -beta", "Install the redesigned beta Combobox")
|
|
337
|
+
.example("$0 -i", "Interactive selection mode")
|
|
302
338
|
.help().argv;
|
|
303
339
|
|
|
304
|
-
// List components if requested
|
|
305
|
-
if (argv.list) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
: ""
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
340
|
+
// List components if requested
|
|
341
|
+
if (argv.list) {
|
|
342
|
+
const availableComponents = getAvailableComponents(argv.beta);
|
|
343
|
+
console.log(`\nAvailable ${argv.beta ? "beta " : ""}components:`);
|
|
344
|
+
availableComponents.forEach((comp) => {
|
|
345
|
+
const deps = CONFIG.dependencies[comp]
|
|
346
|
+
? ` (requires: ${CONFIG.dependencies[comp].join(", ")})`
|
|
347
|
+
: "";
|
|
348
|
+
console.log(`- ${comp}${deps}`);
|
|
349
|
+
});
|
|
350
|
+
if (!argv.beta) {
|
|
351
|
+
console.log("\nRedesigned beta components (install with -beta):");
|
|
352
|
+
CONFIG.betaComponents.forEach((comp) => console.log(`- ${comp}`));
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
315
356
|
|
|
316
357
|
// Interactive mode
|
|
317
|
-
if (argv.interactive) {
|
|
318
|
-
console.log("Starting interactive component selector...\n");
|
|
319
|
-
const selectedComponents = await interactiveComponentSelector();
|
|
358
|
+
if (argv.interactive) {
|
|
359
|
+
console.log("Starting interactive component selector...\n");
|
|
360
|
+
const selectedComponents = await interactiveComponentSelector(argv.beta);
|
|
320
361
|
|
|
321
362
|
if (selectedComponents.length === 0) {
|
|
322
363
|
console.log("No components selected. Exiting...");
|
|
@@ -332,8 +373,8 @@ const main = async () => {
|
|
|
332
373
|
await copyCommonFiles(destPath);
|
|
333
374
|
}
|
|
334
375
|
|
|
335
|
-
// Install selected components
|
|
336
|
-
await installMultipleComponents(selectedComponents, destPath);
|
|
376
|
+
// Install selected components
|
|
377
|
+
await installMultipleComponents(selectedComponents, destPath, argv.beta);
|
|
337
378
|
return;
|
|
338
379
|
}
|
|
339
380
|
|
|
@@ -344,12 +385,14 @@ const main = async () => {
|
|
|
344
385
|
process.exit(1);
|
|
345
386
|
}
|
|
346
387
|
|
|
347
|
-
// Parse components (single or multiple)
|
|
348
|
-
const componentInput = argv.add;
|
|
349
|
-
const components = parseMultipleComponents(componentInput)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
388
|
+
// Parse components (single or multiple)
|
|
389
|
+
const componentInput = argv.add;
|
|
390
|
+
const components = parseMultipleComponents(componentInput).map((component) =>
|
|
391
|
+
normalizeComponent(component, getAvailableComponents(argv.beta)) || component,
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
// Validate all components
|
|
395
|
+
if (!validateComponents(components, argv.beta)) {
|
|
353
396
|
process.exit(1);
|
|
354
397
|
}
|
|
355
398
|
|
|
@@ -363,14 +406,14 @@ const main = async () => {
|
|
|
363
406
|
}
|
|
364
407
|
|
|
365
408
|
// Install components
|
|
366
|
-
if (components.length === 1) {
|
|
367
|
-
// Single component installation (existing behavior)
|
|
368
|
-
await installComponentWithDependencies(components[0], destPath);
|
|
369
|
-
} else {
|
|
370
|
-
// Multiple components installation
|
|
371
|
-
await installMultipleComponents(components, destPath);
|
|
372
|
-
}
|
|
373
|
-
};
|
|
409
|
+
if (components.length === 1) {
|
|
410
|
+
// Single component installation (existing behavior)
|
|
411
|
+
await installComponentWithDependencies(components[0], destPath, argv.beta);
|
|
412
|
+
} else {
|
|
413
|
+
// Multiple components installation
|
|
414
|
+
await installMultipleComponents(components, destPath, argv.beta);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
374
417
|
|
|
375
418
|
main().catch((error) => {
|
|
376
419
|
console.error("Error:", error.message);
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/source/{components/datagridbeta → beta-components/datagrid}/__tests__/export.test.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|