@noctuatech/uswds 1.4.8 → 1.5.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.
- package/package.json +5 -5
- package/src/lib/file-input/file-input.element.test.ts +46 -0
- package/src/lib/file-input/file-input.element.ts +53 -2
- package/src/lib/file-input/file-input.stories.ts +28 -0
- package/src/lib/file-input/filename.test.ts +28 -0
- package/src/lib/file-input/filename.ts +50 -0
- package/target/lib/file-input/file-input.element.d.ts +4 -0
- package/target/lib/file-input/file-input.element.js +51 -7
- package/target/lib/file-input/file-input.element.js.map +1 -1
- package/target/lib/file-input/file-input.element.test.js +33 -0
- package/target/lib/file-input/file-input.element.test.js.map +1 -1
- package/target/lib/file-input/file-input.stories.d.ts +1 -0
- package/target/lib/file-input/file-input.stories.js +11 -0
- package/target/lib/file-input/file-input.stories.js.map +1 -1
- package/target/lib/file-input/filename.d.ts +5 -0
- package/target/lib/file-input/filename.js +39 -0
- package/target/lib/file-input/filename.js.map +1 -0
- package/target/lib/file-input/filename.test.d.ts +1 -0
- package/target/lib/file-input/filename.test.js +23 -0
- package/target/lib/file-input/filename.test.js.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noctuatech/uswds",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"packages/**"
|
|
@@ -112,10 +112,10 @@
|
|
|
112
112
|
},
|
|
113
113
|
"devDependencies": {
|
|
114
114
|
"@11ty/eleventy": "^3.0.0",
|
|
115
|
-
"@chromatic-com/storybook": "^4.1.
|
|
115
|
+
"@chromatic-com/storybook": "^4.1.3",
|
|
116
116
|
"@open-wc/testing": "^4.0.0",
|
|
117
|
-
"@storybook/addon-docs": "^10.
|
|
118
|
-
"@storybook/web-components-vite": "^10.
|
|
117
|
+
"@storybook/addon-docs": "^10.1.11",
|
|
118
|
+
"@storybook/web-components-vite": "^10.1.11",
|
|
119
119
|
"@testing-library/dom": "^10.4.0",
|
|
120
120
|
"@testing-library/user-event": "^14.6.1",
|
|
121
121
|
"@types/mocha": "^10.0.7",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"mocha": "^11.0.0",
|
|
132
132
|
"plop": "^4.0.1",
|
|
133
133
|
"prettier": "^3.5.3",
|
|
134
|
-
"storybook": "^10.
|
|
134
|
+
"storybook": "^10.1.11",
|
|
135
135
|
"typescript": "^5.8.0",
|
|
136
136
|
"wireit": "^0.14.9"
|
|
137
137
|
},
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import './file-input.element.js';
|
|
2
2
|
|
|
3
3
|
import { assert, fixture, html } from '@open-wc/testing';
|
|
4
|
+
import { DOMInjector } from '@joist/di';
|
|
4
5
|
|
|
5
6
|
import type { USAFileInputElement } from './file-input.element.js';
|
|
7
|
+
import { HttpService } from '../services/http.service.js';
|
|
6
8
|
|
|
7
9
|
describe('usa-file-input', () => {
|
|
8
10
|
it('should be accessible', async () => {
|
|
@@ -231,4 +233,48 @@ describe('usa-file-input', () => {
|
|
|
231
233
|
assert.equal(fileInput.files?.length, 1);
|
|
232
234
|
assert.equal(fileInput.files?.[0].name, 'existing.txt');
|
|
233
235
|
});
|
|
236
|
+
|
|
237
|
+
it('should load file from url and set files', async () => {
|
|
238
|
+
class MockHttpService extends HttpService {
|
|
239
|
+
async fetch(url: string): Promise<Response> {
|
|
240
|
+
const file = new File(['file contents'], 'test-file.txt', { type: 'text/plain' });
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
ok: true,
|
|
244
|
+
status: 200,
|
|
245
|
+
blob: async () => file,
|
|
246
|
+
url,
|
|
247
|
+
headers: new Headers({
|
|
248
|
+
'Content-Disposition': 'attachment; filename="test-file.txt"',
|
|
249
|
+
}),
|
|
250
|
+
} as any;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const root = new DOMInjector({
|
|
255
|
+
providers: [[HttpService, { use: MockHttpService }]],
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
root.attach(document.body);
|
|
259
|
+
|
|
260
|
+
const fileInput = await fixture<USAFileInputElement>(html`<usa-file-input></usa-file-input>`);
|
|
261
|
+
|
|
262
|
+
fileInput.url = 'https://example.com/path/to/test-file.txt';
|
|
263
|
+
|
|
264
|
+
return new Promise((resolve) => {
|
|
265
|
+
fileInput.addEventListener(
|
|
266
|
+
'input',
|
|
267
|
+
() => {
|
|
268
|
+
assert.equal(fileInput.files?.length, 1);
|
|
269
|
+
assert.equal(fileInput.files?.[0].name, 'test-file.txt');
|
|
270
|
+
assert.equal(fileInput.files?.[0].type, 'text/plain');
|
|
271
|
+
|
|
272
|
+
root.detach();
|
|
273
|
+
|
|
274
|
+
resolve();
|
|
275
|
+
},
|
|
276
|
+
{ once: true },
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
234
280
|
});
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import '../templating.js';
|
|
2
2
|
|
|
3
|
+
import { inject, injectable } from '@joist/di';
|
|
3
4
|
import { attr, css, element, html, listen, query } from '@joist/element';
|
|
4
|
-
import { effect } from '@joist/observable';
|
|
5
|
+
import { Changes, effect } from '@joist/observable';
|
|
5
6
|
import { bind } from '@joist/templating';
|
|
6
7
|
|
|
8
|
+
import { HttpService } from '../services/http.service.js';
|
|
9
|
+
import { filenameFromResponse } from './filename.js';
|
|
10
|
+
|
|
7
11
|
declare global {
|
|
8
12
|
interface HTMLElementTagNameMap {
|
|
9
13
|
'usa-file-input': USAFileInputElement;
|
|
10
14
|
}
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
@injectable({
|
|
18
|
+
name: 'USAFileInputElementCtx',
|
|
19
|
+
})
|
|
13
20
|
@element({
|
|
14
21
|
tagName: 'usa-file-input',
|
|
15
22
|
shadowDom: [
|
|
@@ -95,7 +102,7 @@ declare global {
|
|
|
95
102
|
</usa-bind>
|
|
96
103
|
</template>
|
|
97
104
|
|
|
98
|
-
<template
|
|
105
|
+
<template else>
|
|
99
106
|
<div class="box" part="input">
|
|
100
107
|
<slot name="description"> Drag file here or <usa-link>choose from folder</usa-link> </slot>
|
|
101
108
|
</div>
|
|
@@ -120,6 +127,10 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
120
127
|
@bind()
|
|
121
128
|
accessor accept = '';
|
|
122
129
|
|
|
130
|
+
@attr()
|
|
131
|
+
@bind()
|
|
132
|
+
accessor url = '';
|
|
133
|
+
|
|
123
134
|
@attr()
|
|
124
135
|
@bind()
|
|
125
136
|
accessor required = false;
|
|
@@ -127,14 +138,29 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
127
138
|
@bind()
|
|
128
139
|
accessor files: FileList | null = null;
|
|
129
140
|
|
|
141
|
+
#http = inject(HttpService);
|
|
130
142
|
#internals = this.attachInternals();
|
|
131
143
|
#input = query('input');
|
|
132
144
|
|
|
133
145
|
connectedCallback() {
|
|
134
146
|
this.syncFormValues();
|
|
147
|
+
this.#loadFromUrl();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@effect()
|
|
151
|
+
async onURLChanged(changes: Changes<this>) {
|
|
152
|
+
if (changes.has('url')) {
|
|
153
|
+
this.#loadFromUrl();
|
|
154
|
+
}
|
|
135
155
|
}
|
|
136
156
|
|
|
137
157
|
@effect()
|
|
158
|
+
async formValuesChange(changes: Changes<this>) {
|
|
159
|
+
if (changes.has('files') || changes.has('name')) {
|
|
160
|
+
this.syncFormValues();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
138
164
|
async syncFormValues() {
|
|
139
165
|
const input = this.#input();
|
|
140
166
|
|
|
@@ -236,4 +262,29 @@ export class USAFileInputElement extends HTMLElement {
|
|
|
236
262
|
|
|
237
263
|
return false;
|
|
238
264
|
}
|
|
265
|
+
|
|
266
|
+
async #loadFromUrl(): Promise<void> {
|
|
267
|
+
if (!this.url) {
|
|
268
|
+
return void 0;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const http = this.#http();
|
|
272
|
+
|
|
273
|
+
const res = await http.fetch(this.url);
|
|
274
|
+
const blob = await res.blob();
|
|
275
|
+
|
|
276
|
+
// Determine filename from Content-Disposition header when available
|
|
277
|
+
const filename = filenameFromResponse(res);
|
|
278
|
+
|
|
279
|
+
const file = new File([blob], filename, { type: blob.type });
|
|
280
|
+
|
|
281
|
+
const dataTransfer = new DataTransfer();
|
|
282
|
+
dataTransfer.items.add(file);
|
|
283
|
+
|
|
284
|
+
this.files = dataTransfer.files;
|
|
285
|
+
|
|
286
|
+
this.dispatchEvent(new Event('input'));
|
|
287
|
+
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
239
290
|
}
|
|
@@ -66,3 +66,31 @@ export const Multiple: Story = {
|
|
|
66
66
|
`;
|
|
67
67
|
},
|
|
68
68
|
};
|
|
69
|
+
|
|
70
|
+
export const LoadFromURL: Story = {
|
|
71
|
+
args: {},
|
|
72
|
+
render() {
|
|
73
|
+
function onSubmit(e: Event) {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
|
|
76
|
+
const data = new FormData(e.target as HTMLFormElement);
|
|
77
|
+
|
|
78
|
+
console.log(data.getAll('upload'));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return html`
|
|
82
|
+
<form @submit=${onSubmit}>
|
|
83
|
+
<usa-file-input
|
|
84
|
+
name="upload"
|
|
85
|
+
url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREt3ngNcixKZcTbJp3-Zyiovb18MKb7OWz4A&s"
|
|
86
|
+
>
|
|
87
|
+
Input loads default from URL
|
|
88
|
+
|
|
89
|
+
<div slot="description">Drag file here or <usa-link>choose from folder</usa-link></div>
|
|
90
|
+
</usa-file-input>
|
|
91
|
+
|
|
92
|
+
<usa-button type="submit">SUBMIT</usa-button>
|
|
93
|
+
</form>
|
|
94
|
+
`;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { assert } from '@open-wc/testing';
|
|
2
|
+
|
|
3
|
+
import { filenameFromResponse } from './filename.js';
|
|
4
|
+
|
|
5
|
+
describe('filenameFromResponse', () => {
|
|
6
|
+
it('parses filename* with charset and percent-encoding from a Response', () => {
|
|
7
|
+
const res = new Response(null, {
|
|
8
|
+
headers: { 'content-disposition': "attachment; filename*=UTF-8''photo%20new.jpg" },
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
assert.equal(filenameFromResponse(res), 'photo new.jpg');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('parses quoted filename from a Response', () => {
|
|
15
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; filename="photo.jpg"' } });
|
|
16
|
+
assert.equal(filenameFromResponse(res), 'photo.jpg');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('parses unquoted filename from a Response', () => {
|
|
20
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; filename=photo.jpg' } });
|
|
21
|
+
assert.equal(filenameFromResponse(res), 'photo.jpg');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns fallback when no filename present in Response', () => {
|
|
25
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; foo=bar' } });
|
|
26
|
+
assert.equal(filenameFromResponse(res), 'downloaded-file');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a filename from a Response's Content-Disposition header.
|
|
3
|
+
* Returns the filename string if found, otherwise null.
|
|
4
|
+
*/
|
|
5
|
+
export function filenameFromResponse(response: Response): string {
|
|
6
|
+
const contentDisposition = response.headers.get('content-disposition');
|
|
7
|
+
// Use a safe fallback if the response URL doesn't contain a filename (handles empty string)
|
|
8
|
+
|
|
9
|
+
let url: URL | null = null;
|
|
10
|
+
|
|
11
|
+
if (response.url) {
|
|
12
|
+
url = new URL(response.url);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const fallback = url?.pathname.split('/').pop() || 'downloaded-file';
|
|
16
|
+
|
|
17
|
+
if (!contentDisposition) {
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Try RFC 5987 filename* (e.g., filename*=UTF-8''file.jpg)
|
|
22
|
+
const filenameStarMatch = contentDisposition.match(/filename\*\s*=\s*([^;]+)/i);
|
|
23
|
+
|
|
24
|
+
if (filenameStarMatch) {
|
|
25
|
+
try {
|
|
26
|
+
let value = filenameStarMatch[1].trim().replace(/^"|"$/g, '');
|
|
27
|
+
|
|
28
|
+
// Strip optional charset'lang' prefix (e.g., UTF-8''file.jpg)
|
|
29
|
+
const starParts = value.split("''");
|
|
30
|
+
|
|
31
|
+
if (starParts.length === 2) {
|
|
32
|
+
value = starParts[1];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return decodeURIComponent(value);
|
|
36
|
+
} catch (_e) {
|
|
37
|
+
return fallback;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Try simple filename="file.jpg" or filename=file.jpg
|
|
42
|
+
const filenameMatch =
|
|
43
|
+
contentDisposition.match(/filename\s*=\s*"([^"]+)"/i) || contentDisposition.match(/filename\s*=\s*([^;]+)/i);
|
|
44
|
+
|
|
45
|
+
if (filenameMatch) {
|
|
46
|
+
return filenameMatch[1].trim().replace(/^"|"$/g, '');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import '../templating.js';
|
|
2
|
+
import { Changes } from '@joist/observable';
|
|
2
3
|
declare global {
|
|
3
4
|
interface HTMLElementTagNameMap {
|
|
4
5
|
'usa-file-input': USAFileInputElement;
|
|
@@ -10,9 +11,12 @@ export declare class USAFileInputElement extends HTMLElement {
|
|
|
10
11
|
accessor name: string;
|
|
11
12
|
accessor multiple: boolean;
|
|
12
13
|
accessor accept: string;
|
|
14
|
+
accessor url: string;
|
|
13
15
|
accessor required: boolean;
|
|
14
16
|
accessor files: FileList | null;
|
|
15
17
|
connectedCallback(): void;
|
|
18
|
+
onURLChanged(changes: Changes<this>): Promise<void>;
|
|
19
|
+
formValuesChange(changes: Changes<this>): Promise<void>;
|
|
16
20
|
syncFormValues(): Promise<void>;
|
|
17
21
|
onInputChange(e: Event): void;
|
|
18
22
|
onDragEnter(): void;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { __esDecorate, __runInitializers } from "tslib";
|
|
2
2
|
import '../templating.js';
|
|
3
|
+
import { inject, injectable } from '@joist/di';
|
|
3
4
|
import { attr, css, element, html, listen, query } from '@joist/element';
|
|
4
5
|
import { effect } from '@joist/observable';
|
|
5
6
|
import { bind } from '@joist/templating';
|
|
7
|
+
import { HttpService } from '../services/http.service.js';
|
|
8
|
+
import { filenameFromResponse } from './filename.js';
|
|
6
9
|
let USAFileInputElement = (() => {
|
|
7
|
-
let _classDecorators = [
|
|
10
|
+
let _classDecorators = [injectable({
|
|
11
|
+
name: 'USAFileInputElementCtx',
|
|
12
|
+
}), element({
|
|
8
13
|
tagName: 'usa-file-input',
|
|
9
14
|
shadowDom: [
|
|
10
15
|
css `*{box-sizing:border-box}:host{display:block;max-width:30rem;position:relative;margin-bottom:1.5rem}label{display:block}input{cursor:pointer;left:0;margin:0;max-width:none;position:absolute;text-indent:-999em;width:100%;z-index:1;bottom:0;top:0}input:focus{outline:.25rem solid #2491ff;outline-offset:0}label slot.label{font-size:1.06rem;line-height:1.3;display:block;font-weight:400;margin-bottom:.5rem}:host(.dragenter) .box{border-color:#2491ff}.box{border:1px dashed #adadad;border-radius:0;display:flex;font-size:.93rem;position:relative;text-align:center;width:100%;height:5.2rem;align-items:center;justify-content:center}.container{position:relative}`,
|
|
11
|
-
html `<label for="file-input"><slot class="label"></slot></label><div class="container"><usa-bind props="name,multiple,accept,required,files"><input id="file-input" type="file" tabindex="0"></usa-bind><usa-if bind="files.length"><template><usa-bind props="files"><usa-file-input-preview part="preview" exportparts="heading, item">Selected file <usa-link>Change file</usa-link></usa-file-input-preview></usa-bind></template><template
|
|
16
|
+
html `<label for="file-input"><slot class="label"></slot></label><div class="container"><usa-bind props="name,multiple,accept,required,files"><input id="file-input" type="file" tabindex="0"></usa-bind><usa-if bind="files.length"><template><usa-bind props="files"><usa-file-input-preview part="preview" exportparts="heading, item">Selected file <usa-link>Change file</usa-link></usa-file-input-preview></usa-bind></template><template else><div class="box" part="input"><slot name="description">Drag file here or<usa-link>choose from folder</usa-link></slot></div></template></usa-if></div>`,
|
|
12
17
|
],
|
|
13
18
|
})];
|
|
14
19
|
let _classDescriptor;
|
|
@@ -25,13 +30,17 @@ let USAFileInputElement = (() => {
|
|
|
25
30
|
let _accept_decorators;
|
|
26
31
|
let _accept_initializers = [];
|
|
27
32
|
let _accept_extraInitializers = [];
|
|
33
|
+
let _url_decorators;
|
|
34
|
+
let _url_initializers = [];
|
|
35
|
+
let _url_extraInitializers = [];
|
|
28
36
|
let _required_decorators;
|
|
29
37
|
let _required_initializers = [];
|
|
30
38
|
let _required_extraInitializers = [];
|
|
31
39
|
let _files_decorators;
|
|
32
40
|
let _files_initializers = [];
|
|
33
41
|
let _files_extraInitializers = [];
|
|
34
|
-
let
|
|
42
|
+
let _onURLChanged_decorators;
|
|
43
|
+
let _formValuesChange_decorators;
|
|
35
44
|
let _onInputChange_decorators;
|
|
36
45
|
let _onDragEnter_decorators;
|
|
37
46
|
let _onDragLeave_decorators;
|
|
@@ -43,9 +52,11 @@ let USAFileInputElement = (() => {
|
|
|
43
52
|
_name_decorators = [attr(), bind()];
|
|
44
53
|
_multiple_decorators = [attr(), bind()];
|
|
45
54
|
_accept_decorators = [attr(), bind()];
|
|
55
|
+
_url_decorators = [attr(), bind()];
|
|
46
56
|
_required_decorators = [attr(), bind()];
|
|
47
57
|
_files_decorators = [bind()];
|
|
48
|
-
|
|
58
|
+
_onURLChanged_decorators = [effect()];
|
|
59
|
+
_formValuesChange_decorators = [effect()];
|
|
49
60
|
_onInputChange_decorators = [listen('input')];
|
|
50
61
|
_onDragEnter_decorators = [listen('dragenter')];
|
|
51
62
|
_onDragLeave_decorators = [listen('dragleave')];
|
|
@@ -53,9 +64,11 @@ let USAFileInputElement = (() => {
|
|
|
53
64
|
__esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
|
|
54
65
|
__esDecorate(this, null, _multiple_decorators, { kind: "accessor", name: "multiple", static: false, private: false, access: { has: obj => "multiple" in obj, get: obj => obj.multiple, set: (obj, value) => { obj.multiple = value; } }, metadata: _metadata }, _multiple_initializers, _multiple_extraInitializers);
|
|
55
66
|
__esDecorate(this, null, _accept_decorators, { kind: "accessor", name: "accept", static: false, private: false, access: { has: obj => "accept" in obj, get: obj => obj.accept, set: (obj, value) => { obj.accept = value; } }, metadata: _metadata }, _accept_initializers, _accept_extraInitializers);
|
|
67
|
+
__esDecorate(this, null, _url_decorators, { kind: "accessor", name: "url", static: false, private: false, access: { has: obj => "url" in obj, get: obj => obj.url, set: (obj, value) => { obj.url = value; } }, metadata: _metadata }, _url_initializers, _url_extraInitializers);
|
|
56
68
|
__esDecorate(this, null, _required_decorators, { kind: "accessor", name: "required", static: false, private: false, access: { has: obj => "required" in obj, get: obj => obj.required, set: (obj, value) => { obj.required = value; } }, metadata: _metadata }, _required_initializers, _required_extraInitializers);
|
|
57
69
|
__esDecorate(this, null, _files_decorators, { kind: "accessor", name: "files", static: false, private: false, access: { has: obj => "files" in obj, get: obj => obj.files, set: (obj, value) => { obj.files = value; } }, metadata: _metadata }, _files_initializers, _files_extraInitializers);
|
|
58
|
-
__esDecorate(this, null,
|
|
70
|
+
__esDecorate(this, null, _onURLChanged_decorators, { kind: "method", name: "onURLChanged", static: false, private: false, access: { has: obj => "onURLChanged" in obj, get: obj => obj.onURLChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
71
|
+
__esDecorate(this, null, _formValuesChange_decorators, { kind: "method", name: "formValuesChange", static: false, private: false, access: { has: obj => "formValuesChange" in obj, get: obj => obj.formValuesChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
59
72
|
__esDecorate(this, null, _onInputChange_decorators, { kind: "method", name: "onInputChange", static: false, private: false, access: { has: obj => "onInputChange" in obj, get: obj => obj.onInputChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
60
73
|
__esDecorate(this, null, _onDragEnter_decorators, { kind: "method", name: "onDragEnter", static: false, private: false, access: { has: obj => "onDragEnter" in obj, get: obj => obj.onDragEnter }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
61
74
|
__esDecorate(this, null, _onDragLeave_decorators, { kind: "method", name: "onDragLeave", static: false, private: false, access: { has: obj => "onDragLeave" in obj, get: obj => obj.onDragLeave }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -74,16 +87,31 @@ let USAFileInputElement = (() => {
|
|
|
74
87
|
#accept_accessor_storage = (__runInitializers(this, _multiple_extraInitializers), __runInitializers(this, _accept_initializers, ''));
|
|
75
88
|
get accept() { return this.#accept_accessor_storage; }
|
|
76
89
|
set accept(value) { this.#accept_accessor_storage = value; }
|
|
77
|
-
#
|
|
90
|
+
#url_accessor_storage = (__runInitializers(this, _accept_extraInitializers), __runInitializers(this, _url_initializers, ''));
|
|
91
|
+
get url() { return this.#url_accessor_storage; }
|
|
92
|
+
set url(value) { this.#url_accessor_storage = value; }
|
|
93
|
+
#required_accessor_storage = (__runInitializers(this, _url_extraInitializers), __runInitializers(this, _required_initializers, false));
|
|
78
94
|
get required() { return this.#required_accessor_storage; }
|
|
79
95
|
set required(value) { this.#required_accessor_storage = value; }
|
|
80
96
|
#files_accessor_storage = (__runInitializers(this, _required_extraInitializers), __runInitializers(this, _files_initializers, null));
|
|
81
97
|
get files() { return this.#files_accessor_storage; }
|
|
82
98
|
set files(value) { this.#files_accessor_storage = value; }
|
|
83
|
-
#
|
|
99
|
+
#http = (__runInitializers(this, _files_extraInitializers), inject(HttpService));
|
|
100
|
+
#internals = this.attachInternals();
|
|
84
101
|
#input = query('input');
|
|
85
102
|
connectedCallback() {
|
|
86
103
|
this.syncFormValues();
|
|
104
|
+
this.#loadFromUrl();
|
|
105
|
+
}
|
|
106
|
+
async onURLChanged(changes) {
|
|
107
|
+
if (changes.has('url')) {
|
|
108
|
+
this.#loadFromUrl();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async formValuesChange(changes) {
|
|
112
|
+
if (changes.has('files') || changes.has('name')) {
|
|
113
|
+
this.syncFormValues();
|
|
114
|
+
}
|
|
87
115
|
}
|
|
88
116
|
async syncFormValues() {
|
|
89
117
|
const input = this.#input();
|
|
@@ -160,6 +188,22 @@ let USAFileInputElement = (() => {
|
|
|
160
188
|
}
|
|
161
189
|
return false;
|
|
162
190
|
}
|
|
191
|
+
async #loadFromUrl() {
|
|
192
|
+
if (!this.url) {
|
|
193
|
+
return void 0;
|
|
194
|
+
}
|
|
195
|
+
const http = this.#http();
|
|
196
|
+
const res = await http.fetch(this.url);
|
|
197
|
+
const blob = await res.blob();
|
|
198
|
+
// Determine filename from Content-Disposition header when available
|
|
199
|
+
const filename = filenameFromResponse(res);
|
|
200
|
+
const file = new File([blob], filename, { type: blob.type });
|
|
201
|
+
const dataTransfer = new DataTransfer();
|
|
202
|
+
dataTransfer.items.add(file);
|
|
203
|
+
this.files = dataTransfer.files;
|
|
204
|
+
this.dispatchEvent(new Event('input'));
|
|
205
|
+
return void 0;
|
|
206
|
+
}
|
|
163
207
|
static {
|
|
164
208
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
165
209
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input.element.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.ts"],"names":[],"mappings":";AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"file-input.element.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import './file-input.element.js';
|
|
2
2
|
import { assert, fixture, html } from '@open-wc/testing';
|
|
3
|
+
import { DOMInjector } from '@joist/di';
|
|
4
|
+
import { HttpService } from '../services/http.service.js';
|
|
3
5
|
describe('usa-file-input', () => {
|
|
4
6
|
it('should be accessible', async () => {
|
|
5
7
|
const fileInput = await fixture(html `<usa-file-input>Hello World</usa-file-input>`);
|
|
@@ -147,5 +149,36 @@ describe('usa-file-input', () => {
|
|
|
147
149
|
assert.equal(fileInput.files?.length, 1);
|
|
148
150
|
assert.equal(fileInput.files?.[0].name, 'existing.txt');
|
|
149
151
|
});
|
|
152
|
+
it('should load file from url and set files', async () => {
|
|
153
|
+
class MockHttpService extends HttpService {
|
|
154
|
+
async fetch(url) {
|
|
155
|
+
const file = new File(['file contents'], 'test-file.txt', { type: 'text/plain' });
|
|
156
|
+
return {
|
|
157
|
+
ok: true,
|
|
158
|
+
status: 200,
|
|
159
|
+
blob: async () => file,
|
|
160
|
+
url,
|
|
161
|
+
headers: new Headers({
|
|
162
|
+
'Content-Disposition': 'attachment; filename="test-file.txt"',
|
|
163
|
+
}),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const root = new DOMInjector({
|
|
168
|
+
providers: [[HttpService, { use: MockHttpService }]],
|
|
169
|
+
});
|
|
170
|
+
root.attach(document.body);
|
|
171
|
+
const fileInput = await fixture(html `<usa-file-input></usa-file-input>`);
|
|
172
|
+
fileInput.url = 'https://example.com/path/to/test-file.txt';
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
fileInput.addEventListener('input', () => {
|
|
175
|
+
assert.equal(fileInput.files?.length, 1);
|
|
176
|
+
assert.equal(fileInput.files?.[0].name, 'test-file.txt');
|
|
177
|
+
assert.equal(fileInput.files?.[0].type, 'text/plain');
|
|
178
|
+
root.detach();
|
|
179
|
+
resolve();
|
|
180
|
+
}, { once: true });
|
|
181
|
+
});
|
|
182
|
+
});
|
|
150
183
|
});
|
|
151
184
|
//# sourceMappingURL=file-input.element.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input.element.test.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.test.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-input.element.test.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.element.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,4 +30,15 @@ export const Multiple = {
|
|
|
30
30
|
return html `<form @submit="${onSubmit}"><usa-file-input name="upload" required multiple="multiple">Input accepts multiple files<div slot="description">Drag file here or<usa-link>choose from folder</usa-link></div></usa-file-input><usa-button type="submit">SUBMIT</usa-button></form>`;
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
|
+
export const LoadFromURL = {
|
|
34
|
+
args: {},
|
|
35
|
+
render() {
|
|
36
|
+
function onSubmit(e) {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
const data = new FormData(e.target);
|
|
39
|
+
console.log(data.getAll('upload'));
|
|
40
|
+
}
|
|
41
|
+
return html `<form @submit="${onSubmit}"><usa-file-input name="upload" url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREt3ngNcixKZcTbJp3-Zyiovb18MKb7OWz4A&s">Input loads default from URL<div slot="description">Drag file here or<usa-link>choose from folder</usa-link></div></usa-file-input><usa-button type="submit">SUBMIT</usa-button></form>`;
|
|
42
|
+
},
|
|
43
|
+
};
|
|
33
44
|
//# sourceMappingURL=file-input.stories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-input.stories.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAI3B,kFAAkF;AAClF,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,gBAAgB;IACvB,IAAI,EAAE,CAAC,UAAU,CAAC;IAElB,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;CAC2B,CAAC;AAEtC,eAAe,IAAI,CAAC;AAIpB,wFAAwF;AACxF,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE,EAAE;IACR,MAAM;QACJ,SAAS,QAAQ,CAAC,CAAQ;YACxB,CAAC,CAAC,cAAc,EAAE,CAAC;YAEnB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAyB,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAA;sBACO,QAAQ;;;;;;;;;KASzB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE,EAAE;IACR,MAAM;QACJ,SAAS,QAAQ,CAAC,CAAQ;YACxB,CAAC,CAAC,cAAc,EAAE,CAAC;YAEnB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAyB,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAA;sBACO,QAAQ;;;;;;;;;KASzB,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"file-input.stories.js","sourceRoot":"","sources":["../../../src/lib/file-input/file-input.stories.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAI3B,kFAAkF;AAClF,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,gBAAgB;IACvB,IAAI,EAAE,CAAC,UAAU,CAAC;IAElB,QAAQ,EAAE,EAAE;IACZ,IAAI,EAAE,EAAE;CAC2B,CAAC;AAEtC,eAAe,IAAI,CAAC;AAIpB,wFAAwF;AACxF,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE,EAAE;IACR,MAAM;QACJ,SAAS,QAAQ,CAAC,CAAQ;YACxB,CAAC,CAAC,cAAc,EAAE,CAAC;YAEnB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAyB,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAA;sBACO,QAAQ;;;;;;;;;KASzB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE,EAAE;IACR,MAAM;QACJ,SAAS,QAAQ,CAAC,CAAQ;YACxB,CAAC,CAAC,cAAc,EAAE,CAAC;YAEnB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAyB,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAA;sBACO,QAAQ;;;;;;;;;KASzB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAU;IAChC,IAAI,EAAE,EAAE;IACR,MAAM;QACJ,SAAS,QAAQ,CAAC,CAAQ;YACxB,CAAC,CAAC,cAAc,EAAE,CAAC;YAEnB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAyB,CAAC,CAAC;YAEvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAA;sBACO,QAAQ;;;;;;;;;;;;KAYzB,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts a filename from a Response's Content-Disposition header.
|
|
3
|
+
* Returns the filename string if found, otherwise null.
|
|
4
|
+
*/
|
|
5
|
+
export function filenameFromResponse(response) {
|
|
6
|
+
const contentDisposition = response.headers.get('content-disposition');
|
|
7
|
+
// Use a safe fallback if the response URL doesn't contain a filename (handles empty string)
|
|
8
|
+
let url = null;
|
|
9
|
+
if (response.url) {
|
|
10
|
+
url = new URL(response.url);
|
|
11
|
+
}
|
|
12
|
+
const fallback = url?.pathname.split('/').pop() || 'downloaded-file';
|
|
13
|
+
if (!contentDisposition) {
|
|
14
|
+
return fallback;
|
|
15
|
+
}
|
|
16
|
+
// Try RFC 5987 filename* (e.g., filename*=UTF-8''file.jpg)
|
|
17
|
+
const filenameStarMatch = contentDisposition.match(/filename\*\s*=\s*([^;]+)/i);
|
|
18
|
+
if (filenameStarMatch) {
|
|
19
|
+
try {
|
|
20
|
+
let value = filenameStarMatch[1].trim().replace(/^"|"$/g, '');
|
|
21
|
+
// Strip optional charset'lang' prefix (e.g., UTF-8''file.jpg)
|
|
22
|
+
const starParts = value.split("''");
|
|
23
|
+
if (starParts.length === 2) {
|
|
24
|
+
value = starParts[1];
|
|
25
|
+
}
|
|
26
|
+
return decodeURIComponent(value);
|
|
27
|
+
}
|
|
28
|
+
catch (_e) {
|
|
29
|
+
return fallback;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Try simple filename="file.jpg" or filename=file.jpg
|
|
33
|
+
const filenameMatch = contentDisposition.match(/filename\s*=\s*"([^"]+)"/i) || contentDisposition.match(/filename\s*=\s*([^;]+)/i);
|
|
34
|
+
if (filenameMatch) {
|
|
35
|
+
return filenameMatch[1].trim().replace(/^"|"$/g, '');
|
|
36
|
+
}
|
|
37
|
+
return fallback;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=filename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename.js","sourceRoot":"","sources":["../../../src/lib/file-input/filename.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAkB;IACrD,MAAM,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACvE,4FAA4F;IAE5F,IAAI,GAAG,GAAe,IAAI,CAAC;IAE3B,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;QACjB,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,iBAAiB,CAAC;IAErE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,2DAA2D;IAC3D,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAEhF,IAAI,iBAAiB,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,IAAI,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAE9D,8DAA8D;YAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEpC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACZ,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,MAAM,aAAa,GACjB,kBAAkB,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAE/G,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from '@open-wc/testing';
|
|
2
|
+
import { filenameFromResponse } from './filename.js';
|
|
3
|
+
describe('filenameFromResponse', () => {
|
|
4
|
+
it('parses filename* with charset and percent-encoding from a Response', () => {
|
|
5
|
+
const res = new Response(null, {
|
|
6
|
+
headers: { 'content-disposition': "attachment; filename*=UTF-8''photo%20new.jpg" },
|
|
7
|
+
});
|
|
8
|
+
assert.equal(filenameFromResponse(res), 'photo new.jpg');
|
|
9
|
+
});
|
|
10
|
+
it('parses quoted filename from a Response', () => {
|
|
11
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; filename="photo.jpg"' } });
|
|
12
|
+
assert.equal(filenameFromResponse(res), 'photo.jpg');
|
|
13
|
+
});
|
|
14
|
+
it('parses unquoted filename from a Response', () => {
|
|
15
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; filename=photo.jpg' } });
|
|
16
|
+
assert.equal(filenameFromResponse(res), 'photo.jpg');
|
|
17
|
+
});
|
|
18
|
+
it('returns fallback when no filename present in Response', () => {
|
|
19
|
+
const res = new Response(null, { headers: { 'content-disposition': 'attachment; foo=bar' } });
|
|
20
|
+
assert.equal(filenameFromResponse(res), 'downloaded-file');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=filename.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filename.test.js","sourceRoot":"","sources":["../../../src/lib/file-input/filename.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE;YAC7B,OAAO,EAAE,EAAE,qBAAqB,EAAE,8CAA8C,EAAE;SACnF,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,qBAAqB,EAAE,kCAAkC,EAAE,EAAE,CAAC,CAAC;QAC3G,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,qBAAqB,EAAE,gCAAgC,EAAE,EAAE,CAAC,CAAC;QACzG,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC9F,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|