@remotion/bundler 4.0.438 → 4.0.439
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/css-loader/CssSyntaxError.js +31 -0
- package/css-loader/Warning.js +25 -0
- package/css-loader/index.js +158 -0
- package/css-loader/plugins/index.js +13 -0
- package/css-loader/plugins/postcss-import-parser.js +258 -0
- package/css-loader/plugins/postcss-url-parser.js +391 -0
- package/css-loader/runtime/api.js +61 -0
- package/css-loader/runtime/cssWithMappingToString.js +35 -0
- package/css-loader/runtime/getUrl.js +34 -0
- package/css-loader/utils.js +438 -0
- package/dist/bundle.js +42 -9
- package/dist/index.d.ts +6 -2
- package/dist/index.js +3 -1
- package/dist/rspack-config.d.ts +2 -1
- package/dist/rspack-config.js +2 -1
- package/dist/shared-bundler-config.js +4 -1
- package/dist/watch-ignore-next-change-plugin.d.ts +15 -0
- package/dist/watch-ignore-next-change-plugin.js +286 -0
- package/dist/webpack-config.d.ts +3 -1
- package/dist/webpack-config.js +2 -1
- package/package.json +14 -7
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forked from css-loader v5.2.7
|
|
3
|
+
* MIT License http://www.opensource.org/licenses/mit-license.php
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const valueParser = require("postcss-value-parser");
|
|
8
|
+
const {
|
|
9
|
+
normalizeUrl,
|
|
10
|
+
isUrlRequestable,
|
|
11
|
+
requestify,
|
|
12
|
+
resolveRequests,
|
|
13
|
+
WEBPACK_IGNORE_COMMENT_REGEXP,
|
|
14
|
+
} = require("../utils");
|
|
15
|
+
|
|
16
|
+
const isUrlFunc = /url/i;
|
|
17
|
+
const isImageSetFunc = /^(?:-webkit-)?image-set$/i;
|
|
18
|
+
const needParseDeclaration = /(?:url|(?:-webkit-)?image-set)\(/i;
|
|
19
|
+
|
|
20
|
+
function getNodeFromUrlFunc(node) {
|
|
21
|
+
return node.nodes && node.nodes[0];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getWebpackIgnoreCommentValue(index, nodes, inBetween) {
|
|
25
|
+
if (index === 0 && typeof inBetween !== "undefined") {
|
|
26
|
+
return inBetween;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let prevValueNode = nodes[index - 1];
|
|
30
|
+
|
|
31
|
+
if (!prevValueNode) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (prevValueNode.type === "space") {
|
|
36
|
+
if (!nodes[index - 2]) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
prevValueNode = nodes[index - 2];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (prevValueNode.type !== "comment") {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const matched = prevValueNode.value.match(WEBPACK_IGNORE_COMMENT_REGEXP);
|
|
48
|
+
return matched && matched[2] === "true";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function shouldHandleURL(url, declaration, result) {
|
|
52
|
+
if (url.length === 0) {
|
|
53
|
+
result.warn(`Unable to find uri in '${declaration.toString()}'`, {
|
|
54
|
+
node: declaration,
|
|
55
|
+
});
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!isUrlRequestable(url)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function parseDeclaration(declaration, key, result) {
|
|
67
|
+
if (!needParseDeclaration.test(declaration[key])) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const parsed = valueParser(
|
|
72
|
+
declaration.raws &&
|
|
73
|
+
declaration.raws.value &&
|
|
74
|
+
declaration.raws.value.raw
|
|
75
|
+
? declaration.raws.value.raw
|
|
76
|
+
: declaration[key],
|
|
77
|
+
);
|
|
78
|
+
let inBetween;
|
|
79
|
+
|
|
80
|
+
if (declaration.raws && declaration.raws.between) {
|
|
81
|
+
const lastCommentIndex = declaration.raws.between.lastIndexOf("/*");
|
|
82
|
+
const matched = declaration.raws.between
|
|
83
|
+
.slice(lastCommentIndex)
|
|
84
|
+
.match(WEBPACK_IGNORE_COMMENT_REGEXP);
|
|
85
|
+
|
|
86
|
+
if (matched) {
|
|
87
|
+
inBetween = matched[2] === "true";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let isIgnoreOnDeclaration = false;
|
|
92
|
+
const prevNode = declaration.prev();
|
|
93
|
+
|
|
94
|
+
if (prevNode && prevNode.type === "comment") {
|
|
95
|
+
const matched = prevNode.text.match(WEBPACK_IGNORE_COMMENT_REGEXP);
|
|
96
|
+
|
|
97
|
+
if (matched) {
|
|
98
|
+
isIgnoreOnDeclaration = matched[2] === "true";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let needIgnore;
|
|
103
|
+
const parsedURLs = [];
|
|
104
|
+
parsed.walk((valueNode, index, valueNodes) => {
|
|
105
|
+
if (valueNode.type !== "function") {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (isUrlFunc.test(valueNode.value)) {
|
|
110
|
+
needIgnore = getWebpackIgnoreCommentValue(
|
|
111
|
+
index,
|
|
112
|
+
valueNodes,
|
|
113
|
+
inBetween,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (
|
|
117
|
+
(isIgnoreOnDeclaration && typeof needIgnore === "undefined") ||
|
|
118
|
+
needIgnore
|
|
119
|
+
) {
|
|
120
|
+
if (needIgnore) {
|
|
121
|
+
needIgnore = undefined;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const {nodes} = valueNode;
|
|
128
|
+
const isStringValue =
|
|
129
|
+
nodes.length !== 0 && nodes[0].type === "string";
|
|
130
|
+
let url = isStringValue
|
|
131
|
+
? nodes[0].value
|
|
132
|
+
: valueParser.stringify(nodes);
|
|
133
|
+
url = normalizeUrl(url, isStringValue);
|
|
134
|
+
|
|
135
|
+
if (!shouldHandleURL(url, declaration, result)) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const queryParts = url.split("!");
|
|
140
|
+
let prefix;
|
|
141
|
+
|
|
142
|
+
if (queryParts.length > 1) {
|
|
143
|
+
url = queryParts.pop();
|
|
144
|
+
prefix = queryParts.join("!");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
parsedURLs.push({
|
|
148
|
+
declaration,
|
|
149
|
+
parsed,
|
|
150
|
+
node: getNodeFromUrlFunc(valueNode),
|
|
151
|
+
prefix,
|
|
152
|
+
url,
|
|
153
|
+
needQuotes: false,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return false;
|
|
157
|
+
} else if (isImageSetFunc.test(valueNode.value)) {
|
|
158
|
+
for (const [innerIndex, nNode] of valueNode.nodes.entries()) {
|
|
159
|
+
const {type, value} = nNode;
|
|
160
|
+
|
|
161
|
+
if (type === "function" && isUrlFunc.test(value)) {
|
|
162
|
+
needIgnore = getWebpackIgnoreCommentValue(
|
|
163
|
+
innerIndex,
|
|
164
|
+
valueNode.nodes,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
(isIgnoreOnDeclaration &&
|
|
169
|
+
typeof needIgnore === "undefined") ||
|
|
170
|
+
needIgnore
|
|
171
|
+
) {
|
|
172
|
+
if (needIgnore) {
|
|
173
|
+
needIgnore = undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const {nodes} = nNode;
|
|
180
|
+
const isStringValue =
|
|
181
|
+
nodes.length !== 0 && nodes[0].type === "string";
|
|
182
|
+
let url = isStringValue
|
|
183
|
+
? nodes[0].value
|
|
184
|
+
: valueParser.stringify(nodes);
|
|
185
|
+
url = normalizeUrl(url, isStringValue);
|
|
186
|
+
|
|
187
|
+
if (!shouldHandleURL(url, declaration, result)) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const queryParts = url.split("!");
|
|
192
|
+
let prefix;
|
|
193
|
+
|
|
194
|
+
if (queryParts.length > 1) {
|
|
195
|
+
url = queryParts.pop();
|
|
196
|
+
prefix = queryParts.join("!");
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
parsedURLs.push({
|
|
200
|
+
declaration,
|
|
201
|
+
parsed,
|
|
202
|
+
node: getNodeFromUrlFunc(nNode),
|
|
203
|
+
prefix,
|
|
204
|
+
url,
|
|
205
|
+
needQuotes: false,
|
|
206
|
+
});
|
|
207
|
+
} else if (type === "string") {
|
|
208
|
+
needIgnore = getWebpackIgnoreCommentValue(
|
|
209
|
+
innerIndex,
|
|
210
|
+
valueNode.nodes,
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
if (
|
|
214
|
+
(isIgnoreOnDeclaration &&
|
|
215
|
+
typeof needIgnore === "undefined") ||
|
|
216
|
+
needIgnore
|
|
217
|
+
) {
|
|
218
|
+
if (needIgnore) {
|
|
219
|
+
needIgnore = undefined;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let url = normalizeUrl(value, true);
|
|
226
|
+
|
|
227
|
+
if (!shouldHandleURL(url, declaration, result)) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const queryParts = url.split("!");
|
|
232
|
+
let prefix;
|
|
233
|
+
|
|
234
|
+
if (queryParts.length > 1) {
|
|
235
|
+
url = queryParts.pop();
|
|
236
|
+
prefix = queryParts.join("!");
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
parsedURLs.push({
|
|
240
|
+
declaration,
|
|
241
|
+
parsed,
|
|
242
|
+
node: nNode,
|
|
243
|
+
prefix,
|
|
244
|
+
url,
|
|
245
|
+
needQuotes: true,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
return parsedURLs;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const plugin = (options = {}) => {
|
|
258
|
+
return {
|
|
259
|
+
postcssPlugin: "postcss-url-parser",
|
|
260
|
+
|
|
261
|
+
prepare(result) {
|
|
262
|
+
const parsedDeclarations = [];
|
|
263
|
+
return {
|
|
264
|
+
Declaration(declaration) {
|
|
265
|
+
const parsedURL = parseDeclaration(
|
|
266
|
+
declaration,
|
|
267
|
+
"value",
|
|
268
|
+
result,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
if (!parsedURL) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
parsedDeclarations.push(...parsedURL);
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
async OnceExit() {
|
|
279
|
+
if (parsedDeclarations.length === 0) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const resolvedDeclarations = await Promise.all(
|
|
284
|
+
parsedDeclarations.map(async (parsedDeclaration) => {
|
|
285
|
+
const {url} = parsedDeclaration;
|
|
286
|
+
|
|
287
|
+
if (options.filter) {
|
|
288
|
+
const needKeep = await options.filter(url);
|
|
289
|
+
|
|
290
|
+
if (!needKeep) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const splittedUrl = url.split(/(\?)?#/);
|
|
296
|
+
const [pathname, query, hashOrQuery] = splittedUrl;
|
|
297
|
+
let hash = query ? "?" : "";
|
|
298
|
+
hash += hashOrQuery ? `#${hashOrQuery}` : "";
|
|
299
|
+
const request = requestify(
|
|
300
|
+
pathname,
|
|
301
|
+
options.rootContext,
|
|
302
|
+
);
|
|
303
|
+
const {resolver, context} = options;
|
|
304
|
+
const resolvedUrl = await resolveRequests(
|
|
305
|
+
resolver,
|
|
306
|
+
context,
|
|
307
|
+
[...new Set([request, url])],
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
if (!resolvedUrl) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return {...parsedDeclaration, url: resolvedUrl, hash};
|
|
315
|
+
}),
|
|
316
|
+
);
|
|
317
|
+
const urlToNameMap = new Map();
|
|
318
|
+
const urlToReplacementMap = new Map();
|
|
319
|
+
let hasUrlImportHelper = false;
|
|
320
|
+
|
|
321
|
+
for (
|
|
322
|
+
let index = 0;
|
|
323
|
+
index <= resolvedDeclarations.length - 1;
|
|
324
|
+
index++
|
|
325
|
+
) {
|
|
326
|
+
const item = resolvedDeclarations[index];
|
|
327
|
+
|
|
328
|
+
if (!item) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (!hasUrlImportHelper) {
|
|
333
|
+
options.imports.push({
|
|
334
|
+
importName: "___CSS_LOADER_GET_URL_IMPORT___",
|
|
335
|
+
url: options.urlHandler(
|
|
336
|
+
require.resolve("../runtime/getUrl.js"),
|
|
337
|
+
),
|
|
338
|
+
index: -1,
|
|
339
|
+
});
|
|
340
|
+
hasUrlImportHelper = true;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const {url, prefix} = item;
|
|
344
|
+
const newUrl = prefix ? `${prefix}!${url}` : url;
|
|
345
|
+
let importName = urlToNameMap.get(newUrl);
|
|
346
|
+
|
|
347
|
+
if (!importName) {
|
|
348
|
+
importName = `___CSS_LOADER_URL_IMPORT_${urlToNameMap.size}___`;
|
|
349
|
+
urlToNameMap.set(newUrl, importName);
|
|
350
|
+
options.imports.push({
|
|
351
|
+
importName,
|
|
352
|
+
url: options.urlHandler(newUrl),
|
|
353
|
+
index,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const {hash, needQuotes} = item;
|
|
358
|
+
const replacementKey = JSON.stringify({
|
|
359
|
+
newUrl,
|
|
360
|
+
hash,
|
|
361
|
+
needQuotes,
|
|
362
|
+
});
|
|
363
|
+
let replacementName =
|
|
364
|
+
urlToReplacementMap.get(replacementKey);
|
|
365
|
+
|
|
366
|
+
if (!replacementName) {
|
|
367
|
+
replacementName = `___CSS_LOADER_URL_REPLACEMENT_${urlToReplacementMap.size}___`;
|
|
368
|
+
urlToReplacementMap.set(
|
|
369
|
+
replacementKey,
|
|
370
|
+
replacementName,
|
|
371
|
+
);
|
|
372
|
+
options.replacements.push({
|
|
373
|
+
replacementName,
|
|
374
|
+
importName,
|
|
375
|
+
hash,
|
|
376
|
+
needQuotes,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
item.node.type = "word";
|
|
381
|
+
item.node.value = replacementName;
|
|
382
|
+
item.declaration.value = item.parsed.toString();
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
plugin.postcss = true;
|
|
391
|
+
module.exports = plugin;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forked from css-loader v5.2.7
|
|
3
|
+
* MIT License http://www.opensource.org/licenses/mit-license.php
|
|
4
|
+
* Author Tobias Koppers @sokra
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
// css base code, injected by the css-loader
|
|
9
|
+
module.exports = function (cssWithMappingToString) {
|
|
10
|
+
var list = [];
|
|
11
|
+
|
|
12
|
+
list.toString = function toString() {
|
|
13
|
+
return this.map(function (item) {
|
|
14
|
+
var content = cssWithMappingToString(item);
|
|
15
|
+
|
|
16
|
+
if (item[2]) {
|
|
17
|
+
return "@media ".concat(item[2], " {").concat(content, "}");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return content;
|
|
21
|
+
}).join("");
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
list.i = function (modules, mediaQuery, dedupe) {
|
|
25
|
+
if (typeof modules === "string") {
|
|
26
|
+
modules = [[null, modules, ""]];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var alreadyImportedModules = {};
|
|
30
|
+
|
|
31
|
+
if (dedupe) {
|
|
32
|
+
for (var i = 0; i < this.length; i++) {
|
|
33
|
+
var id = this[i][0];
|
|
34
|
+
|
|
35
|
+
if (id != null) {
|
|
36
|
+
alreadyImportedModules[id] = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (var _i = 0; _i < modules.length; _i++) {
|
|
42
|
+
var item = [].concat(modules[_i]);
|
|
43
|
+
|
|
44
|
+
if (dedupe && alreadyImportedModules[item[0]]) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (mediaQuery) {
|
|
49
|
+
if (!item[2]) {
|
|
50
|
+
item[2] = mediaQuery;
|
|
51
|
+
} else {
|
|
52
|
+
item[2] = "".concat(mediaQuery, " and ").concat(item[2]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
list.push(item);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return list;
|
|
61
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forked from css-loader v5.2.7
|
|
3
|
+
* MIT License http://www.opensource.org/licenses/mit-license.php
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
module.exports = function cssWithMappingToString(item) {
|
|
8
|
+
var content = item[1];
|
|
9
|
+
var cssMapping = item[3];
|
|
10
|
+
|
|
11
|
+
if (!cssMapping) {
|
|
12
|
+
return content;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (typeof btoa === "function") {
|
|
16
|
+
var base64 = btoa(
|
|
17
|
+
unescape(encodeURIComponent(JSON.stringify(cssMapping))),
|
|
18
|
+
);
|
|
19
|
+
var data =
|
|
20
|
+
"sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(
|
|
21
|
+
base64,
|
|
22
|
+
);
|
|
23
|
+
var sourceMapping = "/*# ".concat(data, " */");
|
|
24
|
+
|
|
25
|
+
var sourceURLs = cssMapping.sources.map(function (source) {
|
|
26
|
+
return "/*# sourceURL="
|
|
27
|
+
.concat(cssMapping.sourceRoot || "")
|
|
28
|
+
.concat(source, " */");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return [content].concat(sourceURLs).concat([sourceMapping]).join("\n");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return [content].join("\n");
|
|
35
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forked from css-loader v5.2.7
|
|
3
|
+
* MIT License http://www.opensource.org/licenses/mit-license.php
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
module.exports = function (url, options) {
|
|
8
|
+
if (!options) {
|
|
9
|
+
options = {};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
url = url && url.__esModule ? url.default : url;
|
|
13
|
+
|
|
14
|
+
if (typeof url !== "string") {
|
|
15
|
+
return url;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// If url is already wrapped in quotes, remove them
|
|
19
|
+
if (/^['"].*['"]$/.test(url)) {
|
|
20
|
+
url = url.slice(1, -1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (options.hash) {
|
|
24
|
+
url += options.hash;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Should url be wrapped?
|
|
28
|
+
// See https://drafts.csswg.org/css-values-3/#urls
|
|
29
|
+
if (/["'() \t\n]/.test(url) || options.needQuotes) {
|
|
30
|
+
return '"'.concat(url.replace(/"/g, '\\"').replace(/\n/g, "\\n"), '"');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return url;
|
|
34
|
+
};
|