cds-caching 1.2.0 → 1.3.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.
Files changed (79) hide show
  1. package/README.md +195 -1114
  2. package/app/dashboard/Component-dbg.js +59 -0
  3. package/app/dashboard/Component-dbg.js.map +1 -0
  4. package/app/dashboard/Component.js +2 -0
  5. package/app/dashboard/Component.js.map +1 -0
  6. package/app/dashboard/Component.ts +59 -0
  7. package/app/dashboard/controller/App-dbg.controller.js +132 -0
  8. package/app/dashboard/controller/App-dbg.controller.js.map +1 -0
  9. package/app/dashboard/controller/App.controller.js +2 -0
  10. package/app/dashboard/controller/App.controller.js.map +1 -0
  11. package/app/dashboard/controller/App.controller.ts +147 -0
  12. package/app/dashboard/controller/BaseController-dbg.js +75 -0
  13. package/app/dashboard/controller/BaseController-dbg.js.map +1 -0
  14. package/app/dashboard/controller/BaseController.js +2 -0
  15. package/app/dashboard/controller/BaseController.js.map +1 -0
  16. package/app/dashboard/controller/BaseController.ts +88 -0
  17. package/app/dashboard/controller/Cache-dbg.controller.js +421 -0
  18. package/app/dashboard/controller/Cache-dbg.controller.js.map +1 -0
  19. package/app/dashboard/controller/Cache.controller.js +2 -0
  20. package/app/dashboard/controller/Cache.controller.js.map +1 -0
  21. package/app/dashboard/controller/Cache.controller.ts +490 -0
  22. package/app/dashboard/controller/Main-dbg.controller.js +32 -0
  23. package/app/dashboard/controller/Main-dbg.controller.js.map +1 -0
  24. package/app/dashboard/controller/Main.controller.js +2 -0
  25. package/app/dashboard/controller/Main.controller.js.map +1 -0
  26. package/app/dashboard/controller/Main.controller.ts +31 -0
  27. package/app/dashboard/controller/SingleMetric-dbg.controller.js +306 -0
  28. package/app/dashboard/controller/SingleMetric-dbg.controller.js.map +1 -0
  29. package/app/dashboard/controller/SingleMetric.controller.js +2 -0
  30. package/app/dashboard/controller/SingleMetric.controller.js.map +1 -0
  31. package/app/dashboard/controller/SingleMetric.controller.ts +335 -0
  32. package/app/dashboard/i18n/i18n.properties +61 -0
  33. package/app/dashboard/i18n/i18n_de.properties +3 -0
  34. package/app/dashboard/i18n/i18n_en.properties +3 -0
  35. package/app/dashboard/index-cdn.html +28 -0
  36. package/app/dashboard/index.html +19 -0
  37. package/app/dashboard/manifest.json +145 -0
  38. package/app/dashboard/model/formatter-dbg.js +253 -0
  39. package/app/dashboard/model/formatter-dbg.js.map +1 -0
  40. package/app/dashboard/model/formatter.js +2 -0
  41. package/app/dashboard/model/formatter.js.map +1 -0
  42. package/app/dashboard/model/formatter.ts +275 -0
  43. package/app/dashboard/model/models-dbg.js +13 -0
  44. package/app/dashboard/model/models-dbg.js.map +1 -0
  45. package/app/dashboard/model/models.js +2 -0
  46. package/app/dashboard/model/models.js.map +1 -0
  47. package/app/dashboard/model/models.ts +13 -0
  48. package/app/dashboard/resources/sap-ui-custom-dbg.js +4695 -0
  49. package/app/dashboard/resources/sap-ui-custom-dbg.js.map +1 -0
  50. package/app/dashboard/resources/sap-ui-custom.js +5794 -0
  51. package/app/dashboard/resources/sap-ui-custom.js.map +1 -0
  52. package/app/dashboard/service/CacheStatisticsService-dbg.js +267 -0
  53. package/app/dashboard/service/CacheStatisticsService-dbg.js.map +1 -0
  54. package/app/dashboard/service/CacheStatisticsService.js +2 -0
  55. package/app/dashboard/service/CacheStatisticsService.js.map +1 -0
  56. package/app/dashboard/service/CacheStatisticsService.ts +397 -0
  57. package/app/dashboard/view/App.view.xml +18 -0
  58. package/app/dashboard/view/Cache.view.xml +777 -0
  59. package/app/dashboard/view/Main.view.xml +57 -0
  60. package/app/dashboard/view/SingleMetric.view.xml +337 -0
  61. package/cds-plugin.js +52 -0
  62. package/db/cache-store.cds +12 -0
  63. package/db/statistics.cds +128 -0
  64. package/index.cds +2 -128
  65. package/lib/CachingService.js +13 -0
  66. package/lib/add.js +17 -0
  67. package/lib/operations/AsyncOperations.js +162 -111
  68. package/lib/operations/BasicOperations.js +35 -0
  69. package/lib/operations/CapOperations.js +92 -40
  70. package/lib/support/CacheStatisticsHandler.js +35 -10
  71. package/lib/support/CacheStoreManager.js +29 -0
  72. package/lib/support/KeyvCDS.js +149 -0
  73. package/lib/support/MultitenancyDetector.js +25 -0
  74. package/lib/support/RuntimeConfigurationManager.js +69 -37
  75. package/lib/support/StatisticsPersistenceManager.js +18 -2
  76. package/lib/support/Telemetry.js +137 -0
  77. package/lib/util.js +29 -11
  78. package/package.json +44 -12
  79. package/srv/caching-api-service.js +47 -2
@@ -0,0 +1,4695 @@
1
+ //@ui5-bundle sap-ui-custom-dbg.js
2
+ //@ui5-bundle-raw-include ui5loader.js
3
+ /*!
4
+ * OpenUI5
5
+ * (c) Copyright 2025 SAP SE or an SAP affiliate company.
6
+ * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
7
+ */
8
+
9
+ /*
10
+ * IMPORTANT NOTICE
11
+ * With 1.54, ui5loader.js and its new features are not yet a public API.
12
+ * The loader must only be used via the well-known and documented UI5 APIs
13
+ * such as sap.ui.define, sap.ui.require, etc.
14
+ * Any direct usage of ui5loader.js or its features is not supported and
15
+ * might break in future releases.
16
+ */
17
+
18
+ /*global Blob, console, document, Promise, URL, XMLHttpRequest */
19
+
20
+ (function(__global) {
21
+ "use strict";
22
+
23
+ /*
24
+ * Helper function that removes any query and/or hash parts from the given URL.
25
+ *
26
+ * @param {string} href URL to remove query and hash from
27
+ * @returns {string}
28
+ */
29
+ function pathOnly(href) {
30
+ const p = href.search(/[?#]/);
31
+ return p < 0 ? href : href.slice(0, p);
32
+ }
33
+
34
+ /**
35
+ * Resolve a given URL, either against the base URL of the current document or against a given base URL.
36
+ *
37
+ * If no base URL is given, the URL will be resolved relative to the baseURI of the current document.
38
+ * If a base URL is given, that base will first be resolved relative to the document's baseURI,
39
+ * then the URL will be resolved relative to the resolved base.
40
+ *
41
+ * Search parameters or a hash of the chosen base will be ignored.
42
+ *
43
+ * @param {string} sURI Relative or absolute URL that should be resolved
44
+ * @param {string} [sBase=document.baseURI] Base URL relative to which the URL should be resolved
45
+ * @returns {string} Resolved URL
46
+ */
47
+ function resolveURL(sURI, sBase) {
48
+ sBase = pathOnly(sBase ? resolveURL(sBase) : document.baseURI);
49
+ return new URL(sURI, sBase).href;
50
+ }
51
+
52
+ // ---- helpers -------------------------------------------------------------------------------
53
+
54
+ function noop() {}
55
+
56
+ function forEach(obj, callback) {
57
+ Object.keys(obj).forEach((key) => callback(key, obj[key]));
58
+ }
59
+
60
+ function executeInSeparateTask(fn) {
61
+ setTimeout(fn, 0);
62
+ }
63
+
64
+ function executeInMicroTask(fn) {
65
+ Promise.resolve().then(fn);
66
+ }
67
+
68
+ // ---- hooks & configuration -----------------------------------------------------------------
69
+
70
+ const aEarlyLogs = [];
71
+
72
+ function earlyLog(level, message) {
73
+ aEarlyLogs.push({
74
+ level,
75
+ message
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Log functionality.
81
+ *
82
+ * Can be set to an object with the methods shown below (subset of sap/base/Log).
83
+ * Logging methods never must fail. Should they ever throw errors, then the internal state
84
+ * of the loader will be broken.
85
+ *
86
+ * By default, all methods are implemented as NOOPs.
87
+ *
88
+ * @type {{debug:function(),info:function(),warning:function(),error:function(),isLoggable:function():boolean}}
89
+ * @private
90
+ */
91
+
92
+ let log = {
93
+ debug: earlyLog.bind(this, 'debug'),
94
+ info: earlyLog.bind(this, 'info'),
95
+ warning: earlyLog.bind(this, 'warning'),
96
+ error: earlyLog.bind(this, 'error'),
97
+ isLoggable: noop
98
+ };
99
+
100
+ /**
101
+ * Basic assert functionality.
102
+ *
103
+ * Can be set to a function that gets a value (the expression to be asserted) as first
104
+ * parameter and a message as second parameter. When the expression coerces to false,
105
+ * the assertion is violated and the message should be emitted (logged, thrown, whatever).
106
+ *
107
+ * By default, this is implemented as a NOOP.
108
+ * @type {function(any,string)}
109
+ * @private
110
+ */
111
+ let assert = noop; // Null Object pattern: dummy assert which is used as long as no assert is injected
112
+
113
+ /**
114
+ * Callback for performance measurement.
115
+ *
116
+ * When set, it must be an object with methods <code>start</code> and <code>end</code>.
117
+ * @type {{start:function(string,any),end:function(string)}}
118
+ * @private
119
+ */
120
+ let measure;
121
+
122
+ /**
123
+ * Source code transformation hook.
124
+ *
125
+ * To be used by code coverage, only supported in sync mode.
126
+ * @private
127
+ * @ui5-transform-hint replace-local undefined
128
+ */
129
+ let translate;
130
+
131
+ /**
132
+ * Method used by sap.ui.require to simulate asynchronous behavior.
133
+ *
134
+ * The default executes the given function in a separate browser task.
135
+ * Can be changed to execute in a micro task to save idle time in case of
136
+ * many nested sap.ui.require calls.
137
+ */
138
+ let simulateAsyncCallback = executeInSeparateTask;
139
+
140
+ /*
141
+ * Activates strictest possible compliance with AMD spec
142
+ * - no multiple executions of the same module
143
+ * - at most one anonymous module definition per file, zero for adhoc definitions
144
+ */
145
+ const strictModuleDefinitions = true;
146
+
147
+ /**
148
+ * Whether asynchronous loading can be used at all.
149
+ * When activated, require will load asynchronously, else synchronously.
150
+ * @type {boolean}
151
+ * @private
152
+ * @ui5-transform-hint replace-local true
153
+ */
154
+ let bGlobalAsyncMode = false;
155
+
156
+
157
+ /**
158
+ * Whether ui5loader currently exposes its AMD implementation as global properties
159
+ * <code>define</code> and <code>require</code>. Defaults to <code>false</code>.
160
+ * @type {boolean}
161
+ * @private
162
+ */
163
+ let bExposeAsAMDLoader = false;
164
+
165
+ /**
166
+ * How the loader should react to calls of sync APIs or when global names are accessed:
167
+ * 0: tolerate
168
+ * 1: warn
169
+ * 2: reject
170
+ * @type {int}
171
+ * @private
172
+ */
173
+ let syncCallBehavior = 0;
174
+
175
+ /**
176
+ * Default base URL for modules, used when no other configuration is provided.
177
+ * In case the base url is removed via <code>registerResourcePath("", null)</code>
178
+ * it will be reset to this URL instead.
179
+ * @const
180
+ * @type {string}
181
+ * @private
182
+ */
183
+ const DEFAULT_BASE_URL = "./";
184
+
185
+ /**
186
+ * Temporarily saved reference to the original value of the global define variable.
187
+ *
188
+ * @type {any}
189
+ * @private
190
+ */
191
+ let vOriginalDefine;
192
+
193
+ /**
194
+ * Temporarily saved reference to the original value of the global require variable.
195
+ *
196
+ * @type {any}
197
+ * @private
198
+ */
199
+ let vOriginalRequire;
200
+
201
+
202
+ /**
203
+ * A map of URL prefixes keyed by the corresponding module name prefix.
204
+ *
205
+ * Note that the empty prefix ('') will always match and thus serves as a fallback.
206
+ * See {@link sap.ui.loader.config}, option <code>paths</code>.
207
+ * @type {Object<string,{url:string,absoluteUrl:string}>}
208
+ * @private
209
+ */
210
+ const mUrlPrefixes = Object.create(null);
211
+ mUrlPrefixes[''] = {
212
+ url: DEFAULT_BASE_URL,
213
+ absoluteUrl: resolveURL(DEFAULT_BASE_URL)
214
+ };
215
+
216
+ /**
217
+ * Mapping of module IDs.
218
+ *
219
+ * Each entry is a map of its own, keyed by the module ID prefix for which it should be
220
+ * applied. Each contained map maps module ID prefixes to module ID prefixes.
221
+ *
222
+ * All module ID prefixes must not have extensions.
223
+ * @type {Object.<string,Object.<string,string>>}
224
+ * @private
225
+ */
226
+ const mMaps = Object.create(null);
227
+
228
+ /**
229
+ * Information about third party modules, keyed by the module's resource name (including extension '.js').
230
+ *
231
+ * Each module shim object can have the following properties:
232
+ * <ul>
233
+ * <li><i>boolean</i>: [amd=false] Whether the module uses an AMD loader if present. If set to <code>true</code>,
234
+ * UI5 will disable an AMD loader while loading such a module to force the module to expose its content
235
+ * via global names.</li>
236
+ * <li><i>string[]|string</i>: [exports=undefined] Global name (or names) that are exported by the module.
237
+ * If one ore multiple names are defined, the first one will be read from the global object and will be
238
+ * used as value of the module. Each name can be a dot separated hierarchical name (will be resolved with
239
+ * <code>getGlobalProperty</code>)</li>
240
+ * <li><i>string[]</i>: [deps=undefined] List of modules that the module depends on. The modules will be loaded
241
+ * first before loading the module itself. Note that the stored dependencies also include the extension '.js'
242
+ * for easier evaluation, but <code>config({shim:...})</code> expects them without the extension for
243
+ * compatibility with the AMD-JS specification.</li>
244
+ * </ul>
245
+ *
246
+ * @see config method
247
+ * @type {Object.<string,{amd:boolean,exports:(string|string[]),deps:string[]}>}
248
+ * @private
249
+ */
250
+ const mShims = Object.create(null);
251
+
252
+ /**
253
+ * Dependency Cache information.
254
+ * Maps the name of a module to a list of its known dependencies.
255
+ * @type {Object.<string,string[]>}
256
+ * @private
257
+ */
258
+ const mDepCache = Object.create(null);
259
+
260
+ /**
261
+ * Whether the loader should try to load debug sources.
262
+ * @type {boolean}
263
+ * @private
264
+ */
265
+ let bDebugSources = false;
266
+
267
+ /**
268
+ * Indicates partial or total debug mode.
269
+ *
270
+ * Can be set to a function which checks whether preloads should be ignored for the given module.
271
+ * If undefined, all preloads will be used.
272
+ * @type {function(string):boolean|undefined}
273
+ * @private
274
+ */
275
+ let fnIgnorePreload;
276
+
277
+ /**
278
+ * Whether the loader should try to load the debug variant
279
+ * of a module.
280
+ * This takes the standard and partial debug mode into account.
281
+ *
282
+ * @param {string} sModuleName Name of the module to be loaded
283
+ * @returns {boolean} Whether the debug variant should be loaded
284
+ */
285
+ function shouldLoadDebugVariant(sModuleName) {
286
+ if (fnIgnorePreload) {
287
+ // if preload is ignored (= partial debug mode), load the debug module first
288
+ if (fnIgnorePreload(sModuleName)) {
289
+ return true;
290
+ } else {
291
+ // partial debug mode is active, but not for this module
292
+ return false;
293
+ }
294
+ } else {
295
+ // no debug mode or standard debug mode
296
+ return bDebugSources;
297
+ }
298
+ }
299
+
300
+ // ---- internal state ------------------------------------------------------------------------
301
+
302
+ /**
303
+ * Map of modules that have been loaded or required so far, keyed by their name.
304
+ *
305
+ * @type {Object<string,Module>}
306
+ * @private
307
+ */
308
+ const mModules = Object.create(null);
309
+
310
+ /**
311
+ * Whether (sap.ui.)define calls must be executed synchronously in the current context.
312
+ *
313
+ * The initial value is <code>null</code>. During the execution of a module loading operation
314
+ * ((sap.ui.)require or (sap.ui.)define etc.), it is set to true or false depending on the
315
+ * legacy synchronicity behavior of the operation.
316
+ *
317
+ * Problem: when AMD modules are loaded with hard coded script tags and when some later inline
318
+ * script expects the module export synchronously, then the (sap.ui.)define must be executed
319
+ * synchronously.
320
+ * Most prominent example: unit tests that include QUnitUtils as a script tag and use qutils
321
+ * in one of their inline scripts.
322
+ * @type {boolean|null}
323
+ * @private
324
+ */
325
+ let bForceSyncDefines = null;
326
+
327
+ /**
328
+ * Stack of modules that are currently being executed in case of synchronous processing.
329
+ *
330
+ * Allows to identify the executing module (e.g. when resolving dependencies or in case of
331
+ * bundles like sap-ui-core).
332
+ *
333
+ * @type {Array.<{name:string,used:boolean}>}
334
+ * @private
335
+ */
336
+ const _execStack = [ ];
337
+
338
+ /**
339
+ * A prefix that will be added to module loading log statements and which reflects the nesting of module executions.
340
+ * @type {string}
341
+ * @private
342
+ */
343
+ let sLogPrefix = "";
344
+
345
+ /**
346
+ * Counter used to give anonymous modules a unique module ID.
347
+ * @type {int}
348
+ * @private
349
+ */
350
+ let iAnonymousModuleCount = 0;
351
+
352
+ // ---- break preload execution into tasks ----------------------------------------------------
353
+
354
+ /**
355
+ * Default value for `iMaxTaskDuration`.
356
+ *
357
+ * A value of -1 switched the scheduling off, a value of zero postpones each execution
358
+ */
359
+ const DEFAULT_MAX_TASK_DURATION = -1; // off
360
+
361
+ /**
362
+ * Maximum accumulated task execution time (threshold)
363
+ * Can be configured via the private API property `maxTaskDuration`.
364
+ */
365
+ let iMaxTaskDuration = DEFAULT_MAX_TASK_DURATION;
366
+
367
+ /**
368
+ * The earliest elapsed time at which a new browser task will be enforced.
369
+ * Will be updated when a new task starts.
370
+ */
371
+ let iMaxTaskTime = Date.now() + iMaxTaskDuration;
372
+
373
+ /**
374
+ * A promise that fulfills when the new browser task has been reached.
375
+ * All postponed callback executions will be executed after this promise.
376
+ * `null` as long as the elapsed time threshold is not reached.
377
+ */
378
+ let pWaitForNextTask;
379
+
380
+ /**
381
+ * Message channel which will be used to create a new browser task
382
+ * without being subject to timer throttling.
383
+ * Will be created lazily on first usage.
384
+ */
385
+ let oNextTaskMessageChannel;
386
+
387
+ /**
388
+ * Update elapsed time threshold.
389
+ *
390
+ * The threshold will be updated only if executions currently are not postponed.
391
+ * Otherwise, the next task will anyhow update the threshold.
392
+ */
393
+ function updateMaxTaskTime() {
394
+ if ( pWaitForNextTask == null ) {
395
+ iMaxTaskTime = Date.now() + iMaxTaskDuration;
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Update duration limit and elapsed time threshold.
401
+ */
402
+ function updateMaxTaskDuration(v) {
403
+ v = Number(v);
404
+
405
+ const iBeginOfCurrentTask = iMaxTaskTime - iMaxTaskDuration;
406
+
407
+ // limit to range [-1 ... Infinity], any other value incl. NaN restores the default
408
+ iMaxTaskDuration = v >= -1 ? v : DEFAULT_MAX_TASK_DURATION;
409
+
410
+ // Update the elapsed time threshold only if executions currently are not postponed.
411
+ // Otherwise, the next task will be the first to honor the new maximum duration.
412
+ if ( pWaitForNextTask == null ) {
413
+ iMaxTaskTime = iBeginOfCurrentTask + iMaxTaskDuration;
414
+ }
415
+ }
416
+
417
+ // remember original setTimeout for task splitting to avoid clashes using sinon.useFakeTimers()
418
+ const nativeSetTimeout = __global.setTimeout;
419
+
420
+ function waitForNextTask() {
421
+ if ( pWaitForNextTask == null ) {
422
+ /**
423
+ * Post a message to a MessageChannel to create a new task, without suffering from timer throttling
424
+ * In the new task, use a setTimeout(,0) to allow for better queuing of other events (like CSS loading)
425
+ */
426
+ pWaitForNextTask = new Promise(function(resolve) {
427
+ if ( oNextTaskMessageChannel == null ) {
428
+ oNextTaskMessageChannel = new MessageChannel();
429
+ oNextTaskMessageChannel.port2.start();
430
+ }
431
+ oNextTaskMessageChannel.port2.addEventListener("message", function() {
432
+ nativeSetTimeout(function() {
433
+ pWaitForNextTask = null;
434
+ iMaxTaskTime = Date.now() + iMaxTaskDuration;
435
+ resolve();
436
+ }, 0);
437
+ }, {
438
+ once: true
439
+ });
440
+ oNextTaskMessageChannel.port1.postMessage(null);
441
+ });
442
+ }
443
+ return pWaitForNextTask;
444
+ }
445
+
446
+ /**
447
+ * Creates a function which schedules the execution of the given callback.
448
+ *
449
+ * The scheduling tries to limit the duration of browser tasks. When the configurable
450
+ * limit is reached, the creation of a new browser task is triggered and all subsequently
451
+ * scheduled callbacks will be postponed until the new browser task starts executing.
452
+ * In the new browser task, scheduling starts anew.
453
+ *
454
+ * The limit for the duration of browser tasks is configured via `iMaxTaskDuration`.
455
+ * By setting `iMaxTaskDuration` to a negative value, the whole scheduling mechanism is
456
+ * switched off. In that case, the returned function will execute the callback immediately.
457
+ *
458
+ * If a value of zero is set, each callback will be executed in a separate browser task.
459
+ * For preloaded modules, this essentially mimics the browser behavior of single file loading,
460
+ * but without the network and server delays.
461
+ *
462
+ * For larger values, at least one callback will be executed in each new browser task. When,
463
+ * after the execution of the callback, the configured threshold has been reached, all further
464
+ * callbacks will be postponed.
465
+ *
466
+ * Note: This is a heuristic only. Neither is the measurement of the task duration accurate,
467
+ * nor is there a way to know in advance the execution time of a callback.
468
+ *
469
+ * @param {function(any):void} fnCallback
470
+ * Function to schedule
471
+ * @returns {function(any):void}
472
+ * A function to call instead of the original callback; it takes care of scheduling
473
+ * and executing the original callback.
474
+ * @private
475
+ */
476
+ function scheduleExecution(fnCallback) {
477
+ if ( iMaxTaskDuration < 0 ) {
478
+ return fnCallback;
479
+ }
480
+ return function() {
481
+ if ( pWaitForNextTask == null ) {
482
+ fnCallback.call(undefined, arguments[0]);
483
+
484
+ // if time limit is reached now, postpone future task
485
+ if ( Date.now() >= iMaxTaskTime ) {
486
+ waitForNextTask();
487
+ }
488
+ return;
489
+ }
490
+ pWaitForNextTask.then(scheduleExecution(fnCallback).bind(undefined, arguments[0]));
491
+ };
492
+ }
493
+
494
+ // ---- Names and Paths -----------------------------------------------------------------------
495
+
496
+ /**
497
+ * Name conversion function that converts a name in unified resource name syntax to a name in UI5 module name syntax.
498
+ * If the name cannot be converted (e.g. doesn't end with '.js'), then <code>undefined</code> is returned.
499
+ *
500
+ * @param {string} sName Name in unified resource name syntax
501
+ * @returns {string|undefined} Name in UI5 (legacy) module name syntax (dot separated)
502
+ * or <code>undefined</code> when the name can't be converted
503
+ * @private
504
+ */
505
+ function urnToUI5(sName) {
506
+ // UI5 module name syntax is only defined for JS resources
507
+ if ( !/\.js$/.test(sName) ) {
508
+ return undefined;
509
+ }
510
+
511
+ sName = sName.slice(0, -3);
512
+ if ( /^jquery\.sap\./.test(sName) ) {
513
+ return sName; // do nothing
514
+ }
515
+ return sName.replace(/\//g, ".");
516
+ }
517
+
518
+ function urnToIDAndType(sResourceName) {
519
+ const basenamePos = sResourceName.lastIndexOf('/');
520
+ const dotPos = sResourceName.lastIndexOf('.');
521
+
522
+ if ( dotPos > basenamePos ) {
523
+ return {
524
+ id: sResourceName.slice(0, dotPos),
525
+ type: sResourceName.slice(dotPos)
526
+ };
527
+ }
528
+ return {
529
+ id: sResourceName,
530
+ type: ''
531
+ };
532
+ }
533
+
534
+ const rJSSubTypes = /(\.controller|\.fragment|\.view|\.designtime|\.support)?.js$/;
535
+
536
+ function urnToBaseIDAndSubType(sResourceName) {
537
+ const m = rJSSubTypes.exec(sResourceName);
538
+ if ( m ) {
539
+ return {
540
+ baseID: sResourceName.slice(0, m.index),
541
+ subType: m[0]
542
+ };
543
+ }
544
+ }
545
+
546
+ const rDotSegmentAnywhere = /(?:^|\/)\.+(?=\/|$)/;
547
+ const rDotSegment = /^\.*$/;
548
+
549
+ /**
550
+ * Normalizes a resource name by resolving any relative name segments.
551
+ *
552
+ * A segment consisting of a single dot <code>./</code>, when used at the beginning of a name refers
553
+ * to the containing package of the <code>sBaseName</code>. When used inside a name, it is ignored.
554
+ *
555
+ * A segment consisting of two dots <code>../</code> refers to the parent package. It can be used
556
+ * anywhere in a name, but the resolved name prefix up to that point must not be empty.
557
+ *
558
+ * Example: A name <code>../common/validation.js</code> defined in <code>sap/myapp/controller/mycontroller.controller.js</code>
559
+ * will resolve to <code>sap/myapp/common/validation.js</code>.
560
+ *
561
+ * When <code>sBaseName</code> is <code>null</code> (e.g. for a <code>sap.ui.require</code> call),
562
+ * the resource name must not start with a relative name segment or an error will be thrown.
563
+ *
564
+ * @param {string} sResourceName Name to resolve
565
+ * @param {string|null} sBaseName Name of a reference module relative to which the name will be resolved
566
+ * @returns {string} Resolved name
567
+ * @throws {Error} When a relative name should be resolved but not basename is given;
568
+ * or when upward navigation (../) is requested on the root level
569
+ * or when a name segment consists of 3 or more dots only
570
+ * @private
571
+ */
572
+ function normalize(sResourceName, sBaseName) {
573
+
574
+ const p = sResourceName.search(rDotSegmentAnywhere);
575
+
576
+ // check whether the name needs to be resolved at all - if not, just return the sModuleName as it is.
577
+ if ( p < 0 ) {
578
+ return sResourceName;
579
+ }
580
+
581
+ // if the name starts with a relative segment then there must be a base name (a global sap.ui.require doesn't support relative names)
582
+ if ( p === 0 ) {
583
+ if ( sBaseName == null ) {
584
+ throw new Error("relative name not supported ('" + sResourceName + "'");
585
+ }
586
+ // prefix module name with the parent package
587
+ sResourceName = sBaseName.slice(0, sBaseName.lastIndexOf('/') + 1) + sResourceName;
588
+ }
589
+
590
+ const aSegments = sResourceName.split('/');
591
+
592
+ // process path segments
593
+ let j = 0;
594
+ const l = aSegments.length;
595
+ for (let i = 0; i < l; i++) {
596
+
597
+ const sSegment = aSegments[i];
598
+
599
+ if ( rDotSegment.test(sSegment) ) {
600
+ if (sSegment === '.' || sSegment === '') {
601
+ // ignore '.' as it's just a pointer to current package. ignore '' as it results from double slashes (ignored by browsers as well)
602
+ continue;
603
+ } else if (sSegment === '..') {
604
+ // move to parent directory
605
+ if ( j === 0 ) {
606
+ throw new Error("Can't navigate to parent of root ('" + sResourceName + "')");
607
+ }
608
+ j--;
609
+ } else {
610
+ throw new Error("Illegal path segment '" + sSegment + "' ('" + sResourceName + "')");
611
+ }
612
+ } else {
613
+ aSegments[j++] = sSegment;
614
+ }
615
+
616
+ }
617
+
618
+ aSegments.length = j;
619
+
620
+ return aSegments.join('/');
621
+ }
622
+
623
+ /**
624
+ * Adds a resource path to the resources map.
625
+ *
626
+ * @param {string} sResourceNamePrefix prefix is used as map key
627
+ * @param {string} sUrlPrefix path to the resource
628
+ */
629
+ function registerResourcePath(sResourceNamePrefix, sUrlPrefix) {
630
+ sResourceNamePrefix = String(sResourceNamePrefix || "");
631
+
632
+ if ( sUrlPrefix == null ) {
633
+
634
+ // remove a registered URL prefix, if it wasn't for the empty resource name prefix
635
+ if ( sResourceNamePrefix ) {
636
+ if ( mUrlPrefixes[sResourceNamePrefix] ) {
637
+ delete mUrlPrefixes[sResourceNamePrefix];
638
+ log.info(`registerResourcePath ('${sResourceNamePrefix}') (registration removed)`);
639
+ }
640
+ return;
641
+ }
642
+
643
+ // otherwise restore the default
644
+ sUrlPrefix = DEFAULT_BASE_URL;
645
+ log.info(`registerResourcePath ('${sResourceNamePrefix}') (default registration restored)`);
646
+
647
+ }
648
+
649
+ // cast to string and remove query parameters and/or hash
650
+ sUrlPrefix = pathOnly(String(sUrlPrefix));
651
+
652
+ // ensure that the prefix ends with a '/'
653
+ if ( sUrlPrefix.slice(-1) !== '/' ) {
654
+ sUrlPrefix += '/';
655
+ }
656
+
657
+ mUrlPrefixes[sResourceNamePrefix] = {
658
+ url: sUrlPrefix,
659
+ // calculate absolute URL, only to be used by 'guessResourceName'
660
+ absoluteUrl: resolveURL(sUrlPrefix)
661
+ };
662
+ }
663
+
664
+ /**
665
+ * Retrieves path to a given resource by finding the longest matching prefix for the resource name
666
+ *
667
+ * @param {string} sResourceName name of the resource stored in the resources map
668
+ * @param {string} sSuffix url suffix
669
+ *
670
+ * @returns {string} resource path
671
+ */
672
+ function getResourcePath(sResourceName, sSuffix) {
673
+
674
+ let sNamePrefix = sResourceName;
675
+ let p = sResourceName.length;
676
+
677
+ // search for a registered name prefix, starting with the full name and successively removing one segment
678
+ while ( p > 0 && !mUrlPrefixes[sNamePrefix] ) {
679
+ p = sNamePrefix.lastIndexOf('/');
680
+ // Note: an empty segment at p = 0 (leading slash) will be ignored
681
+ sNamePrefix = p > 0 ? sNamePrefix.slice(0, p) : '';
682
+ }
683
+
684
+ assert((p > 0 || sNamePrefix === '') && mUrlPrefixes[sNamePrefix], "there always must be a mapping");
685
+
686
+ let sPath = mUrlPrefixes[sNamePrefix].url + sResourceName.slice(p + 1); // also skips a leading slash!
687
+
688
+ //remove trailing slash
689
+ if ( sPath.slice(-1) === '/' ) {
690
+ sPath = sPath.slice(0, -1);
691
+ }
692
+ return sPath + (sSuffix || '');
693
+
694
+ }
695
+
696
+ /**
697
+ * Returns the reporting mode for synchronous calls
698
+ *
699
+ * @returns {int} sync call behavior
700
+ */
701
+ function getSyncCallBehavior() {
702
+ return syncCallBehavior;
703
+ }
704
+
705
+ /**
706
+ * Try to find a resource name that would be mapped to the given URL.
707
+ *
708
+ * If multiple path mappings would create a match, the returned name is not necessarily
709
+ * the best (longest) match. The first match which is found, will be returned.
710
+ *
711
+ * When <code>bLoadedResourcesOnly</code> is set, only those resources will be taken
712
+ * into account for which content has been loaded already.
713
+ *
714
+ * @param {string} sURL URL to guess the resource name for
715
+ * @param {boolean} [bLoadedResourcesOnly=false] Whether the guess should be limited to already loaded resources
716
+ * @returns {string|undefined} Resource name or <code>undefined</code> if no matching name could be found
717
+ * @private
718
+ */
719
+ function guessResourceName(sURL, bLoadedResourcesOnly) {
720
+ // Make sure to have an absolute URL without query parameters or hash
721
+ // to check against absolute prefix URLs
722
+ sURL = pathOnly(resolveURL(sURL));
723
+
724
+ for (const sNamePrefix in mUrlPrefixes) {
725
+
726
+ // Note: configured URL prefixes are guaranteed to end with a '/'
727
+ // But to support the legacy scenario promoted by the application tools ( "registerModulePath('Application','Application')" )
728
+ // the prefix check here has to be done without the slash
729
+ const sUrlPrefix = mUrlPrefixes[sNamePrefix].absoluteUrl.slice(0, -1);
730
+
731
+ if ( sURL.startsWith(sUrlPrefix) ) {
732
+
733
+ // calc resource name
734
+ let sResourceName = sNamePrefix + sURL.slice(sUrlPrefix.length);
735
+ // remove a leading '/' (occurs if name prefix is empty and if match was a full segment match
736
+ if ( sResourceName.charAt(0) === '/' ) {
737
+ sResourceName = sResourceName.slice(1);
738
+ }
739
+
740
+ if ( !bLoadedResourcesOnly || mModules[sResourceName]?.data != undefined ) {
741
+ return sResourceName;
742
+ }
743
+ }
744
+ }
745
+ }
746
+
747
+ /**
748
+ * Find the most specific map config that matches the given context resource
749
+ * @param {string} sContext Resource name to be used as context
750
+ * @returns {Object<string,string>|undefined} Most specific map or <code>undefined</code>
751
+ */
752
+ function findMapForContext(sContext) {
753
+ let p, mMap;
754
+ if ( sContext != null ) {
755
+ // maps are defined on module IDs, reduce URN to module ID
756
+ sContext = urnToIDAndType(sContext).id;
757
+ p = sContext.length;
758
+ mMap = mMaps[sContext];
759
+ while ( p > 0 && mMap == null ) {
760
+ p = sContext.lastIndexOf('/');
761
+ if ( p > 0 ) { // Note: an empty segment at p = 0 (leading slash) will be ignored
762
+ sContext = sContext.slice(0, p);
763
+ mMap = mMaps[sContext];
764
+ }
765
+ }
766
+ }
767
+ // if none is found, fallback to '*' map
768
+ return mMap || mMaps['*'];
769
+ }
770
+
771
+ function getMappedName(sResourceName, sRequestingResourceName) {
772
+
773
+ const mMap = findMapForContext(sRequestingResourceName);
774
+
775
+ // resolve relative names
776
+ sResourceName = normalize(sResourceName, sRequestingResourceName);
777
+
778
+ // if there's a map, search for the most specific matching entry
779
+ if ( mMap != null ) {
780
+ // start with the full ID and successively remove one segment
781
+ let sPrefix = urnToIDAndType(sResourceName).id;
782
+ let p = sPrefix.length;
783
+ while ( p > 0 && mMap[sPrefix] == null ) {
784
+ p = sPrefix.lastIndexOf('/');
785
+ // Note: an empty segment at p = 0 (leading slash) will be ignored
786
+ sPrefix = p > 0 ? sPrefix.slice(0, p) : '';
787
+ }
788
+
789
+ if ( p > 0 ) {
790
+ const sMappedResourceName = mMap[sPrefix] + sResourceName.slice(p);
791
+ if ( log.isLoggable() ) {
792
+ log.debug(`module ID ${sResourceName} mapped to ${sMappedResourceName}`);
793
+ }
794
+ return sMappedResourceName; // also skips a leading slash!
795
+ }
796
+ }
797
+
798
+ return sResourceName;
799
+ }
800
+
801
+ function getGlobalObject(oObject, aNames, l, bCreate) {
802
+ for (let i = 0; oObject && i < l; i++) {
803
+ if (!oObject[aNames[i]] && bCreate ) {
804
+ oObject[aNames[i]] = {};
805
+ }
806
+ oObject = oObject[aNames[i]];
807
+ }
808
+ return oObject;
809
+ }
810
+
811
+ function getGlobalProperty(sName) {
812
+ const aNames = sName ? sName.split(".") : [];
813
+
814
+ if ( syncCallBehavior && aNames.length > 1 ) {
815
+ log.error("[nosync] getGlobalProperty called to retrieve global name '" + sName + "'");
816
+ }
817
+
818
+ return getGlobalObject(__global, aNames, aNames.length);
819
+ }
820
+
821
+ function setGlobalProperty(sName, vValue) {
822
+ const aNames = sName ? sName.split(".") : [];
823
+
824
+ if ( aNames.length > 0 ) {
825
+ const oObject = getGlobalObject(__global, aNames, aNames.length - 1, true);
826
+ oObject[aNames[aNames.length - 1]] = vValue;
827
+ }
828
+ }
829
+
830
+ // ---- Modules -------------------------------------------------------------------------------
831
+
832
+ function wrapExport(value) {
833
+ return { moduleExport: value };
834
+ }
835
+
836
+ function unwrapExport(wrapper) {
837
+ return wrapper.moduleExport;
838
+ }
839
+
840
+ /**
841
+ * Module neither has been required nor preloaded nor declared, but someone asked for it.
842
+ */
843
+ const INITIAL = 0,
844
+
845
+ /**
846
+ * Module has been preloaded, but not required or declared.
847
+ */
848
+ PRELOADED = -1,
849
+
850
+ /**
851
+ * Module has been declared.
852
+ */
853
+ LOADING = 1,
854
+
855
+ /**
856
+ * Module has been loaded, but not yet executed.
857
+ */
858
+ LOADED = 2,
859
+
860
+ /**
861
+ * Module is currently being executed
862
+ */
863
+ EXECUTING = 3,
864
+
865
+ /**
866
+ * Module has been loaded and executed without errors.
867
+ */
868
+ READY = 4,
869
+
870
+ /**
871
+ * Module either could not be loaded or execution threw an error
872
+ */
873
+ FAILED = 5,
874
+
875
+ /**
876
+ * Special content value used internally until the content of a module has been determined
877
+ */
878
+ NOT_YET_DETERMINED = {};
879
+
880
+ /**
881
+ * A module/resource as managed by the module system.
882
+ *
883
+ * Each module has the following properties
884
+ * <ul>
885
+ * <li>{int} state one of the module states defined in this function</li>
886
+ * <li>{string} url URL where the module has been loaded from</li>
887
+ * <li>{any} data temp. raw content of the module (between loaded and ready or when preloaded)</li>
888
+ * <li>{string} group the bundle with which a resource was loaded or null</li>
889
+ * <li>{string} error an error description for state <code>FAILED</code></li>
890
+ * <li>{any} content the content of the module as exported via define()<(li>
891
+ * </ul>
892
+ */
893
+ class Module {
894
+
895
+ /**
896
+ * Creates a new Module.
897
+ *
898
+ * @param {string} name Name of the module, including extension
899
+ */
900
+ constructor(name) {
901
+ this.name = name;
902
+ this.state = INITIAL;
903
+ /*
904
+ * Whether processing of the module is complete.
905
+ * This is very similar to, but not the same as state >= READY because declareModule() sets state=READY very early.
906
+ * That state transition is 'legacy' from the library-all files; it needs to be checked whether it can be removed.
907
+ */
908
+ this.settled = false;
909
+ this.url =
910
+ this._deferred =
911
+ this.data =
912
+ this.group =
913
+ this.error =
914
+ this.pending = null;
915
+ this.content = NOT_YET_DETERMINED;
916
+ }
917
+
918
+ deferred() {
919
+ if ( this._deferred == null ) {
920
+ const deferred = this._deferred = {};
921
+ deferred.promise = new Promise(function(resolve,reject) {
922
+ deferred.resolve = resolve;
923
+ deferred.reject = reject;
924
+ });
925
+ // avoid 'Uncaught (in promise)' log entries
926
+ deferred.promise.catch(noop);
927
+ }
928
+ return this._deferred;
929
+ }
930
+
931
+ api() {
932
+ this._api ??= {
933
+ id: this.name.slice(0,-3),
934
+ exports: this._exports = {},
935
+ url: this.url,
936
+ config: noop
937
+ };
938
+ return this._api;
939
+ }
940
+
941
+ /**
942
+ * Sets the module state to READY and either determines the value or sets
943
+ * it from the given parameter.
944
+ * @param {any} value Module value
945
+ */
946
+ ready(value) {
947
+ // should throw, but some tests and apps would fail
948
+ assert(!this.settled, `Module ${this.name} is already settled`);
949
+ this.state = READY;
950
+ this.settled = true;
951
+ if ( arguments.length > 0 ) {
952
+ // check arguments.length to allow a value of undefined
953
+ this.content = value;
954
+ }
955
+ this.deferred().resolve(wrapExport(this.value()));
956
+ if ( this.aliases ) {
957
+ value = this.value();
958
+ this.aliases.forEach((alias) => Module.get(alias).ready(value));
959
+ }
960
+ }
961
+
962
+ failWith(msg, cause) {
963
+ const err = makeModuleError(msg, this, cause);
964
+ this.fail(err);
965
+ return err;
966
+ }
967
+
968
+ fail(err) {
969
+ // should throw, but some tests and apps would fail
970
+ assert(!this.settled, `Module ${this.name} is already settled`);
971
+ this.settled = true;
972
+ if ( this.state !== FAILED ) {
973
+ this.state = FAILED;
974
+ this.error = err;
975
+ this.deferred().reject(err);
976
+ this.aliases?.forEach((alias) => Module.get(alias).fail(err));
977
+ }
978
+ }
979
+
980
+ addPending(sDependency) {
981
+ (this.pending ??= []).push(sDependency);
982
+ }
983
+
984
+ addAlias(sAliasName) {
985
+ (this.aliases ??= []).push(sAliasName);
986
+ // add this module as pending dependency to the original
987
+ Module.get(sAliasName).addPending(this.name);
988
+ }
989
+
990
+ preload(url, data, bundle) {
991
+ if ( this.state === INITIAL && !fnIgnorePreload?.(this.name) ) {
992
+ this.state = PRELOADED;
993
+ this.url = url;
994
+ this.data = data;
995
+ this.group = bundle;
996
+ }
997
+ return this;
998
+ }
999
+
1000
+ /**
1001
+ * Determines the value of this module.
1002
+ *
1003
+ * If the module hasn't been loaded or executed yet, <code>undefined</code> will be returned.
1004
+ *
1005
+ * @returns {any} Export of the module or <code>undefined</code>
1006
+ * @private
1007
+ */
1008
+ value() {
1009
+ if ( this.state === READY ) {
1010
+ if ( this.content === NOT_YET_DETERMINED ) {
1011
+ // Determine the module value lazily.
1012
+ // For AMD modules this has already been done on execution of the factory function.
1013
+ // For other modules that are required synchronously, it has been done after execution.
1014
+ // For the few remaining scenarios (like global scripts), it is done here
1015
+ const oShim = mShims[this.name],
1016
+ sExport = oShim && (Array.isArray(oShim.exports) ? oShim.exports[0] : oShim.exports);
1017
+ // best guess for thirdparty modules or legacy modules that don't use sap.ui.define
1018
+ this.content = getGlobalProperty( sExport || urnToUI5(this.name) );
1019
+ }
1020
+ return this.content;
1021
+ }
1022
+
1023
+ return undefined;
1024
+ }
1025
+
1026
+ /**
1027
+ * Checks whether this module depends on the given module.
1028
+ *
1029
+ * When a module definition (define) is executed, the requested dependencies are added
1030
+ * as 'pending' to the Module instance. This function checks if the oDependantModule is
1031
+ * reachable from this module when following the pending dependency information.
1032
+ *
1033
+ * Note: when module aliases are introduced (all module definitions in a file use an ID that differs
1034
+ * from the request module ID), then the alias module is also added as a "pending" dependency.
1035
+ *
1036
+ * @param {Module} oDependantModule Module which has a dependency to <code>oModule</code>
1037
+ * @returns {boolean} Whether this module depends on the given one.
1038
+ * @private
1039
+ */
1040
+ dependsOn(oDependantModule) {
1041
+ const dependant = oDependantModule.name,
1042
+ visited = Object.create(null),
1043
+ stack = log.isLoggable() ? [this.name, dependant] : undefined;
1044
+
1045
+ // log.debug("checking for a cycle between", this.name, "and", dependant);
1046
+ function visit(mod) {
1047
+ if ( !visited[mod] ) {
1048
+ // log.debug(" ", mod);
1049
+ visited[mod] = true;
1050
+ const pending = mModules[mod]?.pending;
1051
+ if (Array.isArray(pending) &&
1052
+ (pending.includes(dependant) || pending.some(visit)) ) {
1053
+ stack?.push(mod);
1054
+ return true;
1055
+ }
1056
+ }
1057
+ return false;
1058
+ }
1059
+
1060
+ const result = this.name === dependant || visit(this.name);
1061
+ if ( result && stack ) {
1062
+ log.error("Dependency cycle detected: ",
1063
+ stack.reverse().map((entry, idx) => `${"".padEnd(idx)} -> ${entry}`).join("\n").slice(4)
1064
+ );
1065
+ }
1066
+ return result;
1067
+ }
1068
+
1069
+ /**
1070
+ * Find or create a module by its unified resource name.
1071
+ *
1072
+ * If the module doesn't exist yet, a new one is created in state INITIAL.
1073
+ *
1074
+ * @param {string} sModuleName Name of the module in URN syntax
1075
+ * @returns {Module} Module with that name, newly created if it didn't exist yet
1076
+ */
1077
+ static get(sModuleName) {
1078
+ const oModule = mModules[sModuleName] ??= new Module(sModuleName);
1079
+ return oModule;
1080
+ }
1081
+
1082
+ }
1083
+
1084
+ /*
1085
+ * Determines the currently executing module.
1086
+ */
1087
+ function getExecutingModule() {
1088
+ if ( _execStack.length > 0 ) {
1089
+ return _execStack[_execStack.length - 1].name;
1090
+ }
1091
+ return document.currentScript?.getAttribute("data-sap-ui-module");
1092
+ }
1093
+
1094
+ // --------------------------------------------------------------------------------------------
1095
+
1096
+ let _globalDefine,
1097
+ _globalDefineAMD;
1098
+
1099
+ function updateDefineAndInterceptAMDFlag(newDefine) {
1100
+
1101
+ // no change, do nothing
1102
+ if ( _globalDefine === newDefine ) {
1103
+ return;
1104
+ }
1105
+
1106
+ // first cleanup on an old loader
1107
+ if ( _globalDefine ) {
1108
+ // restore old amd flag as normal property
1109
+ Object.defineProperty(_globalDefine, "amd", {
1110
+ value: _globalDefineAMD,
1111
+ configurable: true,
1112
+ enumerable: true,
1113
+ writable: true
1114
+ });
1115
+ _globalDefine =
1116
+ _globalDefineAMD = undefined;
1117
+ }
1118
+
1119
+ // remember the new define
1120
+ _globalDefine = newDefine;
1121
+
1122
+ // intercept access to the 'amd' property of the new define, if it's not our own define
1123
+ if ( newDefine && !newDefine.ui5 ) {
1124
+ _globalDefineAMD = _globalDefine.amd;
1125
+
1126
+ Object.defineProperty(_globalDefine, "amd", {
1127
+ get: function() {
1128
+ const sCurrentModule = getExecutingModule();
1129
+ if ( sCurrentModule && mShims[sCurrentModule]?.amd ) {
1130
+ log.debug(`suppressing define.amd for ${sCurrentModule}`);
1131
+ return undefined;
1132
+ }
1133
+ return _globalDefineAMD;
1134
+ },
1135
+ set: function(newDefineAMD) {
1136
+ _globalDefineAMD = newDefineAMD;
1137
+ log.debug(`define.amd became ${newDefineAMD ? "active" : "unset"}`);
1138
+ },
1139
+ configurable: true // we have to allow a redefine for debug mode or restart from CDN etc.
1140
+ });
1141
+ }
1142
+ }
1143
+
1144
+ updateDefineAndInterceptAMDFlag(__global.define);
1145
+
1146
+ try {
1147
+ Object.defineProperty(__global, "define", {
1148
+ get: function() {
1149
+ return _globalDefine;
1150
+ },
1151
+ set: function(newDefine) {
1152
+ updateDefineAndInterceptAMDFlag(newDefine);
1153
+ log.debug(`define became ${newDefine ? "active" : "unset"}`);
1154
+ },
1155
+ configurable: true // we have to allow a redefine for debug mode or restart from CDN etc.
1156
+ });
1157
+ } catch (e) {
1158
+ log.warning("could not intercept changes to window.define, ui5loader won't be able to detect a change of the AMD loader");
1159
+ }
1160
+
1161
+ // --------------------------------------------------------------------------------------------
1162
+
1163
+ function isModuleError(err) {
1164
+ return err?.name === "ModuleError";
1165
+ }
1166
+
1167
+ /**
1168
+ * Wraps the given 'cause' in a new error with the given message and with name 'ModuleError'.
1169
+ *
1170
+ * The new message and the message of the cause are combined. The stacktrace of the
1171
+ * new error and of the cause are combined (with a separating 'Caused by').
1172
+ *
1173
+ * Instead of the final message string, a template is provided which can contain placeholders
1174
+ * for the module ID ({id}) and module URL ({url}). Providing a template without concrete
1175
+ * values allows to detect the repeated nesting of the same error. In such a case, only
1176
+ * the innermost cause will be kept (affects both, stack trace as well as the cause property).
1177
+ * The message, however, will contain the full chain of module IDs.
1178
+ *
1179
+ * @param {string} template Message string template with placeholders
1180
+ * @param {Module} module Module for which the error occurred
1181
+ * @param {Error} cause original error
1182
+ * @returns {Error} New module error
1183
+ */
1184
+ function makeModuleError(template, module, cause) {
1185
+ let modules = `'${module.name}'`;
1186
+
1187
+ if (isModuleError(cause)) {
1188
+ // update the chain of modules (increasing the indent)
1189
+ modules += `\n -> ${cause._modules.replace(/ -> /g, " -> ")}`;
1190
+ // omit repeated occurrences of the same kind of error
1191
+ if ( template === cause._template ) {
1192
+ cause = cause.cause;
1193
+ }
1194
+ }
1195
+
1196
+ // create the message string from the template and the cause's message
1197
+ const message =
1198
+ template.replace(/\{id\}/, modules).replace(/\{url\}/, module.url)
1199
+ + (cause ? ": " + cause.message : "");
1200
+
1201
+ const error = new Error(message);
1202
+ error.name = "ModuleError";
1203
+ error.cause = cause;
1204
+ if ( cause?.stack ) {
1205
+ error.stack = error.stack + "\nCaused by: " + cause.stack;
1206
+ }
1207
+ // the following properties are only for internal usage
1208
+ error._template = template;
1209
+ error._modules = modules;
1210
+ return error;
1211
+ }
1212
+
1213
+ function declareModule(sModuleName, fnDeprecationMessage) {
1214
+ // sModuleName must be a unified resource name of type .js
1215
+ assert(/\.js$/.test(sModuleName), "must be a Javascript module");
1216
+
1217
+ const oModule = Module.get(sModuleName);
1218
+
1219
+ if ( oModule.state > INITIAL ) {
1220
+ return oModule;
1221
+ }
1222
+
1223
+ if ( log.isLoggable() ) {
1224
+ log.debug(`${sLogPrefix}declare module '${sModuleName}'`);
1225
+ }
1226
+
1227
+ // avoid cycles
1228
+ oModule.state = READY;
1229
+ oModule.deprecation = fnDeprecationMessage || undefined;
1230
+
1231
+ return oModule;
1232
+ }
1233
+
1234
+ /**
1235
+ * Define an already loaded module synchronously.
1236
+ * Finds or creates a module by its unified resource name and resolves it with the given value.
1237
+ *
1238
+ * @param {string} sResourceName Name of the module in URN syntax
1239
+ * @param {any} vValue Content of the module
1240
+ */
1241
+ function defineModuleSync(sResourceName, vValue) {
1242
+ Module.get(sResourceName).ready(vValue);
1243
+ }
1244
+
1245
+ /**
1246
+ * Queue of modules for which sap.ui.define has been called (in async mode), but which have not been executed yet.
1247
+ * When loading modules via script tag, only the onload handler knows the relationship between executed sap.ui.define calls and
1248
+ * module name. It then resolves the pending modules in the queue. Only one entry can get the name of the module
1249
+ * if there are more entries, then this is an error
1250
+ *
1251
+ * @param {boolean} [nested] Whether this is a nested queue used during sync execution of a module
1252
+ */
1253
+ function ModuleDefinitionQueue(nested) {
1254
+ let aQueue = [],
1255
+ iRun = 0,
1256
+ vTimer;
1257
+
1258
+ this.push = function(name, deps, factory, _export) {
1259
+ if ( log.isLoggable() ) {
1260
+ log.debug(sLogPrefix + "pushing define() call"
1261
+ + (document.currentScript ? " from " + document.currentScript.src : "")
1262
+ + " to define queue #" + iRun);
1263
+ }
1264
+
1265
+ const sModule = document.currentScript?.getAttribute('data-sap-ui-module');
1266
+ aQueue.push({
1267
+ name: name,
1268
+ deps: deps,
1269
+ factory: factory,
1270
+ _export: _export,
1271
+ guess: sModule
1272
+ });
1273
+
1274
+ // trigger queue processing via a timer in case the currently executing script is not managed by the loader
1275
+ if ( !vTimer && !nested && sModule == null ) {
1276
+ vTimer = setTimeout(this.process.bind(this, null, "timer"));
1277
+ }
1278
+ };
1279
+
1280
+ this.clear = function() {
1281
+ aQueue = [];
1282
+ if ( vTimer ) {
1283
+ clearTimeout(vTimer);
1284
+ vTimer = null;
1285
+ }
1286
+ };
1287
+
1288
+ /**
1289
+ * Process the queue of module definitions, assuming that the original request was for
1290
+ * <code>oRequestedModule</code>. If there is an unnamed module definition, it is assumed to be
1291
+ * the one for the requested module.
1292
+ *
1293
+ * When called via timer, <code>oRequestedModule</code> will be undefined.
1294
+ *
1295
+ * @param {Module} [oRequestedModule] Module for which the current script was loaded.
1296
+ * @param {string} [sInitiator] A string describing the caller of <code>process</code>
1297
+ */
1298
+ this.process = function(oRequestedModule, sInitiator) {
1299
+ const bLoggable = log.isLoggable();
1300
+ const aQueueCopy = aQueue;
1301
+ const iCurrentRun = iRun++;
1302
+ let sModuleName = null;
1303
+
1304
+ // clear the queue and timer early, we've already taken a copy of the queue
1305
+ this.clear();
1306
+
1307
+
1308
+ // if a module execution error was detected, stop processing the queue
1309
+ if ( oRequestedModule?.execError ) {
1310
+ if ( bLoggable ) {
1311
+ log.debug(`module execution error detected, ignoring queued define calls (${aQueueCopy.length})`);
1312
+ }
1313
+ oRequestedModule.fail(oRequestedModule.execError);
1314
+ return;
1315
+ }
1316
+
1317
+ /*
1318
+ * Name of the requested module, null when unknown or already consumed.
1319
+ *
1320
+ * - when no module request is known (e.g. script was embedded in the page as an unmanaged script tag),
1321
+ * then no name is known and unnamed module definitions will be reported as an error
1322
+ * - multiple unnamed module definitions also are reported as an error
1323
+ * - when the name of a named module definition matches the name of requested module, the name is 'consumed'.
1324
+ * Any later unnamed module definition will be reported as an error, too
1325
+ */
1326
+ sModuleName = oRequestedModule?.name;
1327
+
1328
+ // check whether there's a module definition for the requested module
1329
+ aQueueCopy.forEach((oEntry) => {
1330
+ if ( oEntry.name == null ) {
1331
+ if ( sModuleName != null ) {
1332
+ oEntry.name = sModuleName;
1333
+ sModuleName = null;
1334
+ } else {
1335
+ // multiple modules have been queued, but only one module can inherit the name from the require call
1336
+ if ( strictModuleDefinitions ) {
1337
+ const oError = new Error(
1338
+ "Modules that use an anonymous define() call must be loaded with a require() call; " +
1339
+ "they must not be executed via script tag or nested into other modules. ");
1340
+ if ( oRequestedModule ) {
1341
+ oRequestedModule.fail(oError);
1342
+ } else {
1343
+ throw oError;
1344
+ }
1345
+ }
1346
+ // give anonymous modules a unique pseudo ID
1347
+ oEntry.name = `~anonymous~${++iAnonymousModuleCount}.js`;
1348
+ log.error(
1349
+ "Modules that use an anonymous define() call must be loaded with a require() call; " +
1350
+ "they must not be executed via script tag or nested into other modules. " +
1351
+ "All other usages will fail in future releases or when standard AMD loaders are used. " +
1352
+ "Now using substitute name " + oEntry.name);
1353
+ }
1354
+ } else if ( oRequestedModule && oEntry.name === oRequestedModule.name ) {
1355
+ if ( sModuleName == null && !strictModuleDefinitions ) {
1356
+ // if 'strictModuleDefinitions' is active, double execution will be reported anyhow
1357
+ log.error(
1358
+ "Duplicate module definition: both, an unnamed module and a module with the expected name exist." +
1359
+ "This use case will fail in future releases or when standard AMD loaders are used. ");
1360
+ }
1361
+ sModuleName = null;
1362
+ }
1363
+ });
1364
+
1365
+ // if not, assign an alias if there's at least one queued module definition
1366
+ if ( sModuleName && aQueueCopy.length > 0 ) {
1367
+ if ( bLoggable ) {
1368
+ log.debug(
1369
+ "No queued module definition matches the ID of the request. " +
1370
+ `Now assuming that the first definition '${aQueueCopy[0].name}' is an alias of '${sModuleName}'`);
1371
+ }
1372
+ Module.get(aQueueCopy[0].name).addAlias(sModuleName);
1373
+ sModuleName = null;
1374
+ }
1375
+
1376
+ if ( bLoggable ) {
1377
+ log.debug(sLogPrefix + "[" + sInitiator + "] "
1378
+ + "processing define queue #" + iCurrentRun
1379
+ + (oRequestedModule ? " for '" + oRequestedModule.name + "'" : "")
1380
+ + ` with entries [${aQueueCopy.map((entry) => `'${entry.name}'`)}]`);
1381
+ }
1382
+
1383
+ aQueueCopy.forEach((oEntry) => {
1384
+ // start to resolve the dependencies
1385
+ executeModuleDefinition(oEntry.name, oEntry.deps, oEntry.factory, oEntry._export, /* bAsync = */ true);
1386
+ });
1387
+
1388
+ if ( sModuleName != null && !oRequestedModule.settled ) {
1389
+ // module name still not consumed, might be a non-UI5 module (e.g. in 'global' format)
1390
+ if ( bLoggable ) {
1391
+ log.debug(sLogPrefix + "no queued module definition for the requested module found, assume the module to be ready");
1392
+ }
1393
+ oRequestedModule.data = undefined; // allow GC
1394
+ oRequestedModule.ready(); // no export known, has to be retrieved via global name
1395
+ }
1396
+
1397
+ if ( bLoggable ) {
1398
+ log.debug(sLogPrefix + `processing define queue #${iCurrentRun} done`);
1399
+ }
1400
+ };
1401
+ }
1402
+
1403
+ let queue = new ModuleDefinitionQueue();
1404
+
1405
+ /**
1406
+ * Loads the source for the given module with a sync XHR.
1407
+ * @param {Module} oModule Module to load the source for
1408
+ * @throws {Error} When loading failed for some reason.
1409
+ */
1410
+ function loadSyncXHR(oModule) {
1411
+ const xhr = new XMLHttpRequest();
1412
+
1413
+ function createXHRLoadError(error) {
1414
+ error = new Error(xhr.statusText ? xhr.status + " - " + xhr.statusText : xhr.status);
1415
+ error.name = "XHRLoadError";
1416
+ error.status = xhr.status;
1417
+ error.statusText = xhr.statusText;
1418
+ return error;
1419
+ }
1420
+
1421
+ xhr.addEventListener('load', function(e) {
1422
+ // File protocol (file://) always has status code 0
1423
+ if ( xhr.status === 200 || xhr.status === 0 ) {
1424
+ oModule.state = LOADED;
1425
+ oModule.data = xhr.responseText;
1426
+ } else {
1427
+ oModule.error = createXHRLoadError();
1428
+ }
1429
+ });
1430
+ // Note: according to whatwg spec, error event doesn't fire for sync send(), instead an error is thrown
1431
+ // we register a handler, in case a browser doesn't follow the spec
1432
+ xhr.addEventListener('error', function(e) {
1433
+ oModule.error = createXHRLoadError();
1434
+ });
1435
+ xhr.open('GET', oModule.url, false);
1436
+ try {
1437
+ xhr.send();
1438
+ } catch (error) {
1439
+ oModule.error = error;
1440
+ }
1441
+ }
1442
+
1443
+ /**
1444
+ * Global event handler to detect script execution errors.
1445
+ * @private
1446
+ */
1447
+ window.addEventListener('error', function onUncaughtError(errorEvent) {
1448
+ var sModuleName = document.currentScript?.getAttribute('data-sap-ui-module');
1449
+ var oModule = sModuleName && Module.get(sModuleName);
1450
+ if ( oModule && oModule.execError == null ) {
1451
+ // if a currently executing module can be identified, attach the error to it and suppress reporting
1452
+ if ( log.isLoggable() ) {
1453
+ log.debug(`unhandled exception occurred while executing ${sModuleName}: ${errorEvent.message}`);
1454
+ }
1455
+ oModule.execError = errorEvent.error || {
1456
+ name: 'Error',
1457
+ message: errorEvent.message
1458
+ };
1459
+ return false;
1460
+ }
1461
+ });
1462
+
1463
+ function loadScript(oModule, sAlternativeURL) {
1464
+
1465
+ const oScript = document.createElement('SCRIPT');
1466
+ // Accessing the 'src' property of the script in this strange way prevents Safari 12 (or WebKit) from
1467
+ // wrongly optimizing access. SF12 seems to check at optimization time whether there's a setter for the
1468
+ // property and optimize accordingly. When a setter is defined or changed at a later point in time (e.g.
1469
+ // by the AppCacheBuster), then the optimization seems not to be updated and the new setter is ignored
1470
+ // BCP 1970035485
1471
+ oScript["s" + "rc"] = oModule.url;
1472
+ //oScript.src = oModule.url;
1473
+ oScript.setAttribute("data-sap-ui-module", oModule.name);
1474
+
1475
+ function onload(e) {
1476
+ updateMaxTaskTime();
1477
+ if ( log.isLoggable() ) {
1478
+ log.debug(`JavaScript resource loaded: ${oModule.name}`);
1479
+ }
1480
+ oScript.removeEventListener('load', onload);
1481
+ oScript.removeEventListener('error', onerror);
1482
+ queue.process(oModule, "onload");
1483
+ }
1484
+
1485
+ function onerror(e) {
1486
+ updateMaxTaskTime();
1487
+ oScript.removeEventListener('load', onload);
1488
+ oScript.removeEventListener('error', onerror);
1489
+ if (sAlternativeURL) {
1490
+ log.warning(`retry loading JavaScript resource: ${oModule.name}`);
1491
+ oScript?.parentNode?.removeChild(oScript);
1492
+ oModule.url = sAlternativeURL;
1493
+ loadScript(oModule, /* sAlternativeURL= */ null);
1494
+ return;
1495
+ }
1496
+
1497
+ log.error(`failed to load JavaScript resource: ${oModule.name}`);
1498
+ oModule.failWith("failed to load {id} from {url}", new Error("script load error"));
1499
+ }
1500
+
1501
+ if ( sAlternativeURL !== undefined ) {
1502
+ if ( mShims[oModule.name]?.amd ) {
1503
+ oScript.setAttribute("data-sap-ui-module-amd", "true");
1504
+ }
1505
+ oScript.addEventListener('load', onload);
1506
+ oScript.addEventListener('error', onerror);
1507
+ }
1508
+ document.head.appendChild(oScript);
1509
+
1510
+ }
1511
+
1512
+ /**
1513
+ * If we have knowledge about the dependencies of the given module,
1514
+ * we require them upfront, in parallel to the request for the module or
1515
+ * its containing bundle.
1516
+ *
1517
+ * Note: a dependency is required even when it is in state PRELOADED already.
1518
+ * Reason is that its transitive dependencies might not have been required yet.
1519
+ */
1520
+ function requireDependenciesUpfront(sModuleName) {
1521
+ const knownDependencies = mDepCache[sModuleName];
1522
+ if ( Array.isArray(knownDependencies) ) {
1523
+ mDepCache[sModuleName] = undefined;
1524
+ const missingDeps = [];
1525
+ knownDependencies.forEach((dep) => {
1526
+ dep = getMappedName(dep, sModuleName);
1527
+ // even if a module is PRELOADED, its transitive dependencies might not
1528
+ if ( Module.get(dep).state <= INITIAL ) {
1529
+ missingDeps.push(dep);
1530
+ }
1531
+ });
1532
+ if ( missingDeps.length > 0 ) {
1533
+ log.info(`preload missing dependencies for ${sModuleName}: ${missingDeps}`);
1534
+ missingDeps.forEach((dep) => {
1535
+ if (/\.js$/.test(dep)) {
1536
+ // The resulting promise is ignored here intentionally.
1537
+ // Error handling will happen while module `sModuleName`` is processed
1538
+ requireModule(null, dep, /* always async */ true);
1539
+ } // else: TODO handle non-JS resources, e.g. link rel=prefetch
1540
+ });
1541
+ }
1542
+ }
1543
+ }
1544
+
1545
+ /**
1546
+ * Loads the given module if needed and returns the module export or a promise on it.
1547
+ *
1548
+ * If loading is still ongoing for the requested module and if there is a cycle detected between
1549
+ * the requesting module and the module to be loaded, then <code>undefined</code> (or a promise on
1550
+ * <code>undefined</code>) will be returned as intermediate module export to resolve the cycle.
1551
+ *
1552
+ * @param {Module} oRequestingModule The module in whose context the new module has to be loaded;
1553
+ * this is needed to detect cycles
1554
+ * @param {string} sModuleName Name of the module to be loaded, in URN form and with '.js' extension
1555
+ * @param {boolean} bAsync Whether the operation can be executed asynchronously
1556
+ * @param {boolean} [bSkipShimDeps=false] Whether shim dependencies should be ignored (used by recursive calls)
1557
+ * @param {boolean} [bSkipBundle=false] Whether bundle information should be ignored (used by recursive calls)
1558
+ * @returns {any|Promise} Returns the module export in sync mode or a promise on it in async mode
1559
+ * @throws {Error} When loading failed in sync mode
1560
+ *
1561
+ * @private
1562
+ * @ui5-transform-hint replace-param bAsync true
1563
+ */
1564
+ function requireModule(oRequestingModule, sModuleName, bAsync, bSkipShimDeps, bSkipBundle) {
1565
+
1566
+ // only for robustness, should not be possible by design (all callers append '.js')
1567
+ const oSplitName = urnToBaseIDAndSubType(sModuleName);
1568
+ if ( !oSplitName ) {
1569
+ throw new Error(`can only require Javascript module, not ${sModuleName}`);
1570
+ }
1571
+
1572
+ // Module names should not start with a "/"
1573
+ if (sModuleName[0] == "/") {
1574
+ log.error("Module names that start with a slash should not be used, as they are reserved for future use.");
1575
+ }
1576
+
1577
+ const bLoggable = log.isLoggable();
1578
+
1579
+ const oModule = Module.get(sModuleName);
1580
+ const oShim = mShims[sModuleName];
1581
+
1582
+ if (oModule.deprecation) {
1583
+ const msg = typeof oModule.deprecation === "function" ? oModule.deprecation() : oModule.deprecation;
1584
+ log.error((oRequestingModule ? "(dependency of '" + oRequestingModule.name + "') " : "") + msg);
1585
+ }
1586
+
1587
+ // when there's a shim with dependencies for the module
1588
+ // resolve them first before requiring the module again with bSkipShimDeps = true
1589
+ if ( oShim?.deps && !bSkipShimDeps ) {
1590
+ if ( bLoggable ) {
1591
+ log.debug("require dependencies of raw module " + sModuleName);
1592
+ }
1593
+ return requireAll(oModule, oShim.deps, function() {
1594
+ // set bSkipShimDeps to true to prevent endless recursion
1595
+ return requireModule(oRequestingModule, sModuleName, bAsync, /* bSkipShimDeps = */ true, bSkipBundle);
1596
+ }, function(oErr) {
1597
+ // Note: in async mode, this 'throw' will reject the promise returned by requireAll
1598
+ throw oModule.failWith("Failed to resolve dependencies of {id}", oErr);
1599
+ }, bAsync);
1600
+ }
1601
+
1602
+ // when there's bundle information for the module
1603
+ // require the bundle first before requiring the module again with bSkipBundle = true
1604
+ if ( oModule.state === INITIAL && oModule.group && oModule.group !== sModuleName && !bSkipBundle ) {
1605
+ if ( log.isLoggable(/* INFO */ 3) && Module.get(oModule.group).state === INITIAL ) {
1606
+ log.info(`${sLogPrefix}require bundle '${oModule.group}' containing '${sModuleName}'`);
1607
+ }
1608
+ if ( bAsync ) {
1609
+ const pResult = requireModule(null, oModule.group, bAsync).catch(noop).then(function() {
1610
+ // set bSkipBundle to true to prevent endless recursion
1611
+ return requireModule(oRequestingModule, sModuleName, bAsync, bSkipShimDeps, /* bSkipBundle = */ true);
1612
+ });
1613
+ // start loading of dependencies in parallel
1614
+ requireDependenciesUpfront(sModuleName);
1615
+ return pResult;
1616
+ } else {
1617
+ try {
1618
+ requireModule(null, oModule.group, bAsync);
1619
+ } catch (oError) {
1620
+ if ( bLoggable ) {
1621
+ log.error(sLogPrefix + "require bundle '" + oModule.group + "' failed (ignored)");
1622
+ }
1623
+ }
1624
+ }
1625
+ }
1626
+
1627
+ if ( bLoggable ) {
1628
+ log.debug(sLogPrefix + "require '" + sModuleName + "'"
1629
+ + (oRequestingModule ? " (dependency of '" + oRequestingModule.name + "')" : ""));
1630
+ }
1631
+
1632
+ // check if module has been loaded already
1633
+ if ( oModule.state !== INITIAL ) {
1634
+
1635
+ let bExecutedNow = false;
1636
+
1637
+ if ( oModule.state === EXECUTING && oModule.data != null && !bAsync && oModule.async ) {
1638
+ oModule.state = PRELOADED;
1639
+ oModule.async = bAsync;
1640
+ oModule.pending = null; // TODO or is this still needed ?
1641
+ }
1642
+
1643
+ if ( oModule.state === PRELOADED ) {
1644
+ oModule.state = LOADED;
1645
+ oModule.async = bAsync;
1646
+ bExecutedNow = true;
1647
+ measure && measure.start(sModuleName, "Require module " + sModuleName + " (preloaded)", ["require"]);
1648
+ execModule(sModuleName, bAsync);
1649
+ measure && measure.end(sModuleName);
1650
+ }
1651
+
1652
+ if ( oModule.state === READY ) {
1653
+ if ( !bExecutedNow && bLoggable ) {
1654
+ log.debug(sLogPrefix + "module '" + sModuleName + "' has already been loaded (skipped).");
1655
+ }
1656
+ // Note: this intentionally does not return oModule.promise() as the export might be temporary in case of cycles
1657
+ // or it might have changed after repeated module execution
1658
+ return bAsync ? Promise.resolve(wrapExport(oModule.value())) : wrapExport(oModule.value());
1659
+ } else if ( oModule.state === FAILED ) {
1660
+ if ( bAsync ) {
1661
+ return oModule.deferred().promise;
1662
+ } else {
1663
+ throw oModule.error;
1664
+ }
1665
+ } else {
1666
+ // currently loading or executing
1667
+ if ( bAsync ) {
1668
+ // break up cyclic dependencies
1669
+ if ( oRequestingModule && oModule.dependsOn(oRequestingModule) ) {
1670
+ if ( log.isLoggable() ) {
1671
+ log.debug("cycle detected between '" + oRequestingModule.name + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
1672
+ }
1673
+ // Note: this must be a separate promise as the fulfillment is not the final one
1674
+ return Promise.resolve(wrapExport(undefined));
1675
+ }
1676
+ return oModule.deferred().promise;
1677
+ }
1678
+ if ( !bAsync && !oModule.async ) {
1679
+ // sync pending, return undefined
1680
+ if ( log.isLoggable() ) {
1681
+ log.debug("cycle detected between '" + (oRequestingModule ? oRequestingModule.name : "unknown") + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
1682
+ }
1683
+ return wrapExport(undefined);
1684
+ }
1685
+ // async pending, load sync again
1686
+ log.warning("Sync request triggered for '" + sModuleName + "' while async request was already pending." +
1687
+ " Loading a module twice might cause issues and should be avoided by fully migrating to async APIs.");
1688
+ }
1689
+ }
1690
+
1691
+ measure && measure.start(sModuleName, "Require module " + sModuleName, ["require"]);
1692
+
1693
+ // set marker for loading modules (to break cycles)
1694
+ oModule.state = LOADING;
1695
+ oModule.async = bAsync;
1696
+
1697
+ // if debug is enabled, try to load debug module first
1698
+ const aExtensions = shouldLoadDebugVariant(sModuleName) ? ["-dbg", ""] : [""];
1699
+
1700
+ if ( !bAsync ) {
1701
+
1702
+ for (let i = 0; i < aExtensions.length && oModule.state !== LOADED; i++) {
1703
+ // create module URL for the current extension
1704
+ oModule.url = getResourcePath(oSplitName.baseID, aExtensions[i] + oSplitName.subType);
1705
+ if ( bLoggable ) {
1706
+ log.debug(sLogPrefix + "loading " + (aExtensions[i] ? aExtensions[i] + " version of " : "") + "'" + sModuleName + "' from '" + oModule.url + "' (using sync XHR)");
1707
+ }
1708
+
1709
+ if ( syncCallBehavior ) {
1710
+ const sMsg = "[nosync] loading module '" + oModule.url + "'";
1711
+ if ( syncCallBehavior === 1 ) {
1712
+ log.error(sMsg);
1713
+ } else {
1714
+ throw new Error(sMsg);
1715
+ }
1716
+ }
1717
+
1718
+ // call notification hook
1719
+ ui5Require.load({ completeLoad:noop, async: false }, oModule.url, oSplitName.baseID);
1720
+
1721
+ loadSyncXHR(oModule);
1722
+ }
1723
+
1724
+ if ( oModule.state === LOADING ) {
1725
+ // transition to FAILED
1726
+ oModule.failWith("failed to load {id} from {url}", oModule.error);
1727
+ } else if ( oModule.state === LOADED ) {
1728
+ // execute module __after__ loading it, this reduces the required stack space!
1729
+ execModule(sModuleName, bAsync);
1730
+ }
1731
+
1732
+ measure && measure.end(sModuleName);
1733
+
1734
+ if ( oModule.state !== READY ) {
1735
+ throw oModule.error;
1736
+ }
1737
+
1738
+ return wrapExport(oModule.value());
1739
+
1740
+ } else {
1741
+
1742
+ oModule.url = getResourcePath(oSplitName.baseID, aExtensions[0] + oSplitName.subType);
1743
+ // in debug mode, fall back to the non-dbg source, otherwise try the same source again (for SSO re-connect)
1744
+ const sAltUrl = aExtensions.length === 2 ? getResourcePath(oSplitName.baseID, aExtensions[1] + oSplitName.subType) : oModule.url;
1745
+
1746
+ if ( log.isLoggable() ) {
1747
+ log.debug(sLogPrefix + "loading '" + sModuleName + "' from '" + oModule.url + "' (using <script>)");
1748
+ }
1749
+
1750
+ // call notification hook only once
1751
+ ui5Require.load({ completeLoad:noop, async: true }, sAltUrl, oSplitName.baseID);
1752
+ loadScript(oModule, /* sAlternativeURL= */ sAltUrl);
1753
+
1754
+ // process dep cache info, if this was not done already together with the bundle
1755
+ if ( !bSkipBundle ) {
1756
+ requireDependenciesUpfront(sModuleName);
1757
+ }
1758
+
1759
+ return oModule.deferred().promise;
1760
+ }
1761
+ }
1762
+
1763
+ /**
1764
+ * Note: `sModuleName` must be a normalized resource name of type .js
1765
+ * @private
1766
+ * @ui5-transform-hint replace-param bAsync true
1767
+ */
1768
+ function execModule(sModuleName, bAsync) {
1769
+
1770
+ const oModule = mModules[sModuleName];
1771
+
1772
+ if ( oModule && oModule.state === LOADED && typeof oModule.data !== "undefined" ) {
1773
+
1774
+ const bLoggable = log.isLoggable();
1775
+ const bOldForceSyncDefines = bForceSyncDefines;
1776
+ const oOldQueue = queue;
1777
+ let sOldPrefix, sScript;
1778
+
1779
+ try {
1780
+
1781
+ bForceSyncDefines = !bAsync;
1782
+ queue = new ModuleDefinitionQueue(true);
1783
+
1784
+ if ( bLoggable ) {
1785
+ if ( typeof oModule.data === "string" ) {
1786
+ log.warning(sLogPrefix + "executing '" + sModuleName + "' (using eval)");
1787
+ } else {
1788
+ log.debug(sLogPrefix + "executing '" + sModuleName + "'");
1789
+ }
1790
+ sOldPrefix = sLogPrefix;
1791
+ sLogPrefix = sLogPrefix + ": ";
1792
+ }
1793
+
1794
+ // execute the script in the __global context
1795
+ oModule.state = EXECUTING;
1796
+ _execStack.push({
1797
+ name: sModuleName,
1798
+ used: false
1799
+ });
1800
+ if ( typeof oModule.data === "function" ) {
1801
+ oModule.data.call(__global);
1802
+ } else if ( Array.isArray(oModule.data) ) {
1803
+ ui5Define.apply(null, oModule.data);
1804
+ } else {
1805
+
1806
+ sScript = oModule.data;
1807
+
1808
+ // sourceURL: Firebug, Chrome and Safari debugging help, appending the string seems to cost ZERO performance
1809
+ // Note: make URL absolute so Chrome displays the file tree correctly
1810
+ // Note: do not append if there is already a sourceURL / sourceMappingURL
1811
+ // Note: Safari fails, if sourceURL is the same as an existing XHR URL
1812
+ // Note: Chrome ignores debug files when the same URL has already been load via sourcemap of the bootstrap file (sap-ui-core)
1813
+ // Note: sourcemap annotations URLs in eval'ed sources are resolved relative to the page, not relative to the source
1814
+ if (sScript ) {
1815
+ const oMatch = /\/\/[#@] source(Mapping)?URL=(.*)$/.exec(sScript);
1816
+ if ( oMatch && oMatch[1] && /^[^/]+\.js\.map$/.test(oMatch[2]) ) {
1817
+ // found a sourcemap annotation with a typical UI5 generated relative URL
1818
+ sScript = sScript.slice(0, oMatch.index) + oMatch[0].slice(0, -oMatch[2].length) + resolveURL(oMatch[2], oModule.url);
1819
+ }
1820
+ // @evo-todo use only sourceMappingURL, sourceURL or both?
1821
+ if ( !oMatch || oMatch[1] ) {
1822
+ // write sourceURL if no annotation was there or when it was a sourceMappingURL
1823
+ sScript += "\n//# sourceURL=" + resolveURL(oModule.url) + "?eval";
1824
+ }
1825
+ }
1826
+
1827
+ // framework internal hook to intercept the loaded script and modify
1828
+ // it before executing the script - e.g. useful for client side coverage
1829
+ if (typeof translate === "function") {
1830
+ sScript = translate(sScript, sModuleName);
1831
+ }
1832
+
1833
+ // eval the source in the global context (preventing access to the closure of this function)
1834
+ __global.eval(sScript);
1835
+ }
1836
+ queue.process(oModule, "after eval");
1837
+
1838
+ } catch (err) {
1839
+ oModule.data = undefined;
1840
+ if (isModuleError(err)) {
1841
+ // don't wrap a ModuleError again
1842
+ oModule.fail(err);
1843
+ } else {
1844
+ if (err instanceof SyntaxError && sScript) {
1845
+ // Module execution failed with a syntax error.
1846
+ // If in debug mode, load the script code again via script tag for better error reporting
1847
+ // (but without reacting to load/error events)
1848
+ if (fnIgnorePreload) {
1849
+ oModule.url = URL.createObjectURL(new Blob([sScript], {type: 'text/javascript'}));
1850
+ loadScript(oModule);
1851
+ } else {
1852
+ log.error("A syntax error occurred while evaluating '" + sModuleName + "'"
1853
+ + ", restarting the app with sap-ui-debug=x might reveal the error location");
1854
+ }
1855
+ }
1856
+ oModule.failWith("Failed to execute {id}", err);
1857
+ }
1858
+ } finally {
1859
+
1860
+ _execStack.pop();
1861
+
1862
+ if ( bLoggable ) {
1863
+ sLogPrefix = sOldPrefix;
1864
+ log.debug(sLogPrefix + "finished executing '" + sModuleName + "'");
1865
+ }
1866
+
1867
+ queue = oOldQueue;
1868
+ bForceSyncDefines = bOldForceSyncDefines;
1869
+ }
1870
+ }
1871
+ }
1872
+
1873
+ /**
1874
+ * @private
1875
+ * @ui5-transform-hint replace-param bAsync true
1876
+ */
1877
+ function requireAll(oRequestingModule, aDependencies, fnCallback, fnErrCallback, bAsync) {
1878
+
1879
+ const aModules = [];
1880
+ let sBaseName,
1881
+ oError;
1882
+
1883
+ try {
1884
+ // calculate the base name for relative module names
1885
+ if ( oRequestingModule instanceof Module ) {
1886
+ sBaseName = oRequestingModule.name;
1887
+ } else {
1888
+ sBaseName = oRequestingModule;
1889
+ oRequestingModule = null;
1890
+ }
1891
+ aDependencies = aDependencies.slice();
1892
+ for (let i = 0; i < aDependencies.length; i++) {
1893
+ aDependencies[i] = getMappedName(aDependencies[i] + '.js', sBaseName);
1894
+ }
1895
+ if ( oRequestingModule ) {
1896
+ // remember outgoing dependencies to be able to detect cycles, but ignore pseudo-dependencies
1897
+ aDependencies.forEach((dep) => {
1898
+ if ( !/^(require|exports|module)\.js$/.test(dep) ) {
1899
+ oRequestingModule.addPending(dep);
1900
+ }
1901
+ });
1902
+ }
1903
+
1904
+ for (let i = 0; i < aDependencies.length; i++) {
1905
+ const sDepModName = aDependencies[i];
1906
+ if ( oRequestingModule ) {
1907
+ switch ( sDepModName ) {
1908
+ case 'require.js':
1909
+ // the injected local require should behave like the Standard require (2nd argument = true)
1910
+ aModules[i] = wrapExport(createContextualRequire(sBaseName, true));
1911
+ break;
1912
+ case 'module.js':
1913
+ aModules[i] = wrapExport(oRequestingModule.api());
1914
+ break;
1915
+ case 'exports.js':
1916
+ oRequestingModule.api();
1917
+ aModules[i] = wrapExport(oRequestingModule._exports);
1918
+ break;
1919
+ default:
1920
+ break;
1921
+ }
1922
+ }
1923
+ if ( !aModules[i] ) {
1924
+ aModules[i] = requireModule(oRequestingModule, sDepModName, bAsync);
1925
+ }
1926
+ }
1927
+
1928
+ } catch (err) {
1929
+ oError = err;
1930
+ }
1931
+
1932
+ if ( bAsync ) {
1933
+ const oPromise = oError ? Promise.reject(oError) : Promise.all(aModules);
1934
+ return oPromise.then(fnCallback, fnErrCallback);
1935
+ } else {
1936
+ if ( oError ) {
1937
+ fnErrCallback(oError);
1938
+ } else {
1939
+ return fnCallback(aModules);
1940
+ }
1941
+ }
1942
+ }
1943
+
1944
+ /**
1945
+ * @private
1946
+ * @ui5-transform-hint replace-param bAsync true
1947
+ * @ui5-transform-hint replace-param bExport false
1948
+ */
1949
+ function executeModuleDefinition(sResourceName, aDependencies, vFactory, bExport, bAsync) {
1950
+ const bLoggable = log.isLoggable();
1951
+ sResourceName = normalize(sResourceName);
1952
+
1953
+ if ( bLoggable ) {
1954
+ log.debug(sLogPrefix + "define('" + sResourceName + "', " + "['" + aDependencies.join("','") + "']" + ")");
1955
+ }
1956
+
1957
+ const oModule = declareModule(sResourceName);
1958
+
1959
+ let repeatedExecutionReported = false;
1960
+
1961
+ function shouldSkipExecution() {
1962
+ if ( oModule.settled ) {
1963
+ // avoid double execution of the module, e.g. when async/sync conflict occurred before queue processing
1964
+ if ( oModule.state >= READY && bAsync && oModule.async === false ) {
1965
+ log.warning("Repeated module execution skipped after async/sync conflict for " + oModule.name);
1966
+ return true;
1967
+ }
1968
+
1969
+ // when an inline module definition is executed repeatedly, this is reported but not prevented
1970
+ // Standard AMD loaders don't support this scenario, it needs to be fixed on caller side
1971
+ if ( strictModuleDefinitions && bAsync ) {
1972
+ log.warning("Module '" + oModule.name + "' has been defined more than once. " +
1973
+ "All but the first definition will be ignored, don't try to define the same module again.");
1974
+ return true;
1975
+ }
1976
+
1977
+ if ( !repeatedExecutionReported ) {
1978
+ log.error(
1979
+ "Module '" + oModule.name + "' is executed more than once. " +
1980
+ "This is an unsupported scenario and will fail in future versions of UI5 or " +
1981
+ "when a standard AMD loader is used. Don't define the same module again.");
1982
+ repeatedExecutionReported = true;
1983
+ }
1984
+ }
1985
+ }
1986
+
1987
+ if ( shouldSkipExecution() ) {
1988
+ return;
1989
+ }
1990
+
1991
+ // avoid early evaluation of the module value
1992
+ oModule.content = undefined;
1993
+
1994
+ function onSuccess(aModules) {
1995
+
1996
+ // avoid double execution of the module, e.g. when async/sync conflict occurred while waiting for dependencies
1997
+ if ( shouldSkipExecution() ) {
1998
+ return;
1999
+ }
2000
+
2001
+ // factory
2002
+ if ( bLoggable ) {
2003
+ log.debug(sLogPrefix + "define('" + sResourceName + "'): dependencies resolved, calling factory " + typeof vFactory);
2004
+ }
2005
+
2006
+ if ( bExport && syncCallBehavior !== 2 ) {
2007
+ // ensure parent namespace
2008
+ const aPackages = sResourceName.split('/');
2009
+ if ( aPackages.length > 1 ) {
2010
+ getGlobalObject(__global, aPackages, aPackages.length - 1, true);
2011
+ }
2012
+ }
2013
+
2014
+ if ( typeof vFactory === 'function' ) {
2015
+ // from https://github.com/amdjs/amdjs-api/blob/master/AMD.md
2016
+ // "If the factory function returns a value (an object, function, or any value that coerces to true),
2017
+ // then that value should be assigned as the exported value for the module."
2018
+ try {
2019
+ aModules = aModules.map(unwrapExport);
2020
+ let exports = vFactory.apply(__global, aModules);
2021
+ if ( oModule._api?.exports !== undefined && oModule._api.exports !== oModule._exports ) {
2022
+ exports = oModule._api.exports;
2023
+ } else if ( exports === undefined && oModule._exports ) {
2024
+ exports = oModule._exports;
2025
+ }
2026
+ oModule.content = exports;
2027
+ } catch (error) {
2028
+ const wrappedError = oModule.failWith("failed to execute module factory for '{id}'", error);
2029
+ if ( bAsync ) {
2030
+ // Note: in async mode, the error is reported via the oModule's promise
2031
+ return;
2032
+ }
2033
+ throw wrappedError;
2034
+ }
2035
+ } else {
2036
+ oModule.content = vFactory;
2037
+ }
2038
+
2039
+ // HACK: global export
2040
+ if ( bExport && syncCallBehavior !== 2 ) {
2041
+ if ( oModule.content == null ) {
2042
+ log.error(`Module '${sResourceName}' returned no content, but should export to global?`);
2043
+ } else {
2044
+ if ( bLoggable ) {
2045
+ log.debug(`exporting content of '${sResourceName}': as global object`);
2046
+ }
2047
+ // convert module name to UI5 module name syntax (might fail!)
2048
+ const sModuleName = urnToUI5(sResourceName);
2049
+ setGlobalProperty(sModuleName, oModule.content);
2050
+ }
2051
+ }
2052
+
2053
+ oModule.ready();
2054
+
2055
+ }
2056
+
2057
+ // Note: dependencies will be resolved and converted from RJS to URN inside requireAll
2058
+ requireAll(oModule, aDependencies, bAsync && oModule.data ? scheduleExecution(onSuccess) : onSuccess, function(oErr) {
2059
+ const oWrappedError = oModule.failWith("Failed to resolve dependencies of {id}", oErr);
2060
+ if ( !bAsync ) {
2061
+ throw oWrappedError;
2062
+ }
2063
+ // Note: in async mode, the error is reported via the oModule's promise
2064
+ }, /* bAsync = */ bAsync);
2065
+
2066
+ }
2067
+
2068
+ /**
2069
+ * @private
2070
+ * @ui5-transform-hint replace-param bExport false
2071
+ */
2072
+ function ui5Define(sModuleName, aDependencies, vFactory, bExport) {
2073
+ let sResourceName;
2074
+
2075
+ // optional id
2076
+ if ( typeof sModuleName === 'string' ) {
2077
+ sResourceName = sModuleName + '.js';
2078
+ } else {
2079
+ // shift parameters
2080
+ bExport = vFactory;
2081
+ vFactory = aDependencies;
2082
+ aDependencies = sModuleName;
2083
+ sResourceName = null;
2084
+ }
2085
+
2086
+ // optional array of dependencies
2087
+ if ( !Array.isArray(aDependencies) ) {
2088
+ // shift parameters
2089
+ bExport = vFactory;
2090
+ vFactory = aDependencies;
2091
+ if ( typeof vFactory === 'function' && vFactory.length > 0 ) {
2092
+ aDependencies = ['require', 'exports', 'module'].slice(0, vFactory.length);
2093
+ } else {
2094
+ aDependencies = [];
2095
+ }
2096
+ }
2097
+
2098
+ if ( bForceSyncDefines === false || (bForceSyncDefines == null && bGlobalAsyncMode) ) {
2099
+ queue.push(sResourceName, aDependencies, vFactory, bExport);
2100
+ if ( sResourceName != null ) {
2101
+ const oModule = Module.get(sResourceName);
2102
+ // change state of PRELOADED or INITIAL modules to prevent further requests/executions
2103
+ if ( oModule.state <= INITIAL ) {
2104
+ oModule.state = EXECUTING;
2105
+ oModule.async = true;
2106
+ }
2107
+ }
2108
+ return;
2109
+ }
2110
+
2111
+ // immediate, synchronous execution
2112
+ const oCurrentExecInfo = _execStack.length > 0 ? _execStack[_execStack.length - 1] : null;
2113
+ if ( !sResourceName ) {
2114
+
2115
+ if ( oCurrentExecInfo && !oCurrentExecInfo.used ) {
2116
+ sResourceName = oCurrentExecInfo.name;
2117
+ oCurrentExecInfo.used = true;
2118
+ } else {
2119
+ // give anonymous modules a unique pseudo ID
2120
+ sResourceName = `~anonymous~${++iAnonymousModuleCount}.js`;
2121
+ if ( oCurrentExecInfo ) {
2122
+ sResourceName = oCurrentExecInfo.name.slice(0, oCurrentExecInfo.name.lastIndexOf('/') + 1) + sResourceName;
2123
+ }
2124
+ log.error(
2125
+ "Modules that use an anonymous define() call must be loaded with a require() call; " +
2126
+ "they must not be executed via script tag or nested into other modules. " +
2127
+ "All other usages will fail in future releases or when standard AMD loaders are used " +
2128
+ "or when ui5loader runs in async mode. Now using substitute name " + sResourceName);
2129
+ }
2130
+ } else if ( oCurrentExecInfo?.used && sResourceName !== oCurrentExecInfo.name ) {
2131
+ log.debug(`module names don't match: requested: ${sModuleName}, defined: ${oCurrentExecInfo.name}`);
2132
+ Module.get(oCurrentExecInfo.name).addAlias(sModuleName);
2133
+ }
2134
+ executeModuleDefinition(sResourceName, aDependencies, vFactory, bExport, /* bAsync = */ false);
2135
+
2136
+ }
2137
+
2138
+ /**
2139
+ * The amdDefine() function is closer to the AMD spec, as opposed to sap.ui.define.
2140
+ * It's later assigned as the global define() if the loader is running in amd=true
2141
+ * mode (has to be configured explicitly).
2142
+ */
2143
+ function amdDefine(sModuleName, aDependencies, vFactory) {
2144
+ let oArgs = arguments;
2145
+ const bExportIsSet = typeof oArgs[oArgs.length - 1] === "boolean";
2146
+
2147
+ // bExport parameter is proprietary and should not be used for an AMD compliant define()
2148
+ if (bExportIsSet) {
2149
+ oArgs = Array.prototype.slice.call(oArgs, 0, oArgs.length - 1);
2150
+ }
2151
+
2152
+ ui5Define.apply(this, oArgs);
2153
+ }
2154
+ amdDefine.amd = {}; // identify as AMD-spec compliant loader
2155
+ amdDefine.ui5 = {}; // identify as ui5loader
2156
+
2157
+
2158
+ /**
2159
+ * Create a require() function which acts in the context of the given resource.
2160
+ *
2161
+ * @param {string|null} sContextName Name of the context resource (module) in URN syntax, incl. extension
2162
+ * @param {boolean} bAMDCompliance If set to true, the behavior of the require() function is closer to the AMD specification.
2163
+ * @returns {function} Require function.
2164
+ */
2165
+ function createContextualRequire(sContextName, bAMDCompliance) {
2166
+ const fnRequire = function(vDependencies, fnCallback, fnErrCallback) {
2167
+ assert(typeof vDependencies === 'string' || Array.isArray(vDependencies), "dependency param either must be a single string or an array of strings");
2168
+ assert(fnCallback == null || typeof fnCallback === 'function', "callback must be a function or null/undefined");
2169
+ assert(fnErrCallback == null || typeof fnErrCallback === 'function', "error callback must be a function or null/undefined");
2170
+
2171
+ // Probing for existing module
2172
+ if ( typeof vDependencies === 'string' ) {
2173
+ const sModuleName = getMappedName(vDependencies + '.js', sContextName);
2174
+ const oModule = Module.get(sModuleName);
2175
+
2176
+ if (oModule.deprecation) {
2177
+ const msg = typeof oModule.deprecation === "function" ? oModule.deprecation() : oModule.deprecation;
2178
+ log.error(msg);
2179
+ }
2180
+
2181
+ // check the modules internal state
2182
+ // everything from PRELOADED to LOADED (incl. FAILED) is considered erroneous
2183
+ if (bAMDCompliance && oModule.state !== EXECUTING && oModule.state !== READY) {
2184
+ throw new Error(
2185
+ "Module '" + sModuleName + "' has not been loaded yet. " +
2186
+ "Use require(['" + sModuleName + "']) to load it."
2187
+ );
2188
+ }
2189
+
2190
+ // Module is in state READY or EXECUTING; or require() was called from sap.ui.require().
2191
+ // A modules value might be undefined (no return statement) even though the state is READY.
2192
+ return oModule.value();
2193
+ }
2194
+
2195
+ requireAll(sContextName, vDependencies, function(aModules) {
2196
+ aModules = aModules.map(unwrapExport);
2197
+ if ( typeof fnCallback === 'function' ) {
2198
+ if ( bGlobalAsyncMode ) {
2199
+ fnCallback.apply(__global, aModules);
2200
+ } else {
2201
+ // enforce asynchronous execution of callback even in sync mode
2202
+ simulateAsyncCallback(function() {
2203
+ fnCallback.apply(__global, aModules);
2204
+ });
2205
+ }
2206
+ }
2207
+ }, function(oErr) {
2208
+ if ( typeof fnErrCallback === 'function' ) {
2209
+ if ( bGlobalAsyncMode ) {
2210
+ fnErrCallback.call(__global, oErr);
2211
+ } else {
2212
+ simulateAsyncCallback(function() {
2213
+ fnErrCallback.call(__global, oErr);
2214
+ });
2215
+ }
2216
+ } else {
2217
+ throw oErr;
2218
+ }
2219
+ }, /* bAsync = */ bGlobalAsyncMode);
2220
+
2221
+ // return undefined;
2222
+ };
2223
+ fnRequire.toUrl = function(sName) {
2224
+ const sMappedName = ensureTrailingSlash(getMappedName(sName, sContextName), sName);
2225
+ return toUrl(sMappedName);
2226
+ };
2227
+ return fnRequire;
2228
+ }
2229
+
2230
+ function ensureTrailingSlash(sName, sInput) {
2231
+ //restore trailing slash
2232
+ if (sInput.slice(-1) === "/" && sName.slice(-1) !== "/") {
2233
+ return sName + "/";
2234
+ }
2235
+ return sName;
2236
+ }
2237
+
2238
+ function toUrl(sName) {
2239
+ if (sName.indexOf("/") === 0) {
2240
+ throw new Error(`The provided argument '${sName}' may not start with a slash`);
2241
+ }
2242
+ return ensureTrailingSlash(getResourcePath(sName), sName);
2243
+ }
2244
+
2245
+ /*
2246
+ * UI5 version of require (sap.ui.require)
2247
+ */
2248
+ const ui5Require = createContextualRequire(null, false);
2249
+
2250
+ /*
2251
+ * AMD version of require (window.require)
2252
+ *
2253
+ * Difference between require (sap.ui.require) and amdRequire (window.require):
2254
+ * - require("my/module"), returns undefined if the module was not loaded yet
2255
+ * - amdRequire("my/module"), throws an error if the module was not loaded yet
2256
+ */
2257
+ const amdRequire = createContextualRequire(null, true);
2258
+
2259
+ /** @deprecated as of 1.120 */
2260
+ function requireSync(sModuleName) {
2261
+ sModuleName = getMappedName(sModuleName + '.js');
2262
+ if ( log.isLoggable() ) {
2263
+ log.warning(`sync require of '${sModuleName}'`);
2264
+ }
2265
+ return unwrapExport(requireModule(null, sModuleName, /* bAsync = */ false));
2266
+ }
2267
+
2268
+ /**
2269
+ * @private
2270
+ * @ui5-transform-hint replace-param bExport false
2271
+ */
2272
+ function predefine(sModuleName, aDependencies, vFactory, bExport) {
2273
+ if ( typeof sModuleName !== 'string' ) {
2274
+ throw new Error("predefine requires a module name");
2275
+ }
2276
+ sModuleName = normalize(sModuleName);
2277
+ Module.get(sModuleName + '.js').preload("<unknown>/" + sModuleName, [sModuleName, aDependencies, vFactory, bExport], null);
2278
+ }
2279
+
2280
+ function preload(modules, group, url) {
2281
+ group = group || null;
2282
+ url = url || "<unknown>";
2283
+ for ( let name in modules ) {
2284
+ name = normalize(name);
2285
+ Module.get(name).preload(url + "/" + name, modules[name], group);
2286
+ }
2287
+ }
2288
+
2289
+ /**
2290
+ * Dumps information about the current set of modules and their state.
2291
+ *
2292
+ * @param {int} [iThreshold=-1] Earliest module state for which modules should be reported
2293
+ * @private
2294
+ */
2295
+ function dumpInternals(iThreshold) {
2296
+
2297
+ const states = [PRELOADED, INITIAL, LOADED, READY, FAILED, EXECUTING, LOADING];
2298
+ const stateNames = {
2299
+ [PRELOADED]: 'PRELOADED',
2300
+ [INITIAL]:'INITIAL',
2301
+ [LOADING]: 'LOADING',
2302
+ [LOADED]: 'LOADED',
2303
+ [EXECUTING]: 'EXECUTING',
2304
+ [READY]: 'READY',
2305
+ [FAILED]: 'FAILED'
2306
+ };
2307
+
2308
+ if ( iThreshold == null ) {
2309
+ iThreshold = PRELOADED;
2310
+ }
2311
+
2312
+ /*eslint-disable no-console */
2313
+ const info = log.isLoggable('INFO') ? log.info.bind(log) : console.info.bind(console);
2314
+ /*eslint-enable no-console */
2315
+
2316
+ const aModuleNames = Object.keys(mModules).sort();
2317
+ states.forEach((state) => {
2318
+ if ( state < iThreshold ) {
2319
+ return;
2320
+ }
2321
+ let count = 0;
2322
+ info(stateNames[state] + ":");
2323
+ aModuleNames.forEach((sModule, idx) => {
2324
+ const oModule = mModules[sModule];
2325
+ if ( oModule.state === state ) {
2326
+ let addtlInfo;
2327
+ if ( oModule.state === LOADING ) {
2328
+ const pending = oModule.pending?.reduce((acc, dep) => {
2329
+ const oDepModule = Module.get(dep);
2330
+ if ( oDepModule.state !== READY ) {
2331
+ acc.push( dep + "(" + stateNames[oDepModule.state] + ")");
2332
+ }
2333
+ return acc;
2334
+ }, []);
2335
+ if ( pending?.length > 0 ) {
2336
+ addtlInfo = "waiting for " + pending.join(", ");
2337
+ }
2338
+ } else if ( oModule.state === FAILED ) {
2339
+ addtlInfo = (oModule.error.name || "Error") + ": " + oModule.error.message;
2340
+ }
2341
+ info(" " + (idx + 1) + " " + sModule + (addtlInfo ? " (" + addtlInfo + ")" : ""));
2342
+ count++;
2343
+ }
2344
+ });
2345
+ if ( count === 0 ) {
2346
+ info(" none");
2347
+ }
2348
+ });
2349
+
2350
+ }
2351
+
2352
+ /**
2353
+ * Returns a flat copy of the current set of URL prefixes.
2354
+ *
2355
+ * @private
2356
+ */
2357
+ function getUrlPrefixes() {
2358
+ const mUrlPrefixesCopy = Object.create(null);
2359
+ forEach(mUrlPrefixes, function(sNamePrefix, oUrlInfo) {
2360
+ mUrlPrefixesCopy[sNamePrefix] = oUrlInfo.url;
2361
+ });
2362
+ return mUrlPrefixesCopy;
2363
+ }
2364
+
2365
+ /**
2366
+ * Removes a set of resources from the resource cache.
2367
+ *
2368
+ * @param {string} sName unified resource name of a resource or the name of a preload group to be removed
2369
+ * @param {boolean} [bPreloadGroup=true] whether the name specifies a preload group, defaults to true
2370
+ * @param {boolean} [bUnloadAll] Whether all matching resources should be unloaded, even if they have been executed already.
2371
+ * @param {boolean} [bDeleteExports] Whether exports (global variables) should be destroyed as well. Will be done for UI5 module names only.
2372
+ * @private
2373
+ */
2374
+ function unloadResources(sName, bPreloadGroup, bUnloadAll, bDeleteExports) {
2375
+ const aModules = [];
2376
+
2377
+ if ( bPreloadGroup == null ) {
2378
+ bPreloadGroup = true;
2379
+ }
2380
+
2381
+ if ( bPreloadGroup ) {
2382
+ // collect modules that belong to the given group
2383
+ for ( const sURN in mModules ) {
2384
+ const oModule = mModules[sURN];
2385
+ if ( oModule && oModule.group === sName ) {
2386
+ aModules.push(sURN);
2387
+ }
2388
+ }
2389
+ } else {
2390
+ // single module
2391
+ if ( mModules[sName] ) {
2392
+ aModules.push(sName);
2393
+ }
2394
+ }
2395
+
2396
+ aModules.forEach((sURN) => {
2397
+ const oModule = mModules[sURN];
2398
+ if ( oModule && bDeleteExports && sURN.match(/\.js$/) ) {
2399
+ // @evo-todo move to compat layer?
2400
+ setGlobalProperty(urnToUI5(sURN), undefined);
2401
+ }
2402
+ if ( oModule && (bUnloadAll || oModule.state === PRELOADED) ) {
2403
+ delete mModules[sURN];
2404
+ }
2405
+ });
2406
+ }
2407
+
2408
+ function getModuleContent(name, url) {
2409
+ if ( name ) {
2410
+ name = getMappedName(name);
2411
+ } else {
2412
+ name = guessResourceName(url, true);
2413
+ }
2414
+ const oModule = name && mModules[name];
2415
+ if ( oModule ) {
2416
+ oModule.state = LOADED;
2417
+ return oModule.data;
2418
+ } else {
2419
+ return undefined;
2420
+ }
2421
+ }
2422
+
2423
+ /**
2424
+ * Returns an info about all known resources keyed by their URN.
2425
+ *
2426
+ * If the URN can be converted to a UI5 module name, then the value in the map
2427
+ * will be that name. Otherwise it will be null or undefined.
2428
+ *
2429
+ * @return {Object.<string,string>} Map of all module names keyed by their resource name
2430
+ * @see isDeclared
2431
+ * @private
2432
+ */
2433
+ function getAllModules() {
2434
+ const mSnapshot = Object.create(null);
2435
+ forEach(mModules, function(sURN, oModule) {
2436
+ mSnapshot[sURN] = {
2437
+ state: oModule.state,
2438
+ ui5: urnToUI5(sURN)
2439
+ };
2440
+ });
2441
+ return mSnapshot;
2442
+ }
2443
+
2444
+ function loadJSResourceAsync(sResource, bIgnoreErrors) {
2445
+ sResource = getMappedName(sResource);
2446
+ const promise = requireModule(null, sResource, /* bAsync = */ true).then(unwrapExport);
2447
+ return bIgnoreErrors ? promise.catch(noop) : promise;
2448
+ }
2449
+
2450
+ // ---- config --------------------------------------------------------------------------------
2451
+
2452
+ const mUI5ConfigHandlers = {
2453
+ baseUrl(url) {
2454
+ registerResourcePath("", url);
2455
+ },
2456
+ paths: registerResourcePath, // has length 2
2457
+ shim(module, shim) {
2458
+ if ( Array.isArray(shim) ) {
2459
+ shim = { deps : shim };
2460
+ }
2461
+ mShims[module + '.js'] = shim;
2462
+ },
2463
+ amd(bValue) {
2464
+ bValue = !!bValue;
2465
+ if ( bExposeAsAMDLoader !== bValue ) {
2466
+ bExposeAsAMDLoader = bValue;
2467
+ if (bValue) {
2468
+ vOriginalDefine = __global.define;
2469
+ vOriginalRequire = __global.require;
2470
+ __global.define = amdDefine;
2471
+ __global.require = amdRequire;
2472
+
2473
+ // Enable async loading behaviour implicitly when switching to amd mode
2474
+ bGlobalAsyncMode = true;
2475
+ } else {
2476
+ __global.define = vOriginalDefine;
2477
+ __global.require = vOriginalRequire;
2478
+ // NOTE: Do not set async mode back to false when amd mode gets deactivated
2479
+ }
2480
+ }
2481
+ },
2482
+ async(async) {
2483
+ if (bGlobalAsyncMode && !async) {
2484
+ throw new Error("Changing the ui5loader config from async to sync is not supported. Only a change from sync to async is allowed.");
2485
+ }
2486
+ bGlobalAsyncMode = !!async;
2487
+ },
2488
+ bundles(bundle, modules) {
2489
+ bundle += '.js';
2490
+ modules.forEach(
2491
+ (module) => { Module.get(module + '.js').group = bundle; }
2492
+ );
2493
+ },
2494
+ bundlesUI5(bundle, resources) {
2495
+ resources.forEach(
2496
+ (module) => { Module.get(module).group = bundle; }
2497
+ );
2498
+ },
2499
+ debugSources(debug) {
2500
+ bDebugSources = !!debug;
2501
+ },
2502
+ depCache(module, deps) {
2503
+ mDepCache[module + '.js'] = deps.map((dep) => dep + '.js');
2504
+ },
2505
+ depCacheUI5(module, deps) {
2506
+ mDepCache[module] = deps;
2507
+ },
2508
+ ignoreBundledResources(filter) {
2509
+ if ( filter == null || typeof filter === 'function' ) {
2510
+ fnIgnorePreload = filter;
2511
+ }
2512
+ },
2513
+ map(context, map) {
2514
+ // @evo-todo ignore empty context, empty prefix?
2515
+ if ( map == null ) {
2516
+ delete mMaps[context];
2517
+ } else if ( typeof map === 'string' ) {
2518
+ // SystemJS style config
2519
+ mMaps['*'][context] = map;
2520
+ } else {
2521
+ mMaps[context] ||= Object.create(null);
2522
+ forEach(map, function(alias, name) {
2523
+ mMaps[context][alias] = name;
2524
+ });
2525
+ }
2526
+ },
2527
+ reportSyncCalls(report) {
2528
+ if ( report === 0 || report === 1 || report === 2 ) {
2529
+ syncCallBehavior = report;
2530
+ }
2531
+ },
2532
+ /**
2533
+ * @deprecated As of 1.135, superceded by option <code>amd</code>
2534
+ */
2535
+ noConflict(bValue) {
2536
+ log.warning("Config option 'noConflict' has been deprecated, use option 'amd' instead, if still needed.");
2537
+ mUI5ConfigHandlers.amd(!bValue);
2538
+ }
2539
+ };
2540
+
2541
+ /**
2542
+ * Config handlers used when amd mode is enabled.
2543
+ * References only methods defined in the AMD spec.
2544
+ */
2545
+ const mAMDConfigHandlers = {
2546
+ baseUrl: mUI5ConfigHandlers.baseUrl,
2547
+ paths(module, url) {
2548
+ registerResourcePath(module, resolveURL(url, getResourcePath("") + "/"));
2549
+ },
2550
+ map: mUI5ConfigHandlers.map,
2551
+ shim: mUI5ConfigHandlers.shim
2552
+ };
2553
+
2554
+ /**
2555
+ * Executes all available handlers which are defined in the config object
2556
+ *
2557
+ * @param {object} oCfg config to handle
2558
+ * @param {Object<string,function>} mHandlers all available handlers
2559
+ */
2560
+ function handleConfigObject(oCfg, mHandlers) {
2561
+
2562
+ function processConfig(key, value) {
2563
+ const handler = mHandlers[key];
2564
+ if ( typeof handler === 'function' ) {
2565
+ if ( handler.length === 1) {
2566
+ handler(value);
2567
+ } else if ( value != null ) {
2568
+ forEach(value, handler);
2569
+ }
2570
+ } else {
2571
+ log.warning(`configuration option ${key} not supported (ignored)`);
2572
+ }
2573
+ }
2574
+
2575
+ // Make sure the 'baseUrl' handler is called first as
2576
+ // other handlers (e.g. paths) depend on it
2577
+ if (oCfg.baseUrl) {
2578
+ processConfig("baseUrl", oCfg.baseUrl);
2579
+ }
2580
+
2581
+ forEach(oCfg, function(key, value) {
2582
+ // Ignore "baseUrl" here as it will be handled above
2583
+ if (key !== "baseUrl") {
2584
+ processConfig(key, value);
2585
+ }
2586
+ });
2587
+ }
2588
+
2589
+ function ui5Config(cfg) {
2590
+ if ( cfg === undefined ) {
2591
+ return {
2592
+ amd: bExposeAsAMDLoader,
2593
+ async: bGlobalAsyncMode,
2594
+ /** @deprecated As of 1.135, superceded by option <code>amd</code> */
2595
+ noConflict: !bExposeAsAMDLoader
2596
+ };
2597
+ }
2598
+ handleConfigObject(cfg, mUI5ConfigHandlers);
2599
+ }
2600
+
2601
+ function amdConfig(cfg) {
2602
+ if ( cfg === undefined ) {
2603
+ return undefined;
2604
+ }
2605
+ handleConfigObject(cfg, mAMDConfigHandlers);
2606
+ }
2607
+
2608
+ // expose preload function as property of sap.ui.require
2609
+ ui5Require.preload = preload;
2610
+
2611
+ // @evo-todo really use this hook for loading. But how to differentiate between sync and async?
2612
+ // for now, it is only a notification hook to attach load tests
2613
+ ui5Require.load = function(context, url, id) {
2614
+ };
2615
+
2616
+ const privateAPI = {
2617
+
2618
+ // properties
2619
+ get assert() {
2620
+ return assert;
2621
+ },
2622
+ set assert(v) {
2623
+ assert = v;
2624
+ },
2625
+ get logger() {
2626
+ return log;
2627
+ },
2628
+ set logger(v) {
2629
+ log = v;
2630
+ aEarlyLogs.forEach(({level, message}) => log[level](message));
2631
+ },
2632
+ get measure() {
2633
+ return measure;
2634
+ },
2635
+ set measure(v) {
2636
+ measure = v;
2637
+ },
2638
+ /**
2639
+ * @deprecated As of version 1.120, sync loading is deprecated without replacement due to the deprecation
2640
+ * of sync XMLHttpRequests in the web standard.
2641
+ */
2642
+ get translate() {
2643
+ return translate;
2644
+ },
2645
+ /**
2646
+ * @deprecated As of version 1.120, sync loading is deprecated without replacement due to the deprecation
2647
+ * of sync XMLHttpRequests in the web standard.
2648
+ */
2649
+ set translate(v) {
2650
+ translate = v;
2651
+ },
2652
+ get callbackInMicroTask() {
2653
+ return simulateAsyncCallback === executeInMicroTask;
2654
+ },
2655
+ set callbackInMicroTask(v) {
2656
+ simulateAsyncCallback = v ? executeInMicroTask : executeInSeparateTask;
2657
+ },
2658
+ get maxTaskDuration() {
2659
+ return iMaxTaskDuration;
2660
+ },
2661
+ set maxTaskDuration(v) {
2662
+ updateMaxTaskDuration(v);
2663
+ },
2664
+
2665
+ // methods
2666
+ amdDefine,
2667
+ amdRequire,
2668
+ config: ui5Config,
2669
+ /**
2670
+ * @deprecated As of version 1.120, all usages of this private API have been deprecated
2671
+ */
2672
+ declareModule(sResourceName, fnDeprecationMessage) {
2673
+ /* void */ declareModule(normalize(sResourceName), fnDeprecationMessage);
2674
+ },
2675
+ defineModuleSync,
2676
+ dump: dumpInternals,
2677
+ getAllModules,
2678
+ getModuleContent,
2679
+ getModuleState(sResourceName) {
2680
+ return mModules[sResourceName] ? mModules[sResourceName].state : INITIAL;
2681
+ },
2682
+ getResourcePath,
2683
+ getSyncCallBehavior,
2684
+ getUrlPrefixes,
2685
+ loadJSResourceAsync,
2686
+ resolveURL,
2687
+ guessResourceName,
2688
+ toUrl,
2689
+ /**
2690
+ * @deprecated As of version 1.135 without replacement (private API)
2691
+ */
2692
+ unloadResources
2693
+ };
2694
+
2695
+
2696
+ // establish APIs in the sap.ui namespace
2697
+
2698
+ /**
2699
+ * Root namespace for JavaScript functionality provided by SAP SE.
2700
+ *
2701
+ * @version 1.136.0
2702
+ * @namespace
2703
+ * @public
2704
+ * @name sap
2705
+ */
2706
+ // ui5lint-disable-next-line no-globals
2707
+ const sap = __global.sap = __global.sap || {};
2708
+ sap.ui = sap.ui || {};
2709
+
2710
+ /**
2711
+ * Provides access to UI5 loader configuration.
2712
+ *
2713
+ * The configuration is used by {@link sap.ui.require} and {@link sap.ui.define}.
2714
+ *
2715
+ * @public
2716
+ * @namespace
2717
+ * @ui5-global-only
2718
+ * @name sap.ui.loader
2719
+ */
2720
+ sap.ui.loader = {
2721
+
2722
+ /**
2723
+ * Sets the configuration for the UI5 loader. The configuration can be updated multiple times.
2724
+ * Later changes do not impact modules that have been loaded before.
2725
+ *
2726
+ * If no parameter is given, a partial copy of UI5 loader configuration in use is returned.
2727
+ *
2728
+ * The configuration options are aligned with the "Common Config" draft of the AMD spec
2729
+ * (https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md).
2730
+ *
2731
+ * The following code shows an example of what a UI5 loader configuration might look like:
2732
+ * <pre>
2733
+ *
2734
+ * sap.ui.loader.config({
2735
+ *
2736
+ * // location from where to load all modules by default
2737
+ * baseUrl: '../../resources/',
2738
+ *
2739
+ * paths: {
2740
+ * // load modules whose ID equals to or starts with 'my/module' from example.com
2741
+ * 'my/module': 'https://example.com/resources/my/module'
2742
+ * },
2743
+ *
2744
+ * map: {
2745
+ * // if any module requires 'sinon', load module 'sap/ui/thirdparty/sinon-4'
2746
+ * '*': {
2747
+ * 'sinon': 'sap/ui/thirdparty/sinon-4'
2748
+ * },
2749
+ * // but if a module whose ID equals to or starts with 'app' requires 'sinon'
2750
+ * // then load a legacy version instead
2751
+ * "app": {
2752
+ * 'sinon': 'sap/ui/legacy/sinon'
2753
+ * }
2754
+ * },
2755
+ *
2756
+ * // define two bundles that consists of JS modules only
2757
+ * bundles: {
2758
+ * bundle1: ['module1', 'module2'],
2759
+ * bundle2: ['moduleX', 'moduleY']
2760
+ * },
2761
+ *
2762
+ * // define a bundle that also contains non-JS resources
2763
+ * bundlesUI5: {
2764
+ * 'all.js': ['Component.js', 'manifest.json',
2765
+ * 'App.controller.js', 'App.view.xml']
2766
+ * },
2767
+ *
2768
+ * // activate real async loading and module definitions
2769
+ * // (will become obsolete in 2.0 contexts as async will be the only mode there)
2770
+ * async: true,
2771
+ *
2772
+ * // provide dependency and export metadata for non-UI5 modules
2773
+ * shim: {
2774
+ * 'sap/ui/thirdparty/blanket': {
2775
+ * amd: true,
2776
+ * exports: 'blanket'
2777
+ * }
2778
+ * }
2779
+ *
2780
+ * });
2781
+ *
2782
+ * </pre>
2783
+ *
2784
+ * @param {object} [cfg]
2785
+ * The provided configuration gets merged with the UI5 loader configuration in use.
2786
+ * If <code>cfg</code> is omitted or <code>undefined</code>, a copy of the current configuration
2787
+ * gets returned, containing at least the properties <code>amd</code> and <code>async</code>.
2788
+ *
2789
+ * @param {string} [cfg.baseUrl='./']
2790
+ * Default location to load modules from. If none of the configured <code>paths</code> prefixes
2791
+ * matches a module ID, the module will be loaded from the concatenation of the <code>baseUrl</code>
2792
+ * and the module ID.
2793
+ *
2794
+ * If the <code>baseUrl</code> itself is a relative URL, it is evaluated relative to <code>document.baseURI</code>.
2795
+ *
2796
+ * @param {Object.<string, string>} [cfg.paths]
2797
+ * A map of resource locations keyed by a corresponding module ID prefix.
2798
+ * When a module is to be loaded, the longest key in <code>paths</code> is searched that is a
2799
+ * prefix of the module ID. The module will be loaded from the concatenation of the corresponding
2800
+ * value in <code>paths</code> and the remainder of the module ID (after the prefix). If no entry
2801
+ * in <code>paths</code> matches, then the module will be loaded from the <code>baseUrl</code>.
2802
+ *
2803
+ * The prefixes (keys) must not contain relative segments (./ or ../), a trailing slash will be
2804
+ * removed, and only full name segment matches are considered a match (prefix 'sap/m' does not
2805
+ * match a module ID 'sap/main').
2806
+ *
2807
+ * <b>Note</b>: In contrast to the "Common Config" of the AMD spec, the paths (values in the map)
2808
+ * are interpreted relative to <code>document.baseURI</code>, not relative to <code>cfg.baseUrl</code>.
2809
+ *
2810
+ * @param {Object.<string, Object.<string, string>>} [cfg.map]
2811
+ * A map of maps that defines how to map module IDs to other module IDs (inner maps)
2812
+ * in the context of a specific set of modules (keys of outer map).
2813
+ *
2814
+ * Each key of the outer map represents a module ID prefix that describes the context for which
2815
+ * its value (inner map) has to be used. The special key <code>*</code> describes the default
2816
+ * context which applies for any module. Only the most specific matching context will be taken
2817
+ * into account.
2818
+ *
2819
+ * Each inner map maps a module ID or module ID prefix to another module ID or module ID prefix.
2820
+ * Again, only the most specific match is taken into account and only one mapping is evaluated
2821
+ * (the evaluation of the mappings is not done recursively).
2822
+ *
2823
+ * Matches are always complete matches, a prefix 'a/b/c' does not match the module ID 'a/b/com'.
2824
+ *
2825
+ * @param {Object.<string, {amd: boolean, deps: string[], exports: (string|string[])}>} [cfg.shim]
2826
+ * Defines additional metadata for modules for which the normal behavior of the AMD APIs is
2827
+ * not sufficient.
2828
+ *
2829
+ * A typical example are scripts that don't use <code>define</code> or <code>sap.ui.define</code>,
2830
+ * but export to a global name. With the <code>exports</code> property, one or more export
2831
+ * names can be specified, and the loader can retrieve the exported value after executing the
2832
+ * corresponding module. If such a module has dependencies, they can be specified in the
2833
+ * <code>deps</code> array and are loaded and executed before executing the module.
2834
+ *
2835
+ * The <code>amd</code> flag of a shim is a ui5loader-specific extension of the standard AMD shims.
2836
+ * If set, the ui5loader hides a currently active AMD loader before executing the module
2837
+ * and restores it afterwards. Otherwise, it might miss the export of third party modules that
2838
+ * check for an AMD loader and register with it instead of exporting to a global name. A future
2839
+ * version of the ui5loader might ignore this flag when it acts as an AMD loader by itself.
2840
+ *
2841
+ * <b>Note:</b> The ui5loader does not support the <code>init</code> option described by the
2842
+ * "Common Config" section of the AMD spec.
2843
+ *
2844
+ * @param {Object.<string, string[]>} [cfg.bundles]
2845
+ * A map of arrays that each define the modules contained in a bundle.
2846
+ *
2847
+ * Each key of the map represents the module ID of a bundle file. The array value represents
2848
+ * the set of JavaScript modules (their module IDs) that are contained in the bundle.
2849
+ *
2850
+ * When a module is required that has not been loaded yet, and for which a containing bundle is
2851
+ * known, that bundle will be required first. Only then the original module will be required
2852
+ * again and usually be taken from the just loaded bundle.
2853
+ *
2854
+ * A bundle will be loaded asynchronously only when the loader is in asynchronous mode and when
2855
+ * the request for the contained module originates from an asynchronous API. In all other cases,
2856
+ * the bundle has to be loaded synchronously to fulfill API contracts.
2857
+ *
2858
+ * <b>Note:</b> The loader only supports one containing bundle per module. If a module is declared
2859
+ * to be part of multiple bundles, only the last one will be taken into account.
2860
+ *
2861
+ * This configuration option is basically provided to be compatible with requireJS or SystemJS
2862
+ * configuration.
2863
+ *
2864
+ * @param {Object.<string, string[]>} [cfg.bundlesUI5]
2865
+ * A map of arrays that each define the resources contained in a bundle.
2866
+ *
2867
+ * This is similar to <code>bundles</code>, but all strings are unified resource names including
2868
+ * a file type extension, not only module IDs. This allows to represent more than just JavaScript
2869
+ * modules.
2870
+ *
2871
+ * Each key of the map represents the resource name (in unified resource name syntax) of a bundle
2872
+ * file. The array value represents the set of resources (also in unified resource name syntax)
2873
+ * that are contained in the bundle. The array can contain JavaScript as well as other textual
2874
+ * resource types (e.g. *.xml or *.json resources).
2875
+ *
2876
+ * When a module is required that has not been loaded yet, and for which a containing bundle is
2877
+ * known, that bundle will be required first. Only then the original module will be required
2878
+ * again and usually be taken from the just loaded bundle.
2879
+ *
2880
+ * A bundle will be loaded asynchronously only when the loader is in asynchronous mode and when
2881
+ * the request for the contained module originates from an asynchronous API. In all other cases,
2882
+ * the bundle has to be loaded synchronously to fulfill API contracts.
2883
+ *
2884
+ * <b>Note:</b> The loader only supports one containing bundle per module. If a module is declared
2885
+ * to be part of multiple bundles, only the last one will be taken into account.
2886
+ *
2887
+ * <b>Note:</b> Although non-JS resources can be declared to be part of a bundle, only requests for
2888
+ * JavaScript modules will currently trigger the loading of a bundle.
2889
+ *
2890
+ * @param {boolean} [cfg.async=false]
2891
+ * When set to true, <code>sap.ui.require</code> loads modules asynchronously via script tags and
2892
+ * <code>sap.ui.define</code> executes asynchronously. To enable this feature, it is recommended to
2893
+ * set the attribute <code>data-sap-ui-async="true"</code> on the application bootstrap tag.
2894
+ *
2895
+ * <b>Note:</b> Switching back from async to sync is not supported and trying to do so will throw
2896
+ * an <code>Error</code>
2897
+ *
2898
+ * In the next major version of UI5, this option will become obsolete as async will be the only mode.
2899
+ *
2900
+ * @param {boolean} [cfg.amd=false]
2901
+ * When set to true, the ui5loader will overwrite the global properties <code>define</code>
2902
+ * and <code>require</code> with its own implementations. Any previously active AMD loader will
2903
+ * be remembered internally and can be restored by setting <code>amd</code> to false again.
2904
+ *
2905
+ * <b>Note:</b> Switching to the <code>amd</code> mode, the ui5loader will set <code>async</code>
2906
+ * to true implicitly for activating asynchronous loading. Once the loading behaviour has been
2907
+ * defined to be asynchronous, it can not be changed to synchronous behaviour again, also not
2908
+ * via setting <code>amd</code> to false.
2909
+ *
2910
+ * @returns {{amd: boolean, async: boolean, noConflict: boolean}|undefined} UI5 loader configuration in use.
2911
+ * @throws {Error} When trying to switch back from async mode to sync mode.
2912
+ * @public
2913
+ * @since 1.56.0
2914
+ * @function
2915
+ * @name sap.ui.loader.config
2916
+ * @ui5-global-only
2917
+ */
2918
+ config: ui5Config,
2919
+
2920
+ /**
2921
+ * Internal API of the UI5 loader.
2922
+ *
2923
+ * Must not be used by code outside sap.ui.core.
2924
+ * @name sap.ui.loader._
2925
+ * @private
2926
+ * @ui5-restricted sap.ui.core
2927
+ * @ui5-global-only
2928
+ */
2929
+ _: privateAPI
2930
+ };
2931
+
2932
+ /**
2933
+ * Sets the configuration of the ui5loader. The configuration can be updated multiple times.
2934
+ * Later changes do not impact modules that have been loaded before.
2935
+ *
2936
+ * Setting the <code>amd</code> option of the sap.ui.loader.config to <code>true</code> is a
2937
+ * prerequisite to use the <code>require.config</code> function
2938
+ * (see {@link sap.ui.loader.config sap.ui.loader.config option amd}).
2939
+ *
2940
+ * The ui5loader acts more AMD compliant in relation to resolution of paths defined as
2941
+ * part of the <code>paths</code> configuration option.
2942
+ *
2943
+ * @param {object} cfg The provided configuration gets merged with the UI5 loader configuration in use.
2944
+ *
2945
+ * @param {string} [cfg.baseUrl='./']
2946
+ * Default location to load modules from. If none of the configured <code>paths</code> prefixes
2947
+ * matches a module ID, the module will be loaded from the concatenation of the <code>baseUrl</code>
2948
+ * and the module ID.
2949
+ *
2950
+ * If the <code>baseUrl</code> itself is a relative URL, it is evaluated relative to <code>document.baseURI</code>.
2951
+ *
2952
+ * @param {object} [cfg.paths]
2953
+ * A map of resource locations keyed by a corresponding module ID prefix.
2954
+ * When a module is to be loaded, the longest key in <code>paths</code> is searched that is a
2955
+ * prefix of the module ID. The module will be loaded from the concatenation of the corresponding
2956
+ * value in <code>paths</code> and the remainder of the module ID (after the prefix). If no entry
2957
+ * in <code>paths</code> matches, then the module will be loaded from the <code>baseUrl</code>.
2958
+ *
2959
+ * The prefixes (keys) must not contain relative segments (./ or ../), a trailing slash will be
2960
+ * removed, and only full name segment matches are considered a match (prefix 'sap/m' does not
2961
+ * match a module ID 'sap/main').
2962
+ *
2963
+ * <b>Note</b>: In contrast to the {@link sap.ui.loader.config sap.ui.loader.config option paths},
2964
+ * the paths (values in the map) are interpreted relative to <code>cfg.baseUrl</code>,
2965
+ * not relative to <code>document.baseURI</code>. The behaviour is exactly as described in the "Common Config" draft
2966
+ * of the AMD spec (https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md).
2967
+ *
2968
+ * @param {Object.<string, Object.<string, string>>} [cfg.map]
2969
+ * A map of maps that defines how to map module IDs to other module IDs (inner maps)
2970
+ * in the context of a specific set of modules (keys of outer map).
2971
+ *
2972
+ * Each key of the outer map represents a module ID prefix that describes the context for which
2973
+ * its value (inner map) has to be used. The special key <code>*</code> describes the default
2974
+ * context which applies for any module. Only the most specific matching context will be taken
2975
+ * into account.
2976
+ *
2977
+ * Each inner map maps a module ID or module ID prefix to another module ID or module ID prefix.
2978
+ * Again, only the most specific match is taken into account and only one mapping is evaluated
2979
+ * (the evaluation of the mappings is not done recursively).
2980
+ *
2981
+ * Matches are always complete matches, a prefix 'a/b/c' does not match the module ID 'a/b/com'.
2982
+ *
2983
+ * @param {Object.<string, {deps: string[], exports: (string|string[])}>} [cfg.shim]
2984
+ * Defines additional metadata for modules for which the normal behavior of the AMD APIs is
2985
+ * not sufficient.
2986
+ *
2987
+ * A typical example are scripts that don't use <code>define</code> or <code>sap.ui.define</code>,
2988
+ * but export to a global name. With the <code>exports</code> property, one or more export
2989
+ * names can be specified, and the loader can retrieve the exported value after executing the
2990
+ * corresponding module. If such a module has dependencies, they can be specified in the
2991
+ * <code>deps</code> array and are loaded and executed before executing the module.
2992
+ *
2993
+ * <b>Note:</b> The ui5loader does not support the <code>init</code> option described by the
2994
+ * "Common Config" section of the AMD spec.
2995
+ *
2996
+ * @returns {undefined}
2997
+ * @public
2998
+ * @name require_config
2999
+ * @function
3000
+ */
3001
+ amdRequire.config = amdConfig;
3002
+
3003
+ /**
3004
+ * Defines a JavaScript module with its ID, its dependencies and a module export value or factory.
3005
+ *
3006
+ * The typical and only suggested usage of this method is to have one single, top level call to
3007
+ * <code>sap.ui.define</code> in one JavaScript resource (file). When a module is requested by its
3008
+ * module ID for the first time, the corresponding resource is determined from the ID and the current
3009
+ * {@link sap.ui.loader.config configuration}. The resource will be loaded and executed
3010
+ * which in turn will execute the top level <code>sap.ui.define</code> call.
3011
+ *
3012
+ * If the module ID was omitted from that call, it will be substituted by the ID that was used to
3013
+ * request the module. As a preparation step, the dependencies as well as their transitive dependencies,
3014
+ * will be loaded. Then, the module value (its export) will be determined: if a static value (object, literal)
3015
+ * was given as <code>vFactory</code>, that value will be the module value. If a function was given, that
3016
+ * function will be called (providing the module exports of the declared dependencies as parameters
3017
+ * to the function) and its return value will be used as module export value. The framework internally
3018
+ * associates the resulting value with the module ID and provides it to the original requester of the module.
3019
+ * Whenever the module is requested again, the same export value will be returned (modules are executed only once).
3020
+ *
3021
+ * <i>Example:</i><br>
3022
+ * The following example defines a module, but doesn't hard code the module ID.
3023
+ * If stored in a file 'sap/mylib/SomeClass.js', it can be requested with the ID 'sap/mylib/SomeClass'.
3024
+ * <pre>
3025
+ * sap.ui.define(['./Helper', 'sap/m/Bar'], function(Helper,Bar) {
3026
+ *
3027
+ * // create a new class
3028
+ * var SomeClass = function() {};
3029
+ *
3030
+ * // add methods to its prototype
3031
+ * SomeClass.prototype.foo = function() {
3032
+ *
3033
+ * // use a function from the dependency 'Helper' in the same package (e.g. 'sap/mylib/Helper' )
3034
+ * var mSettings = Helper.foo();
3035
+ *
3036
+ * // create and return an sap.m.Bar (using its local name 'Bar')
3037
+ * return new Bar(mSettings);
3038
+ *
3039
+ * }
3040
+ *
3041
+ * // return the class as module value
3042
+ * return SomeClass;
3043
+ *
3044
+ * });
3045
+ * </pre>
3046
+ *
3047
+ * In another module or in an application HTML page, the {@link sap.ui.require} API can be used
3048
+ * to load the sap/mylib/Something module and to work with it:
3049
+ *
3050
+ * <pre>
3051
+ * sap.ui.require(['sap/mylib/Something'], function(Something) {
3052
+ *
3053
+ * // instantiate a Something and call foo() on it
3054
+ * new Something().foo();
3055
+ *
3056
+ * });
3057
+ * </pre>
3058
+ *
3059
+ *
3060
+ * <h3>Module Name Syntax</h3>
3061
+ *
3062
+ * <code>sap.ui.define</code> uses a simplified variant of the {@link jQuery.sap.getResourcePath
3063
+ * unified resource name} syntax for the module's own name as well as for its dependencies.
3064
+ * The only difference to that syntax is, that for <code>sap.ui.define</code> and
3065
+ * <code>sap.ui.require</code>, the extension (which always would be '.js') has to be omitted.
3066
+ * Both methods always add this extension internally.
3067
+ *
3068
+ * As a convenience, the name of a dependency can start with the segment './' which will be
3069
+ * replaced by the name of the package that contains the currently defined module (relative name).
3070
+ *
3071
+ * It is best practice to omit the name of the defined module (first parameter) and to use
3072
+ * relative names for the dependencies whenever possible. This reduces the necessary configuration,
3073
+ * simplifies renaming of packages and allows to map them to a different namespace.
3074
+ *
3075
+ *
3076
+ * <h3>Dependency to Modules</h3>
3077
+ *
3078
+ * If a dependencies array is given, each entry represents the name of another module that
3079
+ * the currently defined module depends on. All dependency modules are loaded before the export
3080
+ * of the currently defined module is determined. The module export of each dependency module
3081
+ * will be provided as a parameter to a factory function, the order of the parameters will match
3082
+ * the order of the modules in the dependencies array.
3083
+ *
3084
+ * <b>Note:</b> The order in which the dependency modules are <i>executed</i> is <b>not</b>
3085
+ * defined by the order in the dependencies array! The execution order is affected by dependencies
3086
+ * <i>between</i> the dependency modules as well as by their current state (whether a module
3087
+ * already has been loaded or not). Neither module implementations nor dependents that require
3088
+ * a module set must make any assumption about the execution order (other than expressed by
3089
+ * their dependencies).
3090
+ *
3091
+ * <b>Note:</b> A static module export (a literal provided to <code>sap.ui.define</code>) cannot
3092
+ * depend on the module exports of the dependency modules as it has to be calculated before
3093
+ * the dependencies are resolved. As an alternative, modules can define a factory function,
3094
+ * calculate a static export value in that function, potentially based on the dependencies, and
3095
+ * return the result as module export value. The same approach must be taken when the module
3096
+ * export is supposed to be a function.
3097
+ *
3098
+ *
3099
+ * <h3>Asynchronous Contract</h3>
3100
+ *
3101
+ * <code>sap.ui.define</code> is designed to support real Asynchronous Module Definitions (AMD)
3102
+ * in future, although it internally still might use synchronous module loading, depending on
3103
+ * configuration and context. However, callers of <code>sap.ui.define</code> must never rely on
3104
+ * any synchronous behavior that they might observe in a specific test scenario.
3105
+ *
3106
+ * For example, callers of <code>sap.ui.define</code> must not use the module export value
3107
+ * immediately after invoking <code>sap.ui.define</code>:
3108
+ *
3109
+ * <pre>
3110
+ * // COUNTER EXAMPLE HOW __NOT__ TO DO IT
3111
+ *
3112
+ * // define a class Something as AMD module
3113
+ * sap.ui.define('Something', [], function() {
3114
+ * var Something = function() {};
3115
+ * return Something;
3116
+ * });
3117
+ *
3118
+ * // DON'T DO THAT!
3119
+ * // accessing the class _synchronously_ after sap.ui.define was called
3120
+ * new Something();
3121
+ *
3122
+ * </pre>
3123
+ *
3124
+ * Applications that need to ensure synchronous module definition or synchronous loading of dependencies
3125
+ * <b>MUST</b> use the deprecated legacy APIs {@link jQuery.sap.declare} and {@link jQuery.sap.require}.
3126
+ *
3127
+ *
3128
+ * <h3>(No) Global References</h3>
3129
+ *
3130
+ * To be in line with AMD best practices, modules defined with <code>sap.ui.define</code>
3131
+ * should not make any use of global variables if those variables are also available as module
3132
+ * exports. Instead, they should add dependencies to those modules and use the corresponding parameter
3133
+ * of the factory function to access the module exports.
3134
+ *
3135
+ * As the current programming model and the documentation of UI5 heavily rely on global names,
3136
+ * there will be a transition phase where UI5 enables AMD modules and local references to module
3137
+ * exports in parallel to the old global names. The fourth parameter of <code>sap.ui.define</code>
3138
+ * has been added to support that transition phase. When this parameter is set to true, the framework
3139
+ * provides two additional features
3140
+ *
3141
+ * <ol>
3142
+ * <li>Before the factory function is called, the existence of the global parent namespace for
3143
+ * the current module is ensured</li>
3144
+ * <li>The module export returned by the module's factory function will be automatically exported
3145
+ * under the global name which is derived from the ID of the module</li>
3146
+ * </ol>
3147
+ *
3148
+ * The parameter lets the framework know whether any of those two operations is needed or not.
3149
+ * In future versions of UI5, a central configuration option is planned to suppress those 'exports'.
3150
+ *
3151
+ *
3152
+ * <h3>Third Party Modules</h3>
3153
+ * Although third party modules don't use UI5 APIs, they still can be listed as dependencies in
3154
+ * a <code>sap.ui.define</code> call. They will be requested and executed like UI5 modules, but to
3155
+ * make their exports available, so called <em>shims</em> have to be defined.
3156
+ *
3157
+ * Note that UI5 temporarily deactivates an existing AMD loader while it executes third party modules
3158
+ * known to support AMD. This sounds contradictorily at a first glance as UI5 wants to support AMD,
3159
+ * but for now it is necessary to fully support UI5 applications that rely on global names for such modules.
3160
+ *
3161
+ * For third-party modules that UI5 delivers (e.g. those in namespace <code>sap/ui/thirdparty/</code>),
3162
+ * the necessary shims are defined by UI5 itself by executing the private module <code>ui5loader-autoconfig.js</code>
3163
+ * during bootstrap.
3164
+ *
3165
+ * Example:
3166
+ * <pre>
3167
+ * // module 'Something' wants to use third party library 'URI.js'
3168
+ * // It is packaged by UI5 as non-UI5-module 'sap/ui/thirdparty/URI'
3169
+ * // the following shim helps UI5 to correctly load URI.js and to retrieve the module's export value
3170
+ * // Apps don't have to define that shim, it is already applied by ui5loader-autoconfig.js
3171
+ * sap.ui.loader.config({
3172
+ * shim: {
3173
+ * 'sap/ui/thirdparty/URI': {
3174
+ * amd: true, // URI.js reacts on an AMD loader, this flag lets UI5 temp. disable such loaders
3175
+ * exports: 'URI' // name of the global variable under which URI.js exports its module value
3176
+ * }
3177
+ * }
3178
+ * });
3179
+ *
3180
+ * // now the module can be retrieved like other modules
3181
+ * sap.ui.define('Something', ['sap/ui/thirdparty/URI'], function(URIModuleValue) {
3182
+ *
3183
+ * new URIModuleValue(...); // same as the global 'URI' name: new URI(...)
3184
+ *
3185
+ * ...
3186
+ * });
3187
+ * </pre>
3188
+ *
3189
+ *
3190
+ * <h3>Differences to Standard AMD</h3>
3191
+ *
3192
+ * The current implementation of <code>sap.ui.define</code> differs from the AMD specification
3193
+ * (https://github.com/amdjs/amdjs-api) or from concrete AMD loaders like <code>requireJS</code>
3194
+ * in several aspects:
3195
+ * <ul>
3196
+ * <li>The name <code>sap.ui.define</code> is different from the plain <code>define</code>.
3197
+ * This has two reasons: first, it avoids the impression that <code>sap.ui.define</code> is
3198
+ * an exact implementation of an AMD loader. And second, it allows the coexistence of an AMD
3199
+ * loader (e.g. requireJS) and <code>sap.ui.define</code> in one application as long as UI5 or
3200
+ * applications using UI5 are not fully prepared to run with an AMD loader.
3201
+ * Note that the difference of the API names also implies that the UI5 loader can't be used
3202
+ * to load 'real' AMD modules as they expect methods <code>define</code> and <code>require</code>
3203
+ * to be available. Modules that use Unified Module Definition (UMD) syntax, can be loaded,
3204
+ * but only when no AMD loader is present or when they expose their export also to the global
3205
+ * namespace, even when an AMD loader is present (as e.g. jQuery does) or when a shim is
3206
+ * defined for them using the <code>amd:true</code> flag (see example above)</li>
3207
+ * <li>Depending on configuration and the current context, <code>sap.ui.define</code> loads
3208
+ * the dependencies of a module either synchronously using a sync XHR call + eval or asynchronously
3209
+ * via script tags. The sync loading is basically a tribute to the synchronous history of UI5.
3210
+ * There's no way for a module developer to enforce synchronous loading of the dependencies and
3211
+ * on the long run, sync loading will be faded out.
3212
+ * Applications that need to ensure synchronous loading of dependencies <b>MUST</b> use the
3213
+ * deprecated legacy APIs like {@link jQuery.sap.require}.</li>
3214
+ * <li><code>sap.ui.define</code> does not support plugins to use other file types, formats or
3215
+ * protocols. It is not planned to support this in future</li>
3216
+ * <li><code>sap.ui.define</code> does not support absolute URLs as module names (dependencies)
3217
+ * nor does it allow module names that start with a slash. To refer to a module at an absolute
3218
+ * URL, a resource root can be registered that points to that URL (or to a prefix of it).</li>
3219
+ * <li><code>sap.ui.define</code> does <b>not</b> support the 'sugar' of requireJS where CommonJS
3220
+ * style dependency declarations using <code>sap.ui.require("something")</code> are automagically
3221
+ * converted into <code>sap.ui.define</code> dependencies before executing the factory function.</li>
3222
+ * </ul>
3223
+ *
3224
+ *
3225
+ * <h3>Restrictions, Design Considerations</h3>
3226
+ * <ul>
3227
+ * <li><b>Restriction</b>: as dependency management is not supported for Non-UI5 modules, the only way
3228
+ * to ensure proper execution order for such modules currently is to rely on the order in the
3229
+ * dependency array. Obviously, this only works as long as <code>sap.ui.define</code> uses
3230
+ * synchronous loading. It will be enhanced when asynchronous loading is implemented.</li>
3231
+ * <li>It was discussed to enforce asynchronous execution of the module factory function (e.g. with a
3232
+ * timeout of 0). But this would have invalidated the current migration scenario where a
3233
+ * sync <code>jQuery.sap.require</code> call can load a <code>sap.ui.define</code>'ed module.
3234
+ * If the module definition would not execute synchronously, the synchronous contract of the
3235
+ * require call would be broken (default behavior in existing UI5 applications)</li>
3236
+ * <li>A single file must not contain multiple calls to <code>sap.ui.define</code>. Multiple calls
3237
+ * currently are only supported in the so called 'preload' files that the UI5 merge tooling produces.
3238
+ * The exact details of how this works might be changed in future implementations and are not
3239
+ * part of the API contract</li>
3240
+ * </ul>
3241
+ * @param {string} [sModuleName] ID of the module in simplified resource name syntax.
3242
+ * When omitted, the loader determines the ID from the request.
3243
+ * @param {string[]} [aDependencies] List of dependencies of the module
3244
+ * @param {function|any} vFactory The module export value or a function that calculates that value
3245
+ * @param {boolean} [bExport] Whether an export to global names is required - should be used by SAP-owned code only
3246
+ * @since 1.27.0
3247
+ * @public
3248
+ * @see https://github.com/amdjs/amdjs-api
3249
+ * @function
3250
+ * @ui5-global-only
3251
+ * @name sap.ui.define
3252
+ */
3253
+ sap.ui.define = ui5Define;
3254
+
3255
+ /**
3256
+ * @private
3257
+ * @ui5-restricted bundles created with UI5 tooling
3258
+ * @function
3259
+ * @ui5-global-only
3260
+ * @name sap.ui.predefine
3261
+ */
3262
+ sap.ui.predefine = predefine;
3263
+
3264
+ /**
3265
+ * Resolves one or more module dependencies.
3266
+ *
3267
+ * <h3>Synchronous Retrieval of a Single Module Export Value (Probing)</h3>
3268
+ *
3269
+ * When called with a single string, that string is assumed to be the ID of an already loaded
3270
+ * module and the export of that module is returned. If the module has not been loaded yet,
3271
+ * or if it is a Non-UI5 module (e.g. third-party module) without a shim, <code>undefined</code>
3272
+ * is returned.
3273
+ *
3274
+ * This signature variant allows synchronous access to module exports without initiating module loading.
3275
+ *
3276
+ * Sample:
3277
+ * <pre>
3278
+ * var JSONModel = sap.ui.require("sap/ui/model/json/JSONModel");
3279
+ * </pre>
3280
+ *
3281
+ * For modules that are known to be UI5 modules, this signature variant can be used to check whether
3282
+ * the module has been loaded.
3283
+ *
3284
+ *
3285
+ * <h3>Asynchronous Loading of Multiple Modules</h3>
3286
+ *
3287
+ * If an array of strings is given and (optionally) a callback function, then the strings
3288
+ * are interpreted as module IDs and the corresponding modules (and their transitive
3289
+ * dependencies) are loaded. Then the callback function will be called asynchronously.
3290
+ * The module exports of the specified modules will be provided as parameters to the callback
3291
+ * function in the same order in which they appeared in the dependencies array.
3292
+ *
3293
+ * The return value for the asynchronous use case is <code>undefined</code>.
3294
+ *
3295
+ * <pre>
3296
+ * sap.ui.require(['sap/ui/model/json/JSONModel', 'sap/ui/core/UIComponent'], function(JSONModel,UIComponent) {
3297
+ *
3298
+ * var MyComponent = UIComponent.extend('MyComponent', {
3299
+ * ...
3300
+ * });
3301
+ * ...
3302
+ *
3303
+ * });
3304
+ * </pre>
3305
+ *
3306
+ * This method uses the same variation of the {@link jQuery.sap.getResourcePath unified resource name}
3307
+ * syntax that {@link sap.ui.define} uses: module names are specified without the implicit extension '.js'.
3308
+ * Relative module names are not supported.
3309
+ *
3310
+ * @param {string|string[]} vDependencies Dependency (dependencies) to resolve
3311
+ * @param {function} [fnCallback] Callback function to execute after resolving an array of dependencies
3312
+ * @param {function(Error)} [fnErrback] Callback function to execute if an error was detected while loading the
3313
+ * dependencies or executing the factory function. Note that due to browser restrictions
3314
+ * not all errors will be reported via this callback. In general, module loading is
3315
+ * designed for the non-error case. Error handling is not complete.
3316
+ * @returns {any|undefined} A single module export value (sync probing variant) or <code>undefined</code> (async loading variant)
3317
+ * @public
3318
+ * @function
3319
+ * @ui5-global-only
3320
+ * @name sap.ui.require
3321
+ */
3322
+ sap.ui.require = ui5Require;
3323
+
3324
+ /**
3325
+ * Calculates a URL from the provided resource name.
3326
+ *
3327
+ * The calculation takes any configured ID mappings or resource paths into account
3328
+ * (see {@link sap.ui.loader.config config options map and paths}. It also supports relative
3329
+ * segments such as <code>./</code> and <code>../</code> within the path, but not at its beginning.
3330
+ * If relative navigation would cross the root namespace (e.g. <code>sap.ui.require.toUrl("../")</code>)
3331
+ * or when the resource name starts with a slash or with a relative segment, an error is thrown.
3332
+ *
3333
+ * <b>Note:</b> <code>toUrl</code> does not resolve the returned URL; whether it is an absolute
3334
+ * URL or a relative URL depends on the configured <code>baseUrl</code> and <code>paths</code>.
3335
+ *
3336
+ * @example
3337
+ * sap.ui.loader.config({
3338
+ * baseUrl: "/home"
3339
+ * });
3340
+ *
3341
+ * sap.ui.require.toUrl("app/data") === "/home/app/data"
3342
+ * sap.ui.require.toUrl("app/data.json") === "/home/app/data.json"
3343
+ * sap.ui.require.toUrl("app/data/") === "/home/app/data/"
3344
+ * sap.ui.require.toUrl("app/.config") === "/home/app/.config"
3345
+ * sap.ui.require.toUrl("app/test/../data.json") === "/home/data.json"
3346
+ * sap.ui.require.toUrl("app/test/./data.json") === "/home/test/data.json"
3347
+ * sap.ui.require.toUrl("app/../../data") throws Error because root namespace is left
3348
+ * sap.ui.require.toUrl("/app") throws Error because first character is a slash
3349
+ *
3350
+ * @param {string} sName Name of a resource e.g. <code>'app/data.json'</code>
3351
+ * @returns {string} Path to the resource, e.g. <code>'/home/app/data.json'</code>
3352
+ * @see https://github.com/amdjs/amdjs-api/wiki/require#requiretourlstring-
3353
+ * @throws {Error} If the input name is absolute (starts with a slash character <code>'/'</code>),
3354
+ * starts with a relative segment or if resolving relative segments would cross the root
3355
+ * namespace
3356
+ * @public
3357
+ * @name sap.ui.require.toUrl
3358
+ * @function
3359
+ * @ui5-global-only
3360
+ */
3361
+
3362
+ /**
3363
+ * Load a single module synchronously and return its module value.
3364
+ *
3365
+ * Basically, this method is a combination of {@link jQuery.sap.require} and {@link sap.ui.require}.
3366
+ * Its main purpose is to simplify the migration of modules to AMD style in those cases where some dependencies
3367
+ * have to be loaded late (lazy) and synchronously.
3368
+ *
3369
+ * The method accepts a single module name in the same syntax that {@link sap.ui.define} and {@link sap.ui.require}
3370
+ * already use (a simplified variation of the {@link jQuery.sap.getResourcePath unified resource name}:
3371
+ * slash separated names without the implicit extension '.js'). As for <code>sap.ui.require</code>,
3372
+ * relative names (using <code>./</code> or <code>../</code>) are not supported.
3373
+ * If not loaded yet, the named module will be loaded synchronously and the export value of the module will be returned.
3374
+ * While a module is executing, a value of <code>undefined</code> will be returned in case it is required again during
3375
+ * that period of time (e.g. in case of cyclic dependencies).
3376
+ *
3377
+ * <b>Note:</b> the scope of this method is limited to the sap.ui.core library. Callers are strongly encouraged to use
3378
+ * this method only when synchronous loading is unavoidable. Any code that uses this method won't benefit from future
3379
+ * performance improvements that require asynchronous module loading (e.g. HTTP/2). And such code never can comply with
3380
+ * a content security policies (CSP) that forbids 'eval'.
3381
+ *
3382
+ * @param {string} sModuleName Module name in requireJS syntax
3383
+ * @returns {any} Export value of the loaded module (can be <code>undefined</code>)
3384
+ * @private
3385
+ * @ui5-restricted sap.ui.core
3386
+ * @function
3387
+ * @ui5-global-only
3388
+ * @name sap.ui.requireSync
3389
+ * @deprecated As of version 1.120, sync loading is deprecated without replacement due to the deprecation
3390
+ * of sync XMLHttpRequests in the web standard.
3391
+ */
3392
+
3393
+ /** @deprecated */
3394
+ sap.ui.requireSync = requireSync;
3395
+
3396
+ }(globalThis));
3397
+ //@ui5-bundle-raw-include ui5loader-autoconfig.js
3398
+ /*!
3399
+ * OpenUI5
3400
+ * (c) Copyright 2025 SAP SE or an SAP affiliate company.
3401
+ * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
3402
+ */
3403
+
3404
+ /*
3405
+ * IMPORTANT: This is a private module, its API must not be used and is subject to change.
3406
+ * Code other than the OpenUI5 libraries must not introduce dependencies to this module.
3407
+ */
3408
+ (function() {
3409
+ /*
3410
+ * This module tries to detect a bootstrap script tag in the current page and
3411
+ * to derive the path for 'resources/' from it. For that purpose it checks for a
3412
+ * hard coded set of well-known bootstrap script names:
3413
+ * - sap-ui-custom(-suffix)?.js
3414
+ * - sap-ui-core(-suffix)?.js
3415
+ * - jquery.sap.global.js
3416
+ * - ui5loader-autoconfig.js
3417
+ */
3418
+
3419
+ /*global define */
3420
+ "use strict";
3421
+
3422
+ /** BaseConfiguration */
3423
+ var ui5loader = globalThis.sap && globalThis.sap.ui && globalThis.sap.ui.loader;
3424
+
3425
+ if (ui5loader == null) {
3426
+ throw new Error("ui5loader-autoconfig.js: ui5loader is needed, but could not be found");
3427
+ }
3428
+
3429
+ const origDefine = globalThis.define;
3430
+ globalThis.define = function define(moduleId, dependencies, callback) {
3431
+ const imports = dependencies.map((dep) => sap.ui.require(dep));
3432
+ const moduleExport = callback(...imports);
3433
+ ui5loader._.defineModuleSync(`${moduleId}.js`, moduleExport);
3434
+ };
3435
+
3436
+ define("sap/base/strings/_camelize", [], function () {
3437
+ var rCamelCase = /[-\.]([a-z0-9])/ig;
3438
+ var fnCamelize = function (sString) {
3439
+ var sNormalizedString = sString.replace( rCamelCase, function( sMatch, sChar ) {
3440
+ return sChar.toUpperCase();
3441
+ });
3442
+ if (/^[a-z][A-Za-z0-9]*$/.test(sNormalizedString)) {
3443
+ return sNormalizedString;
3444
+ }
3445
+ return undefined;
3446
+ };
3447
+
3448
+ return fnCamelize;
3449
+ });
3450
+
3451
+ /* helper for finding the bootstrap tag */
3452
+ function getBootstrapTag() {
3453
+ var oResult;
3454
+ function check(oScript, rUrlPattern) {
3455
+ var sUrl = oScript && oScript.getAttribute("src");
3456
+ var oMatch = rUrlPattern.exec(sUrl);
3457
+ var oTagInfo;
3458
+ if (oMatch) {
3459
+ oTagInfo = {
3460
+ tag: oScript,
3461
+ url: sUrl,
3462
+ resourceRoot: oMatch[1] || ""
3463
+ };
3464
+ }
3465
+ return oTagInfo;
3466
+ }
3467
+
3468
+ if (globalThis.document) {
3469
+ var rResources = /^((?:.*\/)?resources\/)/,
3470
+ rBootScripts, aScripts, i;
3471
+ // Prefer script tags which have the sap-ui-bootstrap ID
3472
+ // This prevents issues when multiple script tags point to files named
3473
+ // "sap-ui-core.js", for example when using the cache buster for UI5 resources
3474
+ oResult = check(globalThis.document.querySelector('SCRIPT[src][id=sap-ui-bootstrap]'), rResources);
3475
+ if (!oResult) {
3476
+ aScripts = globalThis.document.querySelectorAll('SCRIPT[src]');
3477
+ rBootScripts = /^([^?#]*\/)?(?:sap-ui-(?:core|custom|boot|merged)(?:-[^?#/]*)?|jquery.sap.global|ui5loader(?:-autoconfig)?)\.js(?:[?#]|$)/;
3478
+ for (i = 0; i < aScripts.length; i++) {
3479
+ oResult = check(aScripts[i], rBootScripts);
3480
+ if (oResult) {
3481
+ break;
3482
+ }
3483
+ }
3484
+ }
3485
+ }
3486
+ return oResult || {};
3487
+ }
3488
+
3489
+ /**
3490
+ * @deprecated As of Version 1.120
3491
+ */
3492
+ function _createGlobalConfig() {
3493
+ var sCfgFile = "sap-ui-config.json",
3494
+ url = globalThis["sap-ui-config"];
3495
+
3496
+ if (typeof url === "string") {
3497
+ if (globalThis.XMLHttpRequest) {
3498
+ ui5loader._.logger.warning("Loading external bootstrap configuration from \"" + url + "\". This is a design time feature and not for productive usage!");
3499
+ if (url !== sCfgFile) {
3500
+ ui5loader._.logger.warning("The external bootstrap configuration file should be named \"" + sCfgFile + "\"!");
3501
+ }
3502
+ try {
3503
+
3504
+ var xhr = new XMLHttpRequest();
3505
+ xhr.open("GET", url, false);
3506
+ xhr.setRequestHeader("Accept", "application/json, text/javascript");
3507
+
3508
+ xhr.addEventListener("load", function() {
3509
+ try {
3510
+ if (xhr.responseType === "json") {
3511
+ globalThis["sap-ui-config"] = xhr.response;
3512
+ } else {
3513
+ globalThis["sap-ui-config"] = JSON.parse(xhr.responseText);
3514
+ }
3515
+ } catch (error) {
3516
+ ui5loader._.logger.error("Parsing externalized bootstrap configuration from \"" + url + "\" failed! Reason: " + error + "!");
3517
+ }
3518
+ });
3519
+ xhr.addEventListener("error", function() {
3520
+ ui5loader._.logger.error("Loading externalized bootstrap configuration from \"" + url + "\" failed! Response: " + xhr.status + "!");
3521
+ });
3522
+
3523
+ xhr.send(null);
3524
+ globalThis["sap-ui-config"].__loaded = true;
3525
+
3526
+ } catch (error) {
3527
+ ui5loader._.logger.error("Loading externalized bootstrap configuration from \"" + url + "\" failed! Reason: " + error + "!");
3528
+ }
3529
+ }
3530
+ }
3531
+ var bootstrap = getBootstrapTag();
3532
+ if (bootstrap.tag) {
3533
+ var dataset = bootstrap.tag.dataset;
3534
+ if (dataset["sapUiConfig"]) {
3535
+ var sConfig = dataset["sapUiConfig"];
3536
+ var oParsedConfig;
3537
+ try {
3538
+ oParsedConfig = JSON.parse("{" + sConfig + "}");
3539
+ } catch (exc) {
3540
+ ui5loader._.logger.error("JSON.parse on the data-sap-ui-config attribute failed. Please check the config for JSON syntax violations.");
3541
+ /*eslint-disable no-new-func */
3542
+ oParsedConfig = (new Function("return {" + sConfig + "};"))();
3543
+ /*eslint-enable no-new-func */
3544
+ }
3545
+
3546
+ if (oParsedConfig) {
3547
+ if (!globalThis["sap-ui-config"]) {
3548
+ globalThis["sap-ui-config"] = {};
3549
+ }
3550
+ Object.assign(globalThis["sap-ui-config"], oParsedConfig);
3551
+ }
3552
+ }
3553
+ }
3554
+ }
3555
+
3556
+ /**
3557
+ * @deprecated As of Version 1.120
3558
+ */
3559
+ _createGlobalConfig();
3560
+
3561
+ define("sap/base/config/GlobalConfigurationProvider", [
3562
+ "sap/base/strings/_camelize"
3563
+ ], function (camelize) {
3564
+ var oConfig;
3565
+ var oWriteableConfig = Object.create(null);
3566
+ var rAlias = /^(sapUiXx|sapUi|sap)((?:[A-Z0-9][a-z]*)+)$/; //for getter
3567
+ var mFrozenProperties = Object.create(null);
3568
+ const multipleParams = new Map();
3569
+ var bFrozen = false;
3570
+ var Configuration;
3571
+
3572
+ function createConfig() {
3573
+ oConfig = Object.create(null);
3574
+ globalThis["sap-ui-config"] ??= {};
3575
+ var mOriginalGlobalParams = {};
3576
+ var oGlobalConfig = globalThis["sap-ui-config"];
3577
+ if (typeof oGlobalConfig === "object") {
3578
+ for (var sKey in oGlobalConfig) {
3579
+ var sNormalizedKey = camelize("sapUi-" + sKey);
3580
+ var vFrozenValue = mFrozenProperties[sNormalizedKey];
3581
+ if (!sNormalizedKey) {
3582
+ ui5loader._.logger.error("Invalid configuration option '" + sKey + "' in global['sap-ui-config']!");
3583
+ } else if (Object.hasOwn(oConfig, sNormalizedKey)) {
3584
+ multipleParams.set(sNormalizedKey, mOriginalGlobalParams[sNormalizedKey]);
3585
+ } else if (Object.hasOwn(mFrozenProperties, sNormalizedKey) && oGlobalConfig[sKey] !== vFrozenValue) {
3586
+ oConfig[sNormalizedKey] = vFrozenValue;
3587
+ ui5loader._.logger.error("Configuration option '" + sNormalizedKey + "' was frozen and cannot be changed to " + oGlobalConfig[sKey] + "!");
3588
+ } else {
3589
+ oConfig[sNormalizedKey] = oGlobalConfig[sKey];
3590
+ mOriginalGlobalParams[sNormalizedKey] = sKey;
3591
+ }
3592
+ }
3593
+ }
3594
+ mOriginalGlobalParams = undefined;
3595
+ }
3596
+ function freeze() {
3597
+ if (!bFrozen) {
3598
+ createConfig();
3599
+ Configuration._.invalidate();
3600
+ bFrozen = true;
3601
+ }
3602
+ }
3603
+
3604
+ function get(sKey, bFreeze) {
3605
+ var vValue = oWriteableConfig[sKey] || oConfig[sKey];
3606
+ if (multipleParams.has(sKey)) {
3607
+ ui5loader._.logger.error("Configuration option '" + multipleParams.get(sKey) + "' was set multiple times. Value '" + vValue + "' will be used");
3608
+ multipleParams.delete(sKey);
3609
+ }
3610
+ if (Object.hasOwn(mFrozenProperties,sKey)) {
3611
+ return mFrozenProperties[sKey];
3612
+ }
3613
+ if (!Object.hasOwn(oConfig, sKey) && !Object.hasOwn(oWriteableConfig, sKey)) {
3614
+ var vMatch = sKey.match(rAlias);
3615
+ var sLowerCaseAlias = vMatch ? vMatch[1] + vMatch[2][0] + vMatch[2].slice(1).toLowerCase() : undefined;
3616
+ if (sLowerCaseAlias) {
3617
+ vValue = oWriteableConfig[sLowerCaseAlias] || oConfig[sLowerCaseAlias];
3618
+ }
3619
+ }
3620
+ if (bFreeze) {
3621
+ mFrozenProperties[sKey] = vValue;
3622
+ }
3623
+ return vValue;
3624
+ }
3625
+
3626
+ function set(sKey, vValue) {
3627
+ if (Object.hasOwn(mFrozenProperties, sKey) || bFrozen) {
3628
+ ui5loader._.logger.error("Configuration option '" + sKey + "' was frozen and cannot be changed to " + vValue + "!");
3629
+ } else {
3630
+ oWriteableConfig[sKey] = vValue;
3631
+ }
3632
+ }
3633
+
3634
+ function setConfiguration(Config) {
3635
+ Configuration = Config;
3636
+ }
3637
+
3638
+ var GlobalConfigurationProvider = {
3639
+ get: get,
3640
+ set: set,
3641
+ freeze: freeze,
3642
+ setConfiguration: setConfiguration,
3643
+ /**
3644
+ * @deprecated As of Version 1.120
3645
+ */
3646
+ _: {
3647
+ configLoaded() {
3648
+ return !!globalThis["sap-ui-config"].__loaded;
3649
+ }
3650
+ }
3651
+ };
3652
+
3653
+ createConfig();
3654
+
3655
+ return GlobalConfigurationProvider;
3656
+ });
3657
+
3658
+ define("sap/ui/core/config/BootstrapConfigurationProvider", [
3659
+ "sap/base/strings/_camelize"
3660
+ ], function(camelize) {
3661
+ var oConfig = Object.create(null);
3662
+ var rAlias = /^(sapUiXx|sapUi|sap)((?:[A-Z0-9][a-z]*)+)$/; //for getter
3663
+ const multipleParams = new Map();
3664
+
3665
+ var bootstrap = getBootstrapTag();
3666
+ if (bootstrap.tag) {
3667
+ var dataset = bootstrap.tag.dataset;
3668
+ if (dataset) {
3669
+ for (var sKey in dataset) {
3670
+ var sNormalizedKey = camelize(sKey);
3671
+ if (!sNormalizedKey) {
3672
+ ui5loader._.logger.error("Invalid configuration option '" + sKey + "' in bootstrap!");
3673
+ } else if (Object.hasOwn(oConfig, sNormalizedKey)) {
3674
+ multipleParams.set(sNormalizedKey, sKey);
3675
+ } else {
3676
+ oConfig[sNormalizedKey] = dataset[sKey];
3677
+ }
3678
+ }
3679
+ }
3680
+ }
3681
+
3682
+ function get(sKey) {
3683
+ var vValue = oConfig[sKey];
3684
+ if (multipleParams.has(sKey)) {
3685
+ ui5loader._.logger.error("Configuration option '" + multipleParams.get(sKey) + "' was set multiple times. Value '" + vValue + "' will be used");
3686
+ multipleParams.delete(sKey);
3687
+ }
3688
+ if (vValue === undefined) {
3689
+ var vMatch = sKey.match(rAlias);
3690
+ var sLowerCaseAlias = vMatch ? vMatch[1] + vMatch[2][0] + vMatch[2].slice(1).toLowerCase() : undefined;
3691
+ if (sLowerCaseAlias) {
3692
+ vValue = oConfig[sLowerCaseAlias];
3693
+ }
3694
+ }
3695
+ return vValue;
3696
+ }
3697
+
3698
+ var BootstrapConfigurationProvider = {
3699
+ get: get
3700
+ };
3701
+
3702
+ return BootstrapConfigurationProvider;
3703
+ });
3704
+
3705
+ define("sap/ui/base/config/URLConfigurationProvider", [
3706
+ "sap/base/strings/_camelize"
3707
+ ], function(camelize) {
3708
+ var oConfig = Object.create(null);
3709
+ const multipleParams = new Map();
3710
+
3711
+ if (globalThis.location) {
3712
+ oConfig = Object.create(null);
3713
+ var mOriginalUrlParams = {};
3714
+ var sLocation = globalThis.location.search;
3715
+ var urlParams = new URLSearchParams(sLocation);
3716
+ urlParams.forEach(function(value, key) {
3717
+ const bSapParam = /sap\-?([Uu]?i\-?)?/.test(key);
3718
+ var sNormalizedKey = camelize(key);
3719
+ if (sNormalizedKey) {
3720
+ if (Object.hasOwn(oConfig, sNormalizedKey)) {
3721
+ multipleParams.set(sNormalizedKey, mOriginalUrlParams[sNormalizedKey]);
3722
+ } else {
3723
+ oConfig[sNormalizedKey] = value;
3724
+ mOriginalUrlParams[sNormalizedKey] = key;
3725
+ }
3726
+ } else if (bSapParam) {
3727
+ ui5loader._.logger.error("Invalid configuration option '" + key + "' in url!");
3728
+ }
3729
+ });
3730
+ mOriginalUrlParams = undefined;
3731
+ }
3732
+
3733
+ function get(sKey) {
3734
+ if (multipleParams.has(sKey)) {
3735
+ ui5loader._.logger.error("Configuration option '" + multipleParams.get(sKey) + "' was set multiple times. Value '" + oConfig[sKey] + "' will be used");
3736
+ multipleParams.delete(sKey);
3737
+ }
3738
+ return oConfig[sKey];
3739
+ }
3740
+
3741
+ var URLConfigurationProvider = {
3742
+ external: true,
3743
+ get: get
3744
+ };
3745
+
3746
+ return URLConfigurationProvider;
3747
+ });
3748
+
3749
+ define("sap/ui/base/config/MetaConfigurationProvider", [
3750
+ "sap/base/strings/_camelize"
3751
+ ], function (camelize) {
3752
+ var oConfig = Object.create(null);
3753
+ const multipleParams = new Map();
3754
+
3755
+ if (globalThis.document) {
3756
+ oConfig = Object.create(null);
3757
+ var mOriginalTagNames = {};
3758
+ var allMetaTags = globalThis.document.querySelectorAll("meta");
3759
+ allMetaTags.forEach(function(tag) {
3760
+ var sNormalizedKey = camelize(tag.name);
3761
+ const bSapParam = /sap\-?([Uu]?i\-?)?/.test(tag.name);
3762
+ if (sNormalizedKey) {
3763
+ if (Object.hasOwn(oConfig, sNormalizedKey)) {
3764
+ multipleParams.set(sNormalizedKey, mOriginalTagNames[sNormalizedKey]);
3765
+ } else {
3766
+ oConfig[sNormalizedKey] = tag.content;
3767
+ mOriginalTagNames[sNormalizedKey] = tag.name;
3768
+ }
3769
+ } else if (tag.name && bSapParam) { // tags without explicit name (tag.name === "") are ignored silently
3770
+ ui5loader._.logger.error("Invalid configuration option '" + tag.name + "' in meta tag!");
3771
+ }
3772
+ });
3773
+ mOriginalTagNames = undefined;
3774
+ }
3775
+
3776
+ function get(sKey) {
3777
+ if (multipleParams.has(sKey)) {
3778
+ ui5loader._.logger.error("Configuration option '" + multipleParams.get(sKey) + "' was set multiple times. Value '" + oConfig[sKey] + "' will be used");
3779
+ multipleParams.delete(sKey);
3780
+ }
3781
+ return oConfig[sKey];
3782
+ }
3783
+
3784
+ var MetaConfigurationProvider = {
3785
+ get: get
3786
+ };
3787
+
3788
+ return MetaConfigurationProvider;
3789
+ });
3790
+
3791
+ define("sap/base/config/_Configuration", [
3792
+ "sap/base/config/GlobalConfigurationProvider"
3793
+ ], function _Configuration(GlobalConfigurationProvider) {
3794
+ var rValidKey = /^[a-z][A-Za-z0-9]*$/;
3795
+ var rXXAlias = /^(sapUi(?!Xx))(.*)$/;
3796
+ var mCache = Object.create(null);
3797
+ var aProvider = [GlobalConfigurationProvider];
3798
+ var mUrlParamOptions = {
3799
+ name: "sapUiIgnoreUrlParams",
3800
+ type: "boolean"
3801
+ };
3802
+ var mInternalDefaultValues = {
3803
+ "boolean": false,
3804
+ "code": undefined,
3805
+ "integer": 0,
3806
+ "string": "",
3807
+ "string[]": [],
3808
+ "function[]": [],
3809
+ "function": undefined,
3810
+ "object": {},
3811
+ "mergedObject": {}
3812
+ };
3813
+
3814
+ /**
3815
+ * Enum for available types of configuration entries.
3816
+ *
3817
+ * @enum {string}
3818
+ * @alias module:sap/base/config.Type
3819
+ * @private
3820
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3821
+ */
3822
+ var TypeEnum = {
3823
+ /**
3824
+ * defaultValue: false
3825
+ * @private
3826
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3827
+ */
3828
+ "Boolean": "boolean",
3829
+ /**
3830
+ * defaultValue: undefined
3831
+ * @private
3832
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3833
+ * @deprecated As of Version 1.120
3834
+ */
3835
+ "Code": "code",
3836
+ /**
3837
+ * defaultValue: 0
3838
+ * @private
3839
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3840
+ */
3841
+ "Integer": "integer",
3842
+ /**
3843
+ * defaultValue: ""
3844
+ * @private
3845
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3846
+ */
3847
+ "String": "string",
3848
+ /**
3849
+ * defaultValue: []
3850
+ * @private
3851
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3852
+ */
3853
+ "StringArray": "string[]",
3854
+ /**
3855
+ * defaultValue: []
3856
+ * @private
3857
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3858
+ */
3859
+ "FunctionArray": "function[]",
3860
+ /**
3861
+ * defaultValue: undefined
3862
+ * @private
3863
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3864
+ */
3865
+ "Function": "function",
3866
+ /**
3867
+ * defaultValue: {}
3868
+ * @private
3869
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3870
+ */
3871
+ "Object": "object",
3872
+ /**
3873
+ * defaultValue: {}
3874
+ * @private
3875
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
3876
+ */
3877
+ "MergedObject": "mergedObject"
3878
+ };
3879
+
3880
+ var bGlobalIgnoreExternal = get(mUrlParamOptions);
3881
+
3882
+ function deepClone(src) {
3883
+ if (src == null) {
3884
+ return src;
3885
+ } else if (Array.isArray(src)) {
3886
+ return cloneArray(src);
3887
+ } else if (typeof src === "object") {
3888
+ return cloneObject(src);
3889
+ } else {
3890
+ return src;
3891
+ }
3892
+ }
3893
+
3894
+ function cloneArray(src) {
3895
+ var aClone = [];
3896
+ for (var i = 0; i < src.length; i++) {
3897
+ aClone.push(deepClone(src[i]));
3898
+ }
3899
+
3900
+ return aClone;
3901
+ }
3902
+
3903
+ function cloneObject(src) {
3904
+ var oClone = {};
3905
+
3906
+ for (var key in src) {
3907
+ if (key === "__proto__") {
3908
+ continue;
3909
+ }
3910
+ oClone[key] = deepClone(src[key]);
3911
+ }
3912
+
3913
+ return oClone;
3914
+ }
3915
+
3916
+ /** Register a new Configuration provider
3917
+ *
3918
+ * @name module:sap/base/config.registerProvider
3919
+ * @function
3920
+ * @param {object} oProvider The provider instance
3921
+ * @private
3922
+ * @ui5-restricted sap.ui.core
3923
+ */
3924
+ function registerProvider(oProvider) {
3925
+ if (aProvider.indexOf(oProvider) === -1) {
3926
+ aProvider.push(oProvider);
3927
+ invalidate();
3928
+ bGlobalIgnoreExternal = get(mUrlParamOptions);
3929
+ }
3930
+ }
3931
+
3932
+ /**
3933
+ * Converts a given value to the given type.
3934
+ *
3935
+ * @name module:sap/base/config.convertToType
3936
+ * @function
3937
+ * @param {any} vValue The value to be converted
3938
+ * @param {string} vType The resulting type
3939
+ * @param {string} [sName] The property name of the enumeration to check
3940
+ * @returns {any} The converted value
3941
+ * @throws {TypeError} Throws an TypeError if the given value could not be converted to the requested type
3942
+ *
3943
+ * @private
3944
+ */
3945
+ function convertToType(vValue, vType, sName) {
3946
+ if (vValue === undefined || vValue === null) {
3947
+ return vValue;
3948
+ }
3949
+
3950
+ if (typeof vType === "string") {
3951
+ switch (vType) {
3952
+ case TypeEnum.Boolean:
3953
+ if (typeof vValue === "string") {
3954
+ return vValue.toLowerCase() === "true" || vValue.toLowerCase() === "x";
3955
+ } else {
3956
+ vValue = !!vValue;
3957
+ }
3958
+ break;
3959
+ /**
3960
+ * @deprecated As of Version 1.120
3961
+ */
3962
+ case TypeEnum.Code:
3963
+ vValue = typeof vValue === "function" ? vValue : String(vValue);
3964
+ break;
3965
+ case TypeEnum.Integer:
3966
+ if (typeof vValue === "string") {
3967
+ vValue = parseInt(vValue);
3968
+ }
3969
+ if (typeof vValue !== 'number' && isNaN(vValue)) {
3970
+ throw new TypeError("unsupported value");
3971
+ }
3972
+ break;
3973
+ case TypeEnum.String:
3974
+ vValue = '' + vValue; // enforce string
3975
+ break;
3976
+ case TypeEnum.StringArray:
3977
+ if (Array.isArray(vValue)) {
3978
+ return vValue;
3979
+ } else if (typeof vValue === "string") {
3980
+ // enforce array
3981
+ vValue = vValue ? vValue.split(/[,;]/).map(function(s) {
3982
+ return s.trim();
3983
+ }) : [];
3984
+ return vValue;
3985
+ } else {
3986
+ throw new TypeError("unsupported value");
3987
+ }
3988
+ case TypeEnum.FunctionArray:
3989
+ vValue.forEach(function(fnFunction) {
3990
+ if ( typeof fnFunction !== "function" ) {
3991
+ throw new TypeError("Not a function: " + fnFunction);
3992
+ }
3993
+ });
3994
+ break;
3995
+ case TypeEnum.Function:
3996
+ if (typeof vValue !== "function") {
3997
+ throw new TypeError("unsupported value");
3998
+ }
3999
+ break;
4000
+ case TypeEnum.Object:
4001
+ case TypeEnum.MergedObject:
4002
+ if (typeof vValue === "string") {
4003
+ vValue = JSON.parse(vValue);
4004
+ }
4005
+ if (typeof vValue !== "object") {
4006
+ throw new TypeError("unsupported value");
4007
+ }
4008
+ break;
4009
+ default:
4010
+ throw new TypeError("unsupported type");
4011
+ }
4012
+ } else if (typeof vType === "object" && !Array.isArray(vType)) {
4013
+ vValue = checkEnum(vType, vValue, sName);
4014
+ } else if (typeof vType === "function") {
4015
+ vValue = vType(vValue);
4016
+ } else {
4017
+ throw new TypeError("unsupported type");
4018
+ }
4019
+
4020
+ return vValue;
4021
+ }
4022
+
4023
+ /**
4024
+ * Checks if a value exists within an enumerable list.
4025
+ *
4026
+ * @name module:sap/base/config._.checkEnum
4027
+ * @function
4028
+ * @param {object} oEnum Enumeration object with values for validation
4029
+ * @param {string} sValue Value to check against enumerable list
4030
+ * @param {string} sPropertyName Name of the property which is checked
4031
+ * @returns {string} Value passed to the function for check
4032
+ * @throws {TypeError} If the value could not be found, an TypeError is thrown
4033
+ *
4034
+ * @private
4035
+ */
4036
+ function checkEnum(oEnum, sValue, sPropertyName) {
4037
+ var aValidValues = [];
4038
+ for (var sKey in oEnum) {
4039
+ if (oEnum.hasOwnProperty(sKey)) {
4040
+ if (oEnum[sKey] === sValue) {
4041
+ return sValue;
4042
+ }
4043
+ aValidValues.push(oEnum[sKey]);
4044
+ }
4045
+ }
4046
+ throw new TypeError("Unsupported Enumeration value for " + sPropertyName + ", valid values are: " + aValidValues.join(", "));
4047
+ }
4048
+
4049
+ /**
4050
+ * Generic getter for configuration options that are not explicitly exposed via a dedicated own getter.
4051
+ *
4052
+ * @name module:sap/base/config.get
4053
+ * @function
4054
+ * @param {object} mOptions The options object that contains the following properties
4055
+ * @param {string} mOptions.name Name of the configuration parameter. Must start with 'sapUi/sapUiXx' prefix followed by letters only. The name must be camel-case
4056
+ * @param {module:sap/base/config.Type|object<string, string>|function} mOptions.type Type of the configuration parameter. This argument can be a <code>module:sap/base/config.Type</code>, object or function.
4057
+ * @param {any} [mOptions.defaultValue=undefined] Default value of the configuration parameter corresponding to the given type or a function returning the default value.
4058
+ * @param {boolean} [mOptions.external=false] Whether external (e.g. url-) parameters should be included or not
4059
+ * @param {boolean} [mOptions.freeze=false] Freezes parameter and parameter can't be changed afterwards.
4060
+ * @returns {any} Value of the configuration parameter
4061
+ * @throws {TypeError} Throws an error if the given parameter name does not match the definition.
4062
+ * @private
4063
+ * @ui5-restricted sap.ui.core, sap.fl, sap.ui.intergration, sap.ui.export
4064
+ */
4065
+ function get(mOptions) {
4066
+ if (typeof mOptions.name !== "string" || !rValidKey.test(mOptions.name)) {
4067
+ throw new TypeError(
4068
+ "Invalid configuration key '" + mOptions.name + "'!"
4069
+ );
4070
+ }
4071
+ var sCacheKey = mOptions.name;
4072
+ if (mOptions.provider) {
4073
+ sCacheKey += "-" + mOptions.provider.getId();
4074
+ }
4075
+ if (!(sCacheKey in mCache)) {
4076
+ mOptions = Object.assign({}, mOptions);
4077
+ var vValue;
4078
+
4079
+ var bIgnoreExternal = bGlobalIgnoreExternal || !mOptions.external;
4080
+ var sName = mOptions.name;
4081
+ var vMatch = sName.match(rXXAlias);
4082
+ var vDefaultValue = mOptions.hasOwnProperty("defaultValue") ? mOptions.defaultValue : mInternalDefaultValues[mOptions.type];
4083
+
4084
+ const aAllProvider = [...aProvider, ...(mOptions.provider ? [mOptions.provider] : [])];
4085
+
4086
+ for (var i = aAllProvider.length - 1; i >= 0; i--) {
4087
+ if (!aAllProvider[i].external || !bIgnoreExternal) {
4088
+ const vProviderValue = convertToType(aAllProvider[i].get(sName, mOptions.freeze), mOptions.type, mOptions.name);
4089
+ if (vProviderValue !== undefined) {
4090
+ if (mOptions.type === TypeEnum.MergedObject) {
4091
+ vValue = Object.assign({}, vProviderValue, vValue);
4092
+ } else {
4093
+ vValue = vProviderValue;
4094
+ break;
4095
+ }
4096
+ }
4097
+ }
4098
+ }
4099
+ if (vValue === undefined && (vMatch && vMatch[1] === "sapUi")) {
4100
+ mOptions.name = vMatch[1] + "Xx" + vMatch[2];
4101
+ vValue = get(mOptions);
4102
+ }
4103
+ if (vValue === undefined) {
4104
+ if (typeof vDefaultValue === 'function') {
4105
+ vDefaultValue = vDefaultValue();
4106
+ }
4107
+ vValue = vDefaultValue;
4108
+ }
4109
+ mCache[sCacheKey] = vValue;
4110
+ }
4111
+ var vCachedValue = mCache[sCacheKey];
4112
+ if (typeof mOptions.type !== 'function' && (mOptions.type === TypeEnum.StringArray || mOptions.type === TypeEnum.Object || mOptions.type === TypeEnum.MergedObject)) {
4113
+ vCachedValue = deepClone(vCachedValue);
4114
+ }
4115
+ return vCachedValue;
4116
+ }
4117
+
4118
+ function invalidate() {
4119
+ mCache = Object.create(null);
4120
+ }
4121
+
4122
+ var Configuration = {
4123
+ get: get,
4124
+ registerProvider: registerProvider,
4125
+ Type: TypeEnum,
4126
+ _: {
4127
+ checkEnum: checkEnum,
4128
+ invalidate: invalidate
4129
+ }
4130
+ };
4131
+
4132
+ //forward Configuration to Global provider to invalidate the cache when freezing
4133
+ GlobalConfigurationProvider.setConfiguration(Configuration);
4134
+
4135
+ return Configuration;
4136
+ });
4137
+
4138
+ globalThis.define = origDefine;
4139
+
4140
+ function _setupConfiguration() {
4141
+ var BaseConfiguration = sap.ui.require('sap/base/config/_Configuration');
4142
+ //register config provider
4143
+ BaseConfiguration.registerProvider(sap.ui.require("sap/ui/core/config/BootstrapConfigurationProvider"));
4144
+ BaseConfiguration.registerProvider(sap.ui.require("sap/ui/base/config/MetaConfigurationProvider"));
4145
+ BaseConfiguration.registerProvider(sap.ui.require("sap/ui/base/config/URLConfigurationProvider"));
4146
+ }
4147
+
4148
+ /** init configuration */
4149
+ _setupConfiguration();
4150
+
4151
+ var BaseConfig = sap.ui.require("sap/base/config/_Configuration");
4152
+
4153
+ /** autoconfig */
4154
+ var sBaseUrl, bNojQuery,
4155
+ aScripts, rBootScripts, i,
4156
+ sBootstrapUrl;
4157
+
4158
+ function findBaseUrl(oScript, rUrlPattern) {
4159
+ var sUrl = oScript && oScript.getAttribute("src"),
4160
+ oMatch = rUrlPattern.exec(sUrl);
4161
+ if ( oMatch ) {
4162
+ sBaseUrl = oMatch[1] || "";
4163
+ sBootstrapUrl = sUrl;
4164
+ bNojQuery = /sap-ui-core-nojQuery\.js(?:[?#]|$)/.test(sUrl);
4165
+ return true;
4166
+ }
4167
+ return false;
4168
+ }
4169
+
4170
+ function ensureSlash(path) {
4171
+ return path && path[path.length - 1] !== '/' ? path + '/' : path;
4172
+ }
4173
+
4174
+ // Prefer script tags which have the sap-ui-bootstrap ID
4175
+ // This prevents issues when multiple script tags point to files named
4176
+ // "sap-ui-core.js", for example when using the cache buster for UI5 resources
4177
+ if ( !findBaseUrl(document.querySelector('SCRIPT[src][id=sap-ui-bootstrap]'), /^((?:[^?#]*\/)?resources\/)/ ) ) {
4178
+
4179
+ // only when there's no such script tag, check all script tags
4180
+ rBootScripts = /^([^?#]*\/)?(?:sap-ui-(?:core|custom|boot|merged)(?:-[^?#/]*)?|jquery.sap.global|ui5loader(?:-autoconfig)?)\.js(?:[?#]|$)/;
4181
+ aScripts = document.scripts;
4182
+ for ( i = 0; i < aScripts.length; i++ ) {
4183
+ if ( findBaseUrl(aScripts[i], rBootScripts) ) {
4184
+ break;
4185
+ }
4186
+ }
4187
+ }
4188
+
4189
+ // configuration via window['sap-ui-config'] always overrides an auto detected base URL
4190
+ var mResourceRoots = BaseConfig.get({
4191
+ name: "sapUiResourceRoots",
4192
+ type: BaseConfig.Type.MergedObject
4193
+ });
4194
+ if (typeof mResourceRoots[''] === 'string' ) {
4195
+ sBaseUrl = mResourceRoots[''];
4196
+ }
4197
+
4198
+ if (sBaseUrl == null) {
4199
+ throw new Error("ui5loader-autoconfig.js: could not determine base URL. No known script tag and no configuration found!");
4200
+ }
4201
+
4202
+ /**
4203
+ * Determine whether a bootstrap reboot URL is set to reboot UI5 from a different URL
4204
+ */
4205
+ (function() {
4206
+ var sRebootUrl;
4207
+ try { // Necessary for FF when Cookies are disabled
4208
+ sRebootUrl = window.localStorage.getItem("sap-ui-reboot-URL");
4209
+ } catch (e) { /* no warning, as this will happen on every startup, depending on browser settings */ }
4210
+
4211
+ /*
4212
+ * Determine whether sap-bootstrap-debug is set, run debugger statement
4213
+ * to allow early debugging in browsers with broken dev tools
4214
+ */
4215
+ var bDebugBootstrap = BaseConfig.get({
4216
+ name: "sapBootstrapDebug",
4217
+ type: BaseConfig.Type.Boolean,
4218
+ external: true,
4219
+ freeze: true
4220
+ });
4221
+ if (bDebugBootstrap) {
4222
+ /*eslint-disable no-debugger */
4223
+ debugger;
4224
+ /*eslint-enable no-debugger */
4225
+ }
4226
+
4227
+ if (sRebootUrl) {
4228
+ var sDebugRebootPath = ensureSlash(sBaseUrl) + 'sap/ui/core/support/debugReboot.js';
4229
+
4230
+ // This won't work in case this script is loaded async (e.g. dynamic script tag)
4231
+ document.write("<script src=\"" + sDebugRebootPath + "\"></script>");
4232
+
4233
+ var oRestart = new Error("This is not a real error. Aborting UI5 bootstrap and rebooting from: " + sRebootUrl);
4234
+ oRestart.name = "Restart";
4235
+ throw oRestart;
4236
+ }
4237
+
4238
+ })();
4239
+
4240
+ /**
4241
+ * Determine whether to use debug sources depending on URL parameter, local storage
4242
+ * and script tag attribute.
4243
+ * If full debug mode is required, restart with a debug version of the bootstrap.
4244
+ */
4245
+ (function() {
4246
+ // check URI param
4247
+ var vDebugInfo = BaseConfig.get({
4248
+ name: "sapUiDebug",
4249
+ type: BaseConfig.Type.String,
4250
+ defaultValue: false,
4251
+ external: true,
4252
+ freeze: true
4253
+ });
4254
+
4255
+ // check local storage
4256
+ try {
4257
+ vDebugInfo = vDebugInfo || window.localStorage.getItem("sap-ui-debug");
4258
+ } catch (e) {
4259
+ // access to localStorage might be disallowed
4260
+ }
4261
+
4262
+ // normalize vDebugInfo; afterwards, it either is a boolean or a string not representing a boolean
4263
+ if ( typeof vDebugInfo === 'string' ) {
4264
+ if ( /^(?:false|true|x|X)$/.test(vDebugInfo) ) {
4265
+ vDebugInfo = vDebugInfo !== 'false';
4266
+ }
4267
+ } else {
4268
+ vDebugInfo = !!vDebugInfo;
4269
+ }
4270
+
4271
+ // if bootstrap URL explicitly refers to a debug source, generally use debug sources
4272
+ if ( /-dbg\.js([?#]|$)/.test(sBootstrapUrl) ) {
4273
+ window['sap-ui-loaddbg'] = true;
4274
+ vDebugInfo = vDebugInfo || true;
4275
+ }
4276
+
4277
+ // export resulting debug mode under legacy property
4278
+ window["sap-ui-debug"] = vDebugInfo;
4279
+
4280
+ // check for optimized sources by testing variable names in a local function
4281
+ // (check for native API ".getAttribute" to make sure that the function's source can be retrieved)
4282
+ window["sap-ui-optimized"] = window["sap-ui-optimized"] ||
4283
+ (/\.getAttribute/.test(findBaseUrl) && !/oScript/.test(findBaseUrl));
4284
+
4285
+ if ( window["sap-ui-optimized"] && vDebugInfo ) {
4286
+ // if current sources are optimized and any debug sources should be used, enable the "-dbg" suffix
4287
+ window['sap-ui-loaddbg'] = true;
4288
+ // if debug sources should be used in general, restart with debug URL (if not disabled, e.g. by test runner)
4289
+ if ( vDebugInfo === true && !window["sap-ui-debug-no-reboot"] ) {
4290
+ var sDebugUrl;
4291
+ if ( sBootstrapUrl != null ) {
4292
+ sDebugUrl = sBootstrapUrl.replace(/\/(?:sap-ui-cachebuster\/)?([^\/]+)\.js/, "/$1-dbg.js");
4293
+ } else {
4294
+ // when no boot script could be identified, we can't derive the name of the
4295
+ // debug boot script from it, so fall back to a default debug boot script
4296
+ sDebugUrl = ensureSlash(sBaseUrl) + 'sap-ui-core.js';
4297
+ }
4298
+ // revert changes to global names
4299
+ ui5loader.config({
4300
+ amd:false
4301
+ });
4302
+ window["sap-ui-optimized"] = false;
4303
+
4304
+ if (ui5loader.config().async) {
4305
+ var script = document.createElement("script");
4306
+ script.src = sDebugUrl;
4307
+ document.head.appendChild(script);
4308
+ } else {
4309
+ document.write("<script src=\"" + sDebugUrl + "\"></script>");
4310
+ }
4311
+
4312
+ var oRestart = new Error("This is not a real error. Aborting UI5 bootstrap and restarting from: " + sDebugUrl);
4313
+ oRestart.name = "Restart";
4314
+ throw oRestart;
4315
+ }
4316
+ }
4317
+
4318
+ function makeRegExp(sGlobPattern) {
4319
+ if (!/\/\*\*\/$/.test(sGlobPattern)) {
4320
+ sGlobPattern = sGlobPattern.replace(/\/$/, '/**/');
4321
+ }
4322
+ return sGlobPattern.replace(/\*\*\/|\*|[[\]{}()+?.\\^$|]/g, function(sMatch) {
4323
+ switch (sMatch) {
4324
+ case '**/': return '(?:[^/]+/)*';
4325
+ case '*': return '[^/]*';
4326
+ default: return '\\' + sMatch;
4327
+ }
4328
+ });
4329
+ }
4330
+
4331
+ var fnIgnorePreload;
4332
+
4333
+ if (typeof vDebugInfo === 'string') {
4334
+ var sPattern = "^(?:" + vDebugInfo.split(/,/).map(makeRegExp).join("|") + ")",
4335
+ rFilter = new RegExp(sPattern);
4336
+
4337
+ fnIgnorePreload = function(sModuleName) {
4338
+ return rFilter.test(sModuleName);
4339
+ };
4340
+
4341
+ ui5loader._.logger.debug("Modules that should be excluded from preload: '" + sPattern + "'");
4342
+
4343
+ } else if (vDebugInfo === true) {
4344
+
4345
+ fnIgnorePreload = function() {
4346
+ return true;
4347
+ };
4348
+
4349
+ ui5loader._.logger.debug("All modules should be excluded from preload");
4350
+
4351
+ }
4352
+
4353
+ ui5loader.config({
4354
+ debugSources: !!window['sap-ui-loaddbg'],
4355
+ ignoreBundledResources: fnIgnorePreload
4356
+ });
4357
+
4358
+ })();
4359
+
4360
+ const bFuture = BaseConfig.get({
4361
+ name: "sapUiXxFuture",
4362
+ type: BaseConfig.Type.Boolean,
4363
+ external: true,
4364
+ freeze: true
4365
+ });
4366
+
4367
+ /**
4368
+ * Evaluate legacy configuration.
4369
+ * @deprecated As of version 1.120
4370
+ */
4371
+ (() => {
4372
+ // xx-future implicitly sets the loader to async
4373
+ const bAsync = BaseConfig.get({
4374
+ name: "sapUiAsync",
4375
+ type: BaseConfig.Type.Boolean,
4376
+ external: true,
4377
+ freeze: true
4378
+ }) || bFuture;
4379
+
4380
+ if (bAsync) {
4381
+ ui5loader.config({
4382
+ async: true
4383
+ });
4384
+ }
4385
+ })();
4386
+
4387
+ // Note: loader converts any NaN value to a default value
4388
+ ui5loader._.maxTaskDuration = BaseConfig.get({
4389
+ name: "sapUiXxMaxLoaderTaskDuration",
4390
+ type: BaseConfig.Type.Integer,
4391
+ defaultValue: undefined,
4392
+ external: true,
4393
+ freeze: true
4394
+ });
4395
+
4396
+ // support legacy switch 'noLoaderConflict', but 'amdLoader' has higher precedence
4397
+ const bExposeAsAMDLoader = BaseConfig.get({
4398
+ name: "sapUiAmd",
4399
+ type: BaseConfig.Type.Boolean,
4400
+ defaultValue: !BaseConfig.get({
4401
+ name: "sapUiNoLoaderConflict",
4402
+ type: BaseConfig.Type.Boolean,
4403
+ defaultValue: true,
4404
+ external: true,
4405
+ freeze: true
4406
+ }),
4407
+ external: true,
4408
+ freeze: true
4409
+ });
4410
+
4411
+ // calculate syncCallBehavior
4412
+ let syncCallBehavior = 0; // ignore
4413
+ let sNoSync = BaseConfig.get({ // call must be made to ensure freezing
4414
+ name: "sapUiXxNoSync",
4415
+ type: BaseConfig.Type.String,
4416
+ external: true,
4417
+ freeze: true
4418
+ });
4419
+
4420
+ // sap-ui-xx-future enforces strict sync call behavior
4421
+ sNoSync = bFuture ? "x" : sNoSync;
4422
+
4423
+ if (sNoSync === 'warn') {
4424
+ syncCallBehavior = 1;
4425
+ } else if (/^(true|x)$/i.test(sNoSync)) {
4426
+ syncCallBehavior = 2;
4427
+ }
4428
+
4429
+ /**
4430
+ * @deprecated As of version 1.120
4431
+ */
4432
+ (() => {
4433
+ const GlobalConfigurationProvider = sap.ui.require("sap/base/config/GlobalConfigurationProvider");
4434
+ if ( syncCallBehavior && GlobalConfigurationProvider._.configLoaded()) {
4435
+ const sMessage = "[nosync]: configuration loaded via sync XHR";
4436
+ if (syncCallBehavior === 1) {
4437
+ ui5loader._.logger.warning(sMessage);
4438
+ } else {
4439
+ ui5loader._.logger.error(sMessage);
4440
+ }
4441
+ }
4442
+ })();
4443
+
4444
+ ui5loader.config({
4445
+ baseUrl: sBaseUrl,
4446
+
4447
+ amd: bExposeAsAMDLoader,
4448
+
4449
+ map: {
4450
+ "*": {
4451
+ 'blanket': 'sap/ui/thirdparty/blanket',
4452
+ 'crossroads': 'sap/ui/thirdparty/crossroads',
4453
+ 'd3': 'sap/ui/thirdparty/d3',
4454
+ 'handlebars': 'sap/ui/thirdparty/handlebars',
4455
+ 'hasher': 'sap/ui/thirdparty/hasher',
4456
+ 'IPv6': 'sap/ui/thirdparty/IPv6',
4457
+ 'jquery': 'sap/ui/thirdparty/jquery',
4458
+ 'jszip': 'sap/ui/thirdparty/jszip',
4459
+ 'less': 'sap/ui/thirdparty/less',
4460
+ 'OData': 'sap/ui/thirdparty/datajs',
4461
+ 'punycode': 'sap/ui/thirdparty/punycode',
4462
+ 'SecondLevelDomains': 'sap/ui/thirdparty/SecondLevelDomains',
4463
+ 'sinon': 'sap/ui/thirdparty/sinon',
4464
+ 'signals': 'sap/ui/thirdparty/signals',
4465
+ 'URI': 'sap/ui/thirdparty/URI',
4466
+ 'URITemplate': 'sap/ui/thirdparty/URITemplate',
4467
+ 'esprima': 'sap/ui/documentation/sdk/thirdparty/esprima'
4468
+ }
4469
+ },
4470
+
4471
+ reportSyncCalls: syncCallBehavior,
4472
+
4473
+ shim: {
4474
+ 'sap/ui/thirdparty/bignumber': {
4475
+ amd: true,
4476
+ exports: 'BigNumber'
4477
+ },
4478
+ 'sap/ui/thirdparty/blanket': {
4479
+ amd: true,
4480
+ exports: 'blanket' // '_blanket', 'esprima', 'falafel', 'inBrowser', 'parseAndModify'
4481
+ },
4482
+ 'sap/ui/thirdparty/caja-html-sanitizer': {
4483
+ amd: false,
4484
+ exports: 'html' // 'html_sanitizer', 'html4'
4485
+ },
4486
+ 'sap/ui/thirdparty/crossroads': {
4487
+ amd: true,
4488
+ exports: 'crossroads',
4489
+ deps: ['sap/ui/thirdparty/signals']
4490
+ },
4491
+ 'sap/ui/thirdparty/d3': {
4492
+ amd: true,
4493
+ exports: 'd3'
4494
+ },
4495
+ 'sap/ui/thirdparty/datajs': {
4496
+ amd: true,
4497
+ exports: 'OData' // 'datajs'
4498
+ },
4499
+ 'sap/ui/thirdparty/handlebars': {
4500
+ amd: true,
4501
+ exports: 'Handlebars'
4502
+ },
4503
+ 'sap/ui/thirdparty/hasher': {
4504
+ amd: true,
4505
+ exports: 'hasher',
4506
+ deps: ['sap/ui/thirdparty/signals']
4507
+ },
4508
+ 'sap/ui/thirdparty/IPv6': {
4509
+ amd: true,
4510
+ exports: 'IPv6'
4511
+ },
4512
+ 'sap/ui/thirdparty/iscroll-lite': {
4513
+ amd: false,
4514
+ exports: 'iScroll'
4515
+ },
4516
+ 'sap/ui/thirdparty/iscroll': {
4517
+ amd: false,
4518
+ exports: 'iScroll'
4519
+ },
4520
+ 'sap/ui/thirdparty/jquery': {
4521
+ amd: true,
4522
+ exports: 'jQuery',
4523
+ deps: ['sap/ui/thirdparty/jquery-compat']
4524
+ },
4525
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-datepicker': {
4526
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-core'],
4527
+ exports: 'jQuery'
4528
+ },
4529
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-draggable': {
4530
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
4531
+ exports: 'jQuery'
4532
+ },
4533
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-droppable': {
4534
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse', 'sap/ui/thirdparty/jqueryui/jquery-ui-draggable'],
4535
+ exports: 'jQuery'
4536
+ },
4537
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-effect': {
4538
+ deps: ['sap/ui/thirdparty/jquery'],
4539
+ exports: 'jQuery'
4540
+ },
4541
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-mouse': {
4542
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-core', 'sap/ui/thirdparty/jqueryui/jquery-ui-widget'],
4543
+ exports: 'jQuery'
4544
+ },
4545
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-position': {
4546
+ deps: ['sap/ui/thirdparty/jquery'],
4547
+ exports: 'jQuery'
4548
+ },
4549
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-resizable': {
4550
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
4551
+ exports: 'jQuery'
4552
+ },
4553
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-selectable': {
4554
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
4555
+ exports: 'jQuery'
4556
+ },
4557
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-sortable': {
4558
+ deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
4559
+ exports: 'jQuery'
4560
+ },
4561
+ 'sap/ui/thirdparty/jqueryui/jquery-ui-widget': {
4562
+ deps: ['sap/ui/thirdparty/jquery'],
4563
+ exports: 'jQuery'
4564
+ },
4565
+ 'sap/ui/thirdparty/jquery-mobile-custom': {
4566
+ amd: true,
4567
+ deps: ['sap/ui/thirdparty/jquery', 'sap/ui/Device'],
4568
+ exports: 'jQuery.mobile'
4569
+ },
4570
+ 'sap/ui/thirdparty/jszip': {
4571
+ amd: true,
4572
+ exports: 'JSZip'
4573
+ },
4574
+ 'sap/ui/thirdparty/less': {
4575
+ amd: true,
4576
+ exports: 'less'
4577
+ },
4578
+ 'sap/ui/thirdparty/qunit-2': {
4579
+ amd: false,
4580
+ exports: 'QUnit'
4581
+ },
4582
+ 'sap/ui/thirdparty/punycode': {
4583
+ amd: true,
4584
+ exports: 'punycode'
4585
+ },
4586
+ 'sap/ui/thirdparty/RequestRecorder': {
4587
+ amd: true,
4588
+ exports: 'RequestRecorder',
4589
+ deps: ['sap/ui/thirdparty/URI', 'sap/ui/thirdparty/sinon']
4590
+ },
4591
+ 'sap/ui/thirdparty/require': {
4592
+ exports: 'define' // 'require', 'requirejs'
4593
+ },
4594
+ 'sap/ui/thirdparty/SecondLevelDomains': {
4595
+ amd: true,
4596
+ exports: 'SecondLevelDomains'
4597
+ },
4598
+ 'sap/ui/thirdparty/signals': {
4599
+ amd: true,
4600
+ exports: 'signals'
4601
+ },
4602
+ 'sap/ui/thirdparty/sinon': {
4603
+ amd: true,
4604
+ exports: 'sinon'
4605
+ },
4606
+ 'sap/ui/thirdparty/sinon-4': {
4607
+ amd: true,
4608
+ exports: 'sinon'
4609
+ },
4610
+ 'sap/ui/thirdparty/sinon-server': {
4611
+ amd: true,
4612
+ exports: 'sinon' // really sinon! sinon-server is a subset of server and uses the same global for export
4613
+ },
4614
+ 'sap/ui/thirdparty/URI': {
4615
+ amd: true,
4616
+ exports: 'URI'
4617
+ },
4618
+ 'sap/ui/thirdparty/URITemplate': {
4619
+ amd: true,
4620
+ exports: 'URITemplate',
4621
+ deps: ['sap/ui/thirdparty/URI']
4622
+ },
4623
+ 'sap/ui/thirdparty/vkbeautify': {
4624
+ amd: false,
4625
+ exports: 'vkbeautify'
4626
+ },
4627
+ 'sap/ui/thirdparty/zyngascroll': {
4628
+ amd: false,
4629
+ exports: 'Scroller' // 'requestAnimationFrame', 'cancelRequestAnimationFrame', 'core'
4630
+ },
4631
+ 'sap/ui/demokit/js/esprima': {
4632
+ amd: true,
4633
+ exports: 'esprima'
4634
+ },
4635
+ 'sap/ui/documentation/sdk/thirdparty/esprima': {
4636
+ amd: true,
4637
+ exports: 'esprima'
4638
+ },
4639
+ 'sap/viz/libs/canvg': {
4640
+ deps: ['sap/viz/libs/rgbcolor']
4641
+ },
4642
+ 'sap/viz/libs/rgbcolor': {
4643
+ },
4644
+ 'sap/viz/libs/sap-viz': {
4645
+ deps: ['sap/viz/library', 'sap/ui/thirdparty/jquery', 'sap/ui/thirdparty/d3', 'sap/viz/libs/canvg']
4646
+ },
4647
+ 'sap/viz/libs/sap-viz-info-charts': {
4648
+ amd: true,
4649
+ deps: ['sap/viz/libs/sap-viz-info-framework']
4650
+ },
4651
+ 'sap/viz/libs/sap-viz-info-framework': {
4652
+ amd: true,
4653
+ deps: ['sap/ui/thirdparty/jquery', 'sap/ui/thirdparty/d3']
4654
+ },
4655
+ 'sap/viz/ui5/container/libs/sap-viz-controls-vizcontainer': {
4656
+ deps: ['sap/viz/libs/sap-viz', 'sap/viz/ui5/container/libs/common/libs/rgbcolor/rgbcolor_static']
4657
+ },
4658
+ 'sap/viz/ui5/controls/libs/sap-viz-vizframe/sap-viz-vizframe': {
4659
+ deps: ['sap/viz/libs/sap-viz-info-charts']
4660
+ },
4661
+ 'sap/viz/ui5/controls/libs/sap-viz-vizservices/sap-viz-vizservices': {
4662
+ deps: ['sap/viz/libs/sap-viz-info-charts']
4663
+ },
4664
+ 'sap/viz/resources/chart/templates/standard_fiori/template': {
4665
+ deps: ['sap/viz/libs/sap-viz-info-charts']
4666
+ }
4667
+ }
4668
+ });
4669
+
4670
+ var defineModuleSync = ui5loader._.defineModuleSync;
4671
+
4672
+ defineModuleSync('ui5loader.js', null);
4673
+ defineModuleSync('ui5loader-autoconfig.js', null);
4674
+
4675
+ if (bNojQuery && typeof jQuery === 'function') {
4676
+ // when we're executed in the context of the sap-ui-core-noJQuery file,
4677
+ // we try to detect an existing jQuery / jQuery position plugin and register them as modules
4678
+ defineModuleSync('sap/ui/thirdparty/jquery.js', jQuery);
4679
+ if (jQuery.ui && jQuery.ui.position) {
4680
+ defineModuleSync('sap/ui/thirdparty/jqueryui/jquery-ui-position.js', jQuery);
4681
+ }
4682
+ }
4683
+
4684
+ var sMainModule = BaseConfig.get({
4685
+ name: "sapUiMain",
4686
+ type: BaseConfig.Type.String,
4687
+ freeze: true
4688
+ });
4689
+ if ( sMainModule ) {
4690
+ sap.ui.require(sMainModule.trim().split(/\s*,\s*/));
4691
+ }
4692
+
4693
+ }());
4694
+ sap.ui.require(["sap/ui/core/Core"], (Core) => Core.boot?.());
4695
+ //# sourceMappingURL=sap-ui-custom-dbg.js.map