@angular-wave/angular.ts 0.15.0 → 0.15.1

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 (59) hide show
  1. package/@types/angular.d.ts +1 -1
  2. package/@types/core/compile/attributes.d.ts +28 -4
  3. package/@types/core/compile/inteface.d.ts +5 -1
  4. package/@types/core/di/inteface.d.ts +11 -0
  5. package/@types/core/parse/ast/ast-node.d.ts +2 -0
  6. package/@types/core/parse/parse.d.ts +4 -1
  7. package/@types/core/scope/interface.d.ts +26 -0
  8. package/@types/directive/bind/bind.d.ts +5 -7
  9. package/@types/directive/form/form.d.ts +12 -9
  10. package/@types/directive/init/init.d.ts +2 -2
  11. package/@types/directive/input/input.d.ts +16 -0
  12. package/@types/directive/listener/listener.d.ts +4 -0
  13. package/@types/directive/model/interface.d.ts +18 -0
  14. package/@types/directive/model/model.d.ts +20 -18
  15. package/@types/directive/non-bindable/non-bindable.d.ts +2 -2
  16. package/@types/directive/select/select.d.ts +2 -2
  17. package/@types/directive/setter/setter.d.ts +2 -2
  18. package/@types/directive/show-hide/show-hide.d.ts +2 -4
  19. package/@types/directive/switch/switch.d.ts +4 -4
  20. package/@types/interface.d.ts +22 -1
  21. package/@types/namespace.d.ts +9 -1
  22. package/@types/router/router.d.ts +5 -3
  23. package/@types/router/scroll/interface.d.ts +1 -1
  24. package/@types/router/state/interface.d.ts +5 -0
  25. package/@types/router/state/state-builder.d.ts +10 -6
  26. package/@types/router/state/state-matcher.d.ts +11 -3
  27. package/@types/router/state/state-object.d.ts +3 -5
  28. package/@types/router/state/state-queue-manager.d.ts +14 -8
  29. package/@types/router/state/state-registry.d.ts +12 -3
  30. package/@types/router/state/state-service.d.ts +8 -2
  31. package/@types/router/transition/hook-registry.d.ts +15 -5
  32. package/@types/router/transition/transition.d.ts +4 -2
  33. package/@types/router/url/url-rules.d.ts +3 -84
  34. package/@types/router/url/url-service.d.ts +9 -8
  35. package/@types/services/cookie/cookie.d.ts +3 -11
  36. package/@types/services/http/http.d.ts +6 -31
  37. package/@types/services/http/interface.d.ts +22 -0
  38. package/@types/services/location/location.d.ts +14 -13
  39. package/@types/services/sce/interface.d.ts +25 -0
  40. package/@types/services/sse/interface.d.ts +8 -1
  41. package/@types/services/sse/sse.d.ts +10 -18
  42. package/@types/services/storage/storage.d.ts +6 -6
  43. package/@types/services/stream/interface.d.ts +1 -1
  44. package/@types/services/stream/stream.d.ts +98 -0
  45. package/@types/shared/common.d.ts +2 -2
  46. package/@types/shared/dom.d.ts +21 -42
  47. package/@types/shared/hof.d.ts +27 -37
  48. package/@types/shared/noderef.d.ts +2 -2
  49. package/@types/shared/strings.d.ts +13 -4
  50. package/@types/shared/utils.d.ts +123 -66
  51. package/@types/shared/validate.d.ts +7 -0
  52. package/dist/angular-ts.esm.js +980 -812
  53. package/dist/angular-ts.umd.js +980 -812
  54. package/dist/angular-ts.umd.min.js +1 -1
  55. package/dist/angular-ts.umd.min.js.gz +0 -0
  56. package/dist/angular-ts.umd.min.js.map +1 -1
  57. package/package.json +1 -1
  58. package/@types/router/state-filters.d.ts +0 -39
  59. package/@types/shared/cache.d.ts +0 -7
@@ -1,4 +1,4 @@
1
- /* Version: 0.15.0 - December 14, 2025 04:42:37 */
1
+ /* Version: 0.15.1 - December 21, 2025 17:06:20 */
2
2
  const VALID_CLASS = "ng-valid";
3
3
  const INVALID_CLASS = "ng-invalid";
4
4
  const PRISTINE_CLASS = "ng-pristine";
@@ -102,14 +102,14 @@ function isArrayLike(obj) {
102
102
  // via the forEach method when constructing the JQLite object in the first place
103
103
  if (isArray(obj) || obj instanceof Array || isString(obj)) return true;
104
104
 
105
- const len = /** @type {Object} */ (obj).length;
105
+ const len = /** @type {ArrayLike<any>} */ (obj).length;
106
106
 
107
107
  // NodeList objects (with `item` method) and
108
108
  // other objects with suitable length characteristics are array-like
109
109
  return (
110
110
  isNumber(len) &&
111
111
  ((len >= 0 && len - 1 in /** @type {Object} */ (obj)) ||
112
- typeof (/** @type {Object} */ (obj).item) === "function")
112
+ typeof (/** @type {NodeList} */ (obj).item) === "function")
113
113
  );
114
114
  }
115
115
 
@@ -149,7 +149,7 @@ function isArray(array) {
149
149
  * @param {new (...args: any[]) => T} type The constructor to test against
150
150
  * @returns {val is T}
151
151
  */
152
- function isIntanceOf(val, type) {
152
+ function isInstanceOf(val, type) {
153
153
  return val instanceof type;
154
154
  }
155
155
 
@@ -168,8 +168,7 @@ function isObject(value) {
168
168
 
169
169
  /**
170
170
  * Determines if a reference is a `string`.
171
- *
172
- * @param value - The value to check.
171
+ * @param {unknown} value - The value to check.
173
172
  * @returns {value is string} True if `value` is a string.
174
173
  */
175
174
  function isString(value) {
@@ -282,7 +281,7 @@ function isRegExp(value) {
282
281
  * @returns {obj is Window} True if `obj` is a window obj.
283
282
  */
284
283
  function isWindow(obj) {
285
- return obj && isIntanceOf(obj, Window);
284
+ return isInstanceOf(obj, Window);
286
285
  }
287
286
 
288
287
  /**
@@ -341,25 +340,30 @@ function trim(value) {
341
340
  return isString(value) ? value.trim() : value;
342
341
  }
343
342
 
343
+ /**
344
+ * @param {string} name
345
+ * @param {string} separator
346
+ */
344
347
  function snakeCase(name, separator) {
345
348
  const modseparator = separator;
346
349
 
347
350
  return name.replace(
348
351
  /[A-Z]/g,
349
- (letter, pos) => (pos ? modseparator : "") + letter.toLowerCase(),
352
+ (/** @type {string} */ letter, /** @type {any} */ pos) =>
353
+ (pos ? modseparator : "") + letter.toLowerCase(),
350
354
  );
351
355
  }
352
356
 
353
357
  /**
354
358
  * Set or clear the hashkey for an object.
355
- * @param obj object
356
- * @param hashkey the hashkey (!truthy to delete the hashkey)
359
+ * @param {{ [x: string]: any; _hashKey?: any; }} obj object
360
+ * @param {any} hashkey the hashkey (!truthy to delete the hashkey)
357
361
  */
358
362
  function setHashKey(obj, hashkey) {
359
363
  if (hashkey) {
360
- obj.$$hashKey = hashkey;
364
+ obj._hashKey = hashkey;
361
365
  } else {
362
- delete obj.$$hashKey;
366
+ delete obj._hashKey;
363
367
  }
364
368
  }
365
369
 
@@ -374,7 +378,7 @@ function setHashKey(obj, hashkey) {
374
378
  * @returns {Object<string, any>} The extended destination object.
375
379
  */
376
380
  function baseExtend(dst, objs, deep = false) {
377
- const hasKey = dst.$$hashKey;
381
+ const hasKey = dst._hashKey;
378
382
 
379
383
  for (let i = 0, ii = objs.length; i < ii; ++i) {
380
384
  const obj = objs[i];
@@ -441,6 +445,10 @@ function inherit$1(parent, extra) {
441
445
  return extend(Object.create(parent), extra);
442
446
  }
443
447
 
448
+ /**
449
+ * @param {{ toString: () => string; }} obj
450
+ * @returns {boolean}
451
+ */
444
452
  function hasCustomToString(obj) {
445
453
  return isFunction(obj.toString) && obj.toString !== toString;
446
454
  }
@@ -451,12 +459,16 @@ function hasCustomToString(obj) {
451
459
  * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName)
452
460
  *
453
461
  * @param {Element} element
454
- * @returns
462
+ * @returns {string}
455
463
  */
456
464
  function getNodeName(element) {
457
465
  return lowercase(element.nodeName);
458
466
  }
459
467
 
468
+ /**
469
+ * @param {any} array
470
+ * @param {string} obj
471
+ */
460
472
  function includes(array, obj) {
461
473
  return Array.prototype.indexOf.call(array, obj) !== -1;
462
474
  }
@@ -479,6 +491,10 @@ function arrayRemove(array, value) {
479
491
  return index;
480
492
  }
481
493
 
494
+ /**
495
+ * @param {unknown} val1
496
+ * @param {unknown} val2
497
+ */
482
498
  function simpleCompare(val1, val2) {
483
499
  return val1 === val2 || (Number.isNaN(val1) && Number.isNaN(val2));
484
500
  }
@@ -633,6 +649,10 @@ function assertNotHasOwnProperty(name, context) {
633
649
  }
634
650
  }
635
651
 
652
+ /**
653
+ * @param {unknown} value
654
+ * @returns {string | unknown}
655
+ */
636
656
  function stringify$1(value) {
637
657
  if (isNull(value) || isUndefined(value)) {
638
658
  return "";
@@ -644,10 +664,14 @@ function stringify$1(value) {
644
664
  value = `${value}`;
645
665
  break;
646
666
  default:
647
- if (hasCustomToString(value) && !isArray(value) && !isDate(value)) {
648
- value = value.toString();
667
+ if (
668
+ hasCustomToString(/** @type {Object} */ (value)) &&
669
+ !isArray(value) &&
670
+ !isDate(value)
671
+ ) {
672
+ value = /** @type {Object} */ (value).toString();
649
673
  } else {
650
- value = toJson(value);
674
+ value = toJson(/** @type {any[]} */ (value));
651
675
  }
652
676
  }
653
677
 
@@ -662,10 +686,19 @@ function isValidObjectMaxDepth(maxDepth) {
662
686
  return isNumber(maxDepth) && maxDepth > 0;
663
687
  }
664
688
 
689
+ /**
690
+ * @param {any[]} array1
691
+ * @param {IArguments | any[] | NodeListOf<ChildNode>} array2
692
+ * @param {number | undefined} [index]
693
+ */
665
694
  function concat(array1, array2, index) {
666
695
  return array1.concat(Array.prototype.slice.call(array2, index));
667
696
  }
668
697
 
698
+ /**
699
+ * @param {IArguments | [string, ...any[]]} args
700
+ * @param {number} startIndex
701
+ */
669
702
  function sliceArgs(args, startIndex) {
670
703
  return Array.prototype.slice.call(args, startIndex);
671
704
  }
@@ -701,6 +734,10 @@ function bind(context, fn) {
701
734
  return fn;
702
735
  }
703
736
 
737
+ /**
738
+ * @param {string} key
739
+ * @param {unknown} value
740
+ */
704
741
  function toJsonReplacer(key, value) {
705
742
  let val = value;
706
743
 
@@ -722,66 +759,41 @@ function toJsonReplacer(key, value) {
722
759
  }
723
760
 
724
761
  /**
725
- * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
726
- * stripped since AngularTS uses this notation internally.
762
+ * Serializes input into a JSON-formatted string. Properties with leading `$$` characters
763
+ * will be stripped since AngularTS uses this notation internally.
727
764
  *
728
- * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON.
729
- * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
730
- * If set to an integer, the JSON output will contain that many spaces per indentation.
731
- * @returns {string|undefined} JSON-ified string representing `obj`.
732
- * @knownIssue
733
- *
734
- * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date`
735
- * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the
736
- * `Date.prototype.toJSON` method as follows:
737
- *
738
- * ```
739
- * let _DatetoJSON = Date.prototype.toJSON;
740
- * Date.prototype.toJSON = function() {
741
- * try {
742
- * return _DatetoJSON.call(this);
743
- * } catch(e) {
744
- * if (e instanceof RangeError) {
745
- * return null;
746
- * }
747
- * throw e;
748
- * }
749
- * };
750
- * ```
751
- *
752
- * See https://github.com/angular/angular.js/pull/14221 for more information.
765
+ * @param {Object|Array<any>|Date|string|number|boolean} obj
766
+ * Input to be serialized into JSON.
767
+ * @param {boolean|number} [pretty=2]
768
+ * If `true`, the JSON output will contain newlines and whitespace (2 spaces).
769
+ * If a number, the JSON output will contain that many spaces per indentation.
770
+ * @returns {string|undefined}
771
+ * JSON-ified string representing `obj`, or `undefined` if `obj` is undefined.
753
772
  */
754
773
  function toJson(obj, pretty) {
755
774
  if (isUndefined(obj)) return undefined;
756
775
 
757
776
  if (!isNumber(pretty)) {
758
- pretty = pretty ? 2 : null;
777
+ pretty = pretty ? 2 : undefined;
759
778
  }
760
779
 
761
- return JSON.stringify(obj, toJsonReplacer, /** @type {Number} */ (pretty));
780
+ return JSON.stringify(obj, toJsonReplacer, /** @type {number} */ (pretty));
762
781
  }
763
782
 
764
783
  /**
765
784
  * Deserializes a JSON string.
766
785
  *
767
786
  * @param {string} json JSON string to deserialize.
768
- * @returns {Object|Array|string|number} Deserialized JSON string.
787
+ * @returns {Object|Array<any>|string|number} Deserialized JSON string.
769
788
  */
770
789
  function fromJson(json) {
771
790
  return isString(json) ? JSON.parse(json) : json;
772
791
  }
773
792
 
774
- const MS_PER_MINUTE = 60_000; // 60,000 ms in a minute
775
-
776
- function timezoneToOffset(timezone, fallback) {
777
- const requestedTimezoneOffset =
778
- Date.parse(`Jan 01, 1970 00:00:00 ${timezone}`) / MS_PER_MINUTE;
779
-
780
- return isNumberNaN(requestedTimezoneOffset)
781
- ? fallback
782
- : requestedTimezoneOffset;
783
- }
784
-
793
+ /**
794
+ * @param {Date} date
795
+ * @param {number} minutes
796
+ */
785
797
  function addDateMinutes(date, minutes) {
786
798
  const newDate = new Date(date.getTime());
787
799
 
@@ -790,25 +802,13 @@ function addDateMinutes(date, minutes) {
790
802
  return newDate;
791
803
  }
792
804
 
793
- function convertTimezoneToLocal(date, timezone, reverse) {
794
- const doReverse = 1;
795
-
796
- const dateTimezoneOffset = date.getTimezoneOffset();
797
-
798
- const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
799
-
800
- return addDateMinutes(
801
- date,
802
- doReverse * (timezoneOffset - dateTimezoneOffset),
803
- );
804
- }
805
-
806
805
  /**
807
806
  * Parses an escaped url query string into key-value pairs.
808
807
  * @param {string} keyValue
809
- * @returns {Object.<string,boolean|Array>}
808
+ * @returns {Object.<string,boolean|Array<any>>}
810
809
  */
811
810
  function parseKeyValue(keyValue) {
811
+ /** @type {Record<string, boolean | string | Array<any>>} */
812
812
  const obj = {};
813
813
 
814
814
  (keyValue || "").split("&").forEach((item) => {
@@ -832,9 +832,9 @@ function parseKeyValue(keyValue) {
832
832
  val = isDefined(val) ? tryDecodeURIComponent(val) : true;
833
833
 
834
834
  if (!hasOwn(obj, /** @type {string} */ (key))) {
835
- obj[key] = val;
835
+ obj[key] = /** @type {string } */ (val);
836
836
  } else if (isArray(obj[key])) {
837
- obj[key].push(val);
837
+ /** @type {Array<any>} */ (obj[key]).push(val);
838
838
  } else {
839
839
  obj[key] = [obj[key], val];
840
840
  }
@@ -842,10 +842,16 @@ function parseKeyValue(keyValue) {
842
842
  }
843
843
  });
844
844
 
845
- return /** @type {Object.<string,boolean|Array>} */ (obj);
845
+ return /** @type {Object.<string,boolean|Array<any>>} */ (obj);
846
846
  }
847
847
 
848
+ /**
849
+ * @param {string | { [s: string]: any; } | ArrayLike<any> | null} obj
850
+ */
848
851
  function toKeyValue(obj) {
852
+ /**
853
+ * @type {string[]}
854
+ */
849
855
  const parts = [];
850
856
 
851
857
  obj &&
@@ -913,6 +919,8 @@ function encodeUriSegment(val) {
913
919
  * pct-encoded = "%" HEXDIG HEXDIG
914
920
  * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
915
921
  * / "*" / "+" / "," / ";" / "="
922
+ * @param {string | number | boolean} val
923
+ * @param {boolean | undefined} [pctEncodeSpaces]
916
924
  */
917
925
  function encodeUriQuery(val, pctEncodeSpaces) {
918
926
  return encodeURIComponent(val)
@@ -927,28 +935,39 @@ function encodeUriQuery(val, pctEncodeSpaces) {
927
935
  const ngAttrPrefixes = ["ng-", "data-ng-"];
928
936
 
929
937
  /**
930
- * Creates a shallow copy of an object, an array or a primitive.
938
+ * Creates a shallow copy of an object, an array, or returns primitives as-is.
931
939
  *
932
- * Assumes that there are no proto properties for objects.
940
+ * Assumes there are no proto properties.
941
+ *
942
+ * @template T
943
+ * @param {T} src
944
+ * @param {T extends any[] ? T : Record<string, unknown>} [dst]
945
+ * @returns {T}
933
946
  */
934
947
  function shallowCopy(src, dst) {
935
948
  if (isArray(src)) {
936
- dst = dst || [];
949
+ /** @type {any[]} */
950
+ const out = /** @type {any[]} */ (dst) || [];
937
951
 
938
- for (let i = 0, ii = src.length; i < ii; i++) {
939
- dst[i] = src[i];
940
- }
941
- } else if (isObject(src)) {
942
- dst = dst || {};
952
+ out.push(...src);
953
+
954
+ return /** @type {T} */ (out);
955
+ }
956
+
957
+ if (isObject(src)) {
958
+ const out = /** @type {Record<string, unknown>} */ (dst) || {};
943
959
 
944
960
  for (const key in src) {
945
- if (!(key.startsWith("$") && key.charAt(1) === "$")) {
946
- dst[key] = src[key];
961
+ // Copy all properties except $$-prefixed
962
+ if (!key.startsWith("$$")) {
963
+ out[key] = src[key];
947
964
  }
948
965
  }
966
+
967
+ return /** @type {T} */ (out);
949
968
  }
950
969
 
951
- return dst || src;
970
+ return src;
952
971
  }
953
972
 
954
973
  /**
@@ -964,6 +983,9 @@ function assert(argument, errorMsg = "Assertion failed") {
964
983
 
965
984
  /**
966
985
  * Throw error if the argument is falsy.
986
+ * @param {string | boolean | Object} arg
987
+ * @param {string} name
988
+ * @param {string | undefined} [reason]
967
989
  */
968
990
  function assertArg(arg, name, reason) {
969
991
  if (!arg) {
@@ -978,6 +1000,11 @@ function assertArg(arg, name, reason) {
978
1000
  return arg;
979
1001
  }
980
1002
 
1003
+ /**
1004
+ * @param {string | Function | any[]} arg
1005
+ * @param {string} name
1006
+ * @param {boolean | undefined} [acceptArrayAnnotation]
1007
+ */
981
1008
  function assertArgFn(arg, name, acceptArrayAnnotation) {
982
1009
  if (acceptArrayAnnotation && isArray(arg)) {
983
1010
  arg = arg[arg.length - 1];
@@ -1065,7 +1092,7 @@ function minErr(module) {
1065
1092
 
1066
1093
  const templateArgs = sliceArgs(args, 2).map((arg) => toDebugString(arg));
1067
1094
 
1068
- message += template.replace(/\{\d+\}/g, (match) => {
1095
+ message += template.replace(/\{\d+\}/g, (/** @type {string} */ match) => {
1069
1096
  const index = +match.slice(1, -1);
1070
1097
 
1071
1098
  if (index < templateArgs.length) {
@@ -1124,19 +1151,19 @@ function toDebugString(obj) {
1124
1151
  * Hash of a:
1125
1152
  * string is string
1126
1153
  * number is number as string
1127
- * object is either result of calling $$hashKey function on the object or uniquely generated id,
1128
- * that is also assigned to the $$hashKey property of the object.
1154
+ * object is either result of calling _hashKey function on the object or uniquely generated id,
1155
+ * that is also assigned to the _hashKey property of the object.
1129
1156
  *
1130
1157
  * @param {*} obj
1131
1158
  * @returns {string} hash string such that the same input will have the same hash string.
1132
1159
  * The resulting string key is in 'type:hashKey' format.
1133
1160
  */
1134
1161
  function hashKey(obj) {
1135
- const key = obj && obj.$$hashKey;
1162
+ const key = obj && obj._hashKey;
1136
1163
 
1137
1164
  if (key) {
1138
1165
  if (typeof key === "function") {
1139
- return obj.$$hashKey();
1166
+ return obj._hashKey();
1140
1167
  }
1141
1168
 
1142
1169
  return key;
@@ -1145,9 +1172,9 @@ function hashKey(obj) {
1145
1172
  const objType = typeof obj;
1146
1173
 
1147
1174
  if (objType === "function" || (objType === "object" && obj !== null)) {
1148
- obj.$$hashKey = `${objType}:${nextUid()}`;
1175
+ obj._hashKey = `${objType}:${nextUid()}`;
1149
1176
 
1150
- return obj.$$hashKey;
1177
+ return obj._hashKey;
1151
1178
  }
1152
1179
 
1153
1180
  if (objType === "undefined") {
@@ -1409,14 +1436,6 @@ function isArrowFunction(fn) {
1409
1436
  return typeof fn === "function" && !fn.prototype;
1410
1437
  }
1411
1438
 
1412
- /**
1413
- * Expando cache for adding properties to DOM nodes with JavaScript.
1414
- * This used to be an Object in JQLite decorator, but swapped out for a Map
1415
- *
1416
- * @type {Map<number, import('../interface.ts').ExpandoStore>}
1417
- */
1418
- const Cache = new Map();
1419
-
1420
1439
  const ADD_CLASS_SUFFIX = "-add";
1421
1440
  const REMOVE_CLASS_SUFFIX = "-remove";
1422
1441
  const EVENT_CLASS_PREFIX = "ng-";
@@ -1843,10 +1862,18 @@ const ISOLATE_SCOPE_KEY = "$isolateScope";
1843
1862
 
1844
1863
  const EXPANDO = "ng";
1845
1864
 
1865
+ /**
1866
+ * Expando cache for adding properties to DOM nodes with JavaScript.
1867
+ * This used to be an Object in JQLite decorator, but swapped out for a Map
1868
+ *
1869
+ * @type {Map<number, import('../interface.ts').ExpandoStore>}
1870
+ */
1871
+ const Cache = new Map();
1872
+
1846
1873
  /**
1847
1874
  * Key for storing scope data, attached to an element
1848
1875
  */
1849
- const SCOPE_KEY = "$scope";
1876
+ const SCOPE_KEY = $injectTokens._scope;
1850
1877
 
1851
1878
  const DASH_LOWERCASE_REGEXP = /-([a-z])/g;
1852
1879
 
@@ -2289,7 +2316,7 @@ function startingTag(elementOrStr) {
2289
2316
  /**
2290
2317
  * Return the DOM siblings between the first and last node in the given array.
2291
2318
  * @param {Array<Node>} nodes An array-like object
2292
- * @returns {Element} the inputted object or a JQLite collection containing the nodes
2319
+ * @returns {*[]|Array<Node>} the inputted object or a JQLite collection containing the nodes
2293
2320
  */
2294
2321
  function getBlockNodes(nodes) {
2295
2322
  // TODO(perf): update `nodes` instead of creating a new object?
@@ -2399,7 +2426,7 @@ function emptyElement(element) {
2399
2426
  * @param {HTMLElement | Element} parentElement
2400
2427
  * The parent element that will receive the inserted element.
2401
2428
  *
2402
- * @param {HTMLElement | Element | null} [afterElement]
2429
+ * @param {ChildNode | Element | null} [afterElement]
2403
2430
  * An optional sibling element — if present and valid, `element`
2404
2431
  * will be inserted after it. If omitted or invalid, `element`
2405
2432
  * is prepended to `parentElement`.
@@ -2425,6 +2452,11 @@ function domInsert(element, parentElement, afterElement) {
2425
2452
  }
2426
2453
  }
2427
2454
 
2455
+ /**
2456
+ * @param {HTMLElement} element
2457
+ * @param {HTMLElement} parent
2458
+ * @param {ChildNode | null | undefined} after
2459
+ */
2428
2460
  function animatedomInsert(element, parent, after) {
2429
2461
  const originalVisibility = element.style.visibility;
2430
2462
 
@@ -2792,11 +2824,11 @@ class InjectorService extends AbstractInjector {
2792
2824
  * Creates a proxy that automatically persists an object's state
2793
2825
  * into a storage backend whenever a property is set.
2794
2826
  *
2795
- * @param {object} target - The object to wrap
2827
+ * @param {Record<PropertyKey, any>} target - The object to wrap
2796
2828
  * @param {string} key - The storage key
2797
- * @param {object} storage - Any storage-like object with getItem/setItem/removeItem
2829
+ * @param {import("../../core/di/inteface").StorageLike & import("../../core/di/inteface").PersistentStoreConfig} storage - Any storage-like object with getItem/setItem/removeItem
2798
2830
  * @param {{serialize?: function, deserialize?: function}} [options] - Optional custom (de)serialization
2799
- * @returns {Proxy}
2831
+ * @returns {Record<PropertyKey, any>}
2800
2832
  */
2801
2833
  function createPersistentProxy(target, key, storage, options = {}) {
2802
2834
  const serialize = options.serialize || JSON.stringify;
@@ -2862,7 +2894,6 @@ function isPromise(obj) {
2862
2894
  }
2863
2895
 
2864
2896
  const BADARG = "badarg";
2865
- const BADARGVALUE = "badarg: value";
2866
2897
 
2867
2898
  /** @type {Map<ng.Validator, string>} */
2868
2899
  const reasons = new Map([
@@ -2965,6 +2996,25 @@ function createInjector(modulesToLoad, strictDi = false) {
2965
2996
  /** @type {Map<String|Function, boolean>} */
2966
2997
  const loadedModules = new Map(); // Keep track of loaded modules to avoid circular dependencies
2967
2998
 
2999
+ /**
3000
+ * @typedef {{
3001
+ * $provide: {
3002
+ * provider: Function,
3003
+ * factory: Function,
3004
+ * service: Function,
3005
+ * value: Function,
3006
+ * constant: Function,
3007
+ * store: Function,
3008
+ * decorator: Function,
3009
+ * },
3010
+ * $injectorProvider?: {
3011
+ * $get: () => unknown
3012
+ * },
3013
+ * $injector?: ProviderInjector
3014
+ * }} ProviderCache
3015
+ */
3016
+
3017
+ /** @type {ProviderCache} */
2968
3018
  const providerCache = {
2969
3019
  $provide: {
2970
3020
  provider: supportObject(provider),
@@ -3121,12 +3171,11 @@ function createInjector(modulesToLoad, strictDi = false) {
3121
3171
  * Registers a service persisted in a storage
3122
3172
  *
3123
3173
  * @param {string} name - Service name
3124
- * @param {Function} ctor - Constructor for the service
3174
+ * @param {import("../../interface.ts").Constructor} ctor - Constructor for the service
3125
3175
  * @param {ng.StorageType} type - Type of storage to be instantiated
3126
- * @param {Storage|Object} backendOrConfig - Either a Storage-like object (getItem/setItem) or a config object
3127
- * with { backend, serialize, deserialize }
3176
+ * @param {import("./inteface.ts").StorageLike & import("./inteface.ts").PersistentStoreConfig} [backendOrConfig]
3128
3177
  */
3129
- function store(name, ctor, type, backendOrConfig = {}) {
3178
+ function store(name, ctor, type, backendOrConfig) {
3130
3179
  return provider(name, {
3131
3180
  $get: /** @param {ng.InjectorService} $injector */ ($injector) => {
3132
3181
  switch (type) {
@@ -3145,11 +3194,11 @@ function createInjector(modulesToLoad, strictDi = false) {
3145
3194
 
3146
3195
  const $cookie = $injector.get($injectTokens._cookie);
3147
3196
 
3148
- const serialize = backendOrConfig.serialize ?? JSON.stringify;
3197
+ const serialize = backendOrConfig?.serialize ?? JSON.stringify;
3149
3198
 
3150
- const deserialize = backendOrConfig.deserialize ?? JSON.parse;
3199
+ const deserialize = backendOrConfig?.deserialize ?? JSON.parse;
3151
3200
 
3152
- const cookieOpts = backendOrConfig.cookie ?? {};
3201
+ const cookieOpts = backendOrConfig?.cookie ?? {};
3153
3202
 
3154
3203
  return createPersistentProxy(instance, name, {
3155
3204
  getItem(key) {
@@ -3199,10 +3248,15 @@ function createInjector(modulesToLoad, strictDi = false) {
3199
3248
  backend = localStorage;
3200
3249
  }
3201
3250
 
3202
- return createPersistentProxy(instance, name, backend, {
3203
- serialize,
3204
- deserialize,
3205
- });
3251
+ return createPersistentProxy(
3252
+ instance,
3253
+ name,
3254
+ /** @type {import("./inteface.ts").StorageLike} */ (backend),
3255
+ {
3256
+ serialize,
3257
+ deserialize,
3258
+ },
3259
+ );
3206
3260
  }
3207
3261
  }
3208
3262
 
@@ -3679,7 +3733,7 @@ function HttpProvider() {
3679
3733
  *
3680
3734
  * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the
3681
3735
  * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.
3682
- *
3736
+ * @type {import("./interface.ts").HttpProviderDefaults}
3683
3737
  */
3684
3738
  const defaults = (this.defaults = {
3685
3739
  // transform incoming response data
@@ -3748,6 +3802,7 @@ function HttpProvider() {
3748
3802
  * array, on request, but reverse order, on response.
3749
3803
  *
3750
3804
  * {@link ng.$http#interceptors Interceptors detailed info}
3805
+ * @type {Array<string | ng.Injectable<import("./interface.ts").HttpInterceptorFactory>>}
3751
3806
  */
3752
3807
  this.interceptors = [];
3753
3808
 
@@ -3791,19 +3846,6 @@ function HttpProvider() {
3791
3846
  */
3792
3847
  this.xsrfTrustedOrigins = [];
3793
3848
 
3794
- /**
3795
- * This property is deprecated. Use {@link $httpProvider#xsrfTrustedOrigins xsrfTrustedOrigins}
3796
- * instead.
3797
- */
3798
- Object.defineProperty(this, "xsrfWhitelistedOrigins", {
3799
- get() {
3800
- return this.xsrfTrustedOrigins;
3801
- },
3802
- set(origins) {
3803
- this.xsrfTrustedOrigins = origins;
3804
- },
3805
- });
3806
-
3807
3849
  const that = this;
3808
3850
 
3809
3851
  this.$get = [
@@ -4688,14 +4730,14 @@ function createHttpDirective(method, attrName) {
4688
4730
  * @param {import("./interface.ts").SwapModeType} swap
4689
4731
  * @param {ng.Scope} scopeParam
4690
4732
  * @param {ng.Attributes} attrsParam
4691
- * @param {Element} elmenetParam
4733
+ * @param {Element} elementParam
4692
4734
  */
4693
4735
  function handleSwapResponse(
4694
4736
  html,
4695
4737
  swap,
4696
4738
  scopeParam,
4697
4739
  attrsParam,
4698
- elmenetParam,
4740
+ elementParam,
4699
4741
  ) {
4700
4742
  let animationEnabled = false;
4701
4743
 
@@ -4718,7 +4760,7 @@ function createHttpDirective(method, attrName) {
4718
4760
 
4719
4761
  const target = targetSelector
4720
4762
  ? document.querySelector(targetSelector)
4721
- : elmenetParam;
4763
+ : elementParam;
4722
4764
 
4723
4765
  if (!target) {
4724
4766
  $log.warn(`${attrName}: target "${targetSelector}" not found`);
@@ -5679,14 +5721,14 @@ class NodeRef {
5679
5721
  * @throws {Error} If the argument is invalid or cannot be wrapped properly.
5680
5722
  */
5681
5723
  constructor(element) {
5682
- /** @private @type {Node | ChildNode | null} */
5683
- this._node = null;
5724
+ /** @private @type {Node | ChildNode | undefined} */
5725
+ this._node = undefined;
5684
5726
 
5685
5727
  /** @type {Element | undefined} */
5686
5728
  this._element = undefined;
5687
5729
 
5688
- /** @private @type {Array<Node> | undefined} a stable list on nodes */
5689
- this._nodes = undefined;
5730
+ /** @private @type {Array<Node>} a stable list on nodes */
5731
+ this._nodes = [];
5690
5732
 
5691
5733
  /** @type {boolean} */
5692
5734
  this._isList = false;
@@ -5804,7 +5846,9 @@ class NodeRef {
5804
5846
  if (this._isList) {
5805
5847
  return this._nodes[0];
5806
5848
  } else {
5807
- return this._element || this._node;
5849
+ return /** @type {Element | Node | ChildNode} */ (
5850
+ this._element || this._node
5851
+ );
5808
5852
  }
5809
5853
  }
5810
5854
 
@@ -5813,7 +5857,9 @@ class NodeRef {
5813
5857
  if (this._isList) {
5814
5858
  return this._nodes;
5815
5859
  } else {
5816
- return this._element || this._node;
5860
+ return /** @type {Element | Node | ChildNode} */ (
5861
+ this._element || this._node
5862
+ );
5817
5863
  }
5818
5864
  }
5819
5865
 
@@ -5822,7 +5868,9 @@ class NodeRef {
5822
5868
  if (this._isList) {
5823
5869
  return Array.from(this._nodes);
5824
5870
  } else {
5825
- return [this._element || this._node];
5871
+ return [
5872
+ /** @type {Element | Node | ChildNode} */ (this._element || this._node),
5873
+ ];
5826
5874
  }
5827
5875
  }
5828
5876
 
@@ -6978,10 +7026,29 @@ const SIMPLE_ATTR_NAME = /^\w/;
6978
7026
 
6979
7027
  const specialAttrHolder = document.createElement("div");
6980
7028
 
7029
+ /**
7030
+ * @extends {Record<string, any>}
7031
+ */
6981
7032
  class Attributes {
6982
7033
  static $nonscope = true;
6983
7034
 
6984
7035
  /**
7036
+ * Creates an Attributes instance.
7037
+ *
7038
+ * There are two construction modes:
7039
+ *
7040
+ * 1. **Fresh instance** (no `attributesToCopy`):
7041
+ * - Used when compiling a DOM element for the first time.
7042
+ * - Initializes a new `$attr` map to track normalized → DOM attribute names.
7043
+ *
7044
+ * 2. **Clone instance** (`attributesToCopy` provided):
7045
+ * - Used when cloning attributes for directive linking / child scopes.
7046
+ * - Performs a shallow copy of all properties from the source Attributes object,
7047
+ * including `$attr`, normalized attribute values, and internal fields
7048
+ * (e.g. `$$observers`).
7049
+ * - `$attr` is intentionally **not reinitialized** in this case, because the
7050
+ * source object already contains the correct normalized → DOM attribute mapping.
7051
+ *
6985
7052
  * @param {ng.AnimateService} $animate
6986
7053
  * @param {ng.ExceptionHandlerService} $exceptionHandler
6987
7054
  * @param {*} $sce
@@ -7002,16 +7069,20 @@ class Attributes {
7002
7069
  this[key] = attributesToCopy[key];
7003
7070
  }
7004
7071
  } else {
7072
+ /**
7073
+ * A map of DOM element attribute names to the normalized name. This is needed
7074
+ * to do reverse lookup from normalized name back to actual name.
7075
+ */
7005
7076
  this.$attr = {};
7006
7077
  }
7007
7078
 
7008
7079
  /** @type {import("../../shared/noderef.js").NodeRef} */
7009
- this.$nodeRef = nodeRef;
7080
+ this._nodeRef = nodeRef;
7010
7081
  }
7011
7082
 
7012
7083
  /** @type {Node|Element} */
7013
7084
  get $$element() {
7014
- return this.$nodeRef.node;
7085
+ return this._nodeRef.node;
7015
7086
  }
7016
7087
 
7017
7088
  /**
@@ -7040,7 +7111,7 @@ class Attributes {
7040
7111
  classVal,
7041
7112
  );
7042
7113
  } else {
7043
- this.$nodeRef.element.classList.add(classVal);
7114
+ this._nodeRef.element.classList.add(classVal);
7044
7115
  }
7045
7116
  }
7046
7117
  }
@@ -7059,7 +7130,7 @@ class Attributes {
7059
7130
  classVal,
7060
7131
  );
7061
7132
  } else {
7062
- this.$nodeRef.element.classList.remove(classVal);
7133
+ this._nodeRef.element.classList.remove(classVal);
7063
7134
  }
7064
7135
  }
7065
7136
  }
@@ -7078,7 +7149,7 @@ class Attributes {
7078
7149
  if (hasAnimate(this.$$element)) {
7079
7150
  this._$animate.addClass(/** @type {Element }*/ (this.$$element), toAdd);
7080
7151
  } else {
7081
- this.$nodeRef.element.classList.add(...toAdd.trim().split(/\s+/));
7152
+ this._nodeRef.element.classList.add(...toAdd.trim().split(/\s+/));
7082
7153
  }
7083
7154
  }
7084
7155
  const toRemove = tokenDifference(oldClasses, newClasses);
@@ -7090,7 +7161,7 @@ class Attributes {
7090
7161
  toRemove,
7091
7162
  );
7092
7163
  } else {
7093
- this.$nodeRef.element.classList.remove(...toRemove.trim().split(/\s+/));
7164
+ this._nodeRef.element.classList.remove(...toRemove.trim().split(/\s+/));
7094
7165
  }
7095
7166
  }
7096
7167
  }
@@ -7138,7 +7209,7 @@ class Attributes {
7138
7209
  }
7139
7210
  }
7140
7211
 
7141
- const nodeName = this.$nodeRef.node.nodeName.toLowerCase();
7212
+ const nodeName = this._nodeRef.node.nodeName.toLowerCase();
7142
7213
 
7143
7214
  let maybeSanitizedValue;
7144
7215
 
@@ -7199,6 +7270,7 @@ class Attributes {
7199
7270
  }
7200
7271
 
7201
7272
  /**
7273
+ * @template T
7202
7274
  * Observes an interpolated attribute.
7203
7275
  *
7204
7276
  * The observer function will be invoked once during the next `$digest` following
@@ -7206,11 +7278,11 @@ class Attributes {
7206
7278
  * changes.
7207
7279
  *
7208
7280
  * @param {string} key Normalized key. (ie ngAttribute) .
7209
- * @param {any} fn Function that will be called whenever
7281
+ * @param {(value?: T) => any} fn Function that will be called whenever
7210
7282
  the interpolated value of the attribute changes.
7211
7283
  * See the {@link guide/interpolation#how-text-and-attribute-bindings-work Interpolation
7212
7284
  * guide} for more info.
7213
- * @returns {function()} Returns a deregistration function for this observer.
7285
+ * @returns {Function} Returns a deregistration function for this observer.
7214
7286
  */
7215
7287
  $observe(key, fn) {
7216
7288
  const $$observers =
@@ -8364,7 +8436,7 @@ class CompileProvider {
8364
8436
  * @param {Attributes|any} attrs The shared attrs object which is used to populate the normalized attributes.
8365
8437
  * @param {number=} maxPriority Max directive priority.
8366
8438
  * @param {string} [ignoreDirective]
8367
- * @return {import('../../interface.ts').Directive[]} An array to which the directives are added to. This array is sorted before the function returns.
8439
+ * @return {ng.Directive[]} An array to which the directives are added to. This array is sorted before the function returns.
8368
8440
  */
8369
8441
  function collectDirectives(node, attrs, maxPriority, ignoreDirective) {
8370
8442
  /**
@@ -8615,7 +8687,7 @@ class CompileProvider {
8615
8687
 
8616
8688
  const { index } = previousCompileContext;
8617
8689
 
8618
- templateAttrs.$nodeRef = compileNodeRef;
8690
+ templateAttrs._nodeRef = compileNodeRef;
8619
8691
  let directive;
8620
8692
 
8621
8693
  let directiveName;
@@ -8666,7 +8738,7 @@ class CompileProvider {
8666
8738
 
8667
8739
  if (compileNode === linkNode) {
8668
8740
  attrs = templateAttrs;
8669
- $element = templateAttrs.$nodeRef;
8741
+ $element = templateAttrs._nodeRef;
8670
8742
  } else {
8671
8743
  $element = new NodeRef(linkNode);
8672
8744
  attrs = new Attributes(
@@ -9092,7 +9164,7 @@ class CompileProvider {
9092
9164
  terminalPriority = directive.priority;
9093
9165
  $template = compileNodeRef;
9094
9166
  compileNodeRef = new NodeRef(document.createComment(""));
9095
- templateAttrs.$nodeRef = compileNodeRef;
9167
+ templateAttrs._nodeRef = compileNodeRef;
9096
9168
  compileNode = compileNodeRef.node;
9097
9169
  ctxNodeRef.node = compileNode;
9098
9170
  replaceWith(
@@ -10791,13 +10863,13 @@ function assertValidDirectiveName(name) {
10791
10863
  * $nonscope: boolean,
10792
10864
  * $addControl: Function,
10793
10865
  * $getControls: () => any[],
10794
- * $$renameControl: Function,
10866
+ * _renameControl: Function,
10795
10867
  * $removeControl: Function,
10796
10868
  * $setValidity: Function | ((key: any, isValid: boolean, control: any) => any),
10797
10869
  * $setDirty: Function,
10798
10870
  * $setPristine: Function,
10799
10871
  * $setSubmitted: Function,
10800
- * $$setSubmitted: Function
10872
+ * _setSubmitted: Function
10801
10873
  * }}
10802
10874
  */
10803
10875
  const nullFormCtrl = {
@@ -10806,7 +10878,7 @@ const nullFormCtrl = {
10806
10878
  /* empty */
10807
10879
  },
10808
10880
  $getControls: () => [],
10809
- $$renameControl: (control, name) => {
10881
+ _renameControl: (control, name) => {
10810
10882
  control.$name = name;
10811
10883
  },
10812
10884
  $removeControl: () => {
@@ -10824,7 +10896,7 @@ const nullFormCtrl = {
10824
10896
  $setSubmitted: () => {
10825
10897
  /* empty */
10826
10898
  },
10827
- $$setSubmitted: () => {
10899
+ _setSubmitted: () => {
10828
10900
  /* empty */
10829
10901
  },
10830
10902
  };
@@ -10881,11 +10953,11 @@ const SUBMITTED_CLASS = "ng-submitted";
10881
10953
  class FormController {
10882
10954
  static $nonscope = true;
10883
10955
  /* @ignore */ static $inject = [
10884
- "$element",
10885
- "$attrs",
10886
- "$scope",
10887
- "$animate",
10888
- "$interpolate",
10956
+ $injectTokens._element,
10957
+ $injectTokens._attrs,
10958
+ $injectTokens._scope,
10959
+ $injectTokens._animate,
10960
+ $injectTokens._interpolate,
10889
10961
  ];
10890
10962
 
10891
10963
  /**
@@ -10896,7 +10968,7 @@ class FormController {
10896
10968
  * @param {ng.InterpolateService} $interpolate
10897
10969
  */
10898
10970
  constructor($element, $attrs, $scope, $animate, $interpolate) {
10899
- this.$$controls = [];
10971
+ this._controls = [];
10900
10972
 
10901
10973
  this.$name = $interpolate($attrs.name || $attrs.ngForm || "")($scope);
10902
10974
 
@@ -10925,6 +10997,7 @@ class FormController {
10925
10997
 
10926
10998
  this.$$classCache[VALID_CLASS] = isValid;
10927
10999
  this.$$classCache[INVALID_CLASS] = !isValid;
11000
+ this.$target = {};
10928
11001
  }
10929
11002
 
10930
11003
  /**
@@ -10935,7 +11008,7 @@ class FormController {
10935
11008
  * a form that uses `ng-model-options` to pend updates.
10936
11009
  */
10937
11010
  $rollbackViewValue() {
10938
- this.$$controls.forEach((control) => {
11011
+ this._controls.forEach((control) => {
10939
11012
  control.$rollbackViewValue();
10940
11013
  });
10941
11014
  }
@@ -10948,7 +11021,7 @@ class FormController {
10948
11021
  * usually handles calling this in response to input events.
10949
11022
  */
10950
11023
  $commitViewValue() {
10951
- this.$$controls.forEach((control) => {
11024
+ this._controls.forEach((control) => {
10952
11025
  control.$commitViewValue();
10953
11026
  });
10954
11027
  }
@@ -10972,7 +11045,7 @@ class FormController {
10972
11045
  // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
10973
11046
  // and not added to the scope. Now we throw an error.
10974
11047
  assertNotHasOwnProperty(control.$name, "input");
10975
- this.$$controls.push(control);
11048
+ this._controls.push(control);
10976
11049
 
10977
11050
  if (control.$name) {
10978
11051
  this[control.$name] = control;
@@ -10994,13 +11067,14 @@ class FormController {
10994
11067
  * Likewise, adding a control to, or removing a control from the form is not reflected
10995
11068
  * in the shallow copy. That means you should get a fresh copy from `$getControls()` every time
10996
11069
  * you need access to the controls.
11070
+ * @returns {ReadonlyArray<FormController>}
10997
11071
  */
10998
11072
  $getControls() {
10999
- return shallowCopy(this.$$controls);
11073
+ return shallowCopy(this._controls);
11000
11074
  }
11001
11075
 
11002
11076
  // Private API: rename a form control
11003
- $$renameControl(control, newName) {
11077
+ _renameControl(control, newName) {
11004
11078
  const oldName = control.$name;
11005
11079
 
11006
11080
  if (this[oldName] === control) {
@@ -11019,6 +11093,7 @@ class FormController {
11019
11093
  * form. `$dirty`, `$submitted` states will not be changed, because the expected behavior can be
11020
11094
  * different from case to case. For example, removing the only `$dirty` control from a form may or
11021
11095
  * may not mean that the form is still `$dirty`.
11096
+ * @param {FormController } control
11022
11097
  */
11023
11098
  $removeControl(control) {
11024
11099
  if (control.$name && this[control.$name] === control) {
@@ -11037,7 +11112,7 @@ class FormController {
11037
11112
  this.$setValidity(name, null, control);
11038
11113
  });
11039
11114
 
11040
- arrayRemove(this.$$controls, control);
11115
+ arrayRemove(this._controls, control);
11041
11116
 
11042
11117
  control.$target.$$parentForm = nullFormCtrl;
11043
11118
  }
@@ -11090,7 +11165,7 @@ class FormController {
11090
11165
  this.$dirty = false;
11091
11166
  this.$pristine = true;
11092
11167
  this.$submitted = false;
11093
- this.$$controls.forEach((control) => {
11168
+ this._controls.forEach((control) => {
11094
11169
  control.$setPristine();
11095
11170
  });
11096
11171
  }
@@ -11105,7 +11180,7 @@ class FormController {
11105
11180
  * back to its pristine state.
11106
11181
  */
11107
11182
  $setUntouched() {
11108
- this.$$controls.forEach((control) => {
11183
+ this._controls.forEach((control) => {
11109
11184
  control.$setUntouched();
11110
11185
  });
11111
11186
  }
@@ -11121,19 +11196,19 @@ class FormController {
11121
11196
  while (rootForm.$$parentForm && rootForm.$$parentForm !== nullFormCtrl) {
11122
11197
  rootForm = rootForm.$$parentForm;
11123
11198
  }
11124
- rootForm.$$setSubmitted();
11199
+ rootForm._setSubmitted();
11125
11200
  }
11126
11201
 
11127
- $$setSubmitted() {
11202
+ _setSubmitted() {
11128
11203
  if (hasAnimate(this.$$element)) {
11129
11204
  this.$$animate.addClass(this.$$element, SUBMITTED_CLASS);
11130
11205
  } else {
11131
11206
  this.$$element.classList.add(SUBMITTED_CLASS);
11132
11207
  }
11133
11208
  this.$submitted = true;
11134
- this.$$controls.forEach((control) => {
11135
- if (control.$$setSubmitted) {
11136
- control.$$setSubmitted();
11209
+ this._controls.forEach((control) => {
11210
+ if (control._setSubmitted) {
11211
+ control._setSubmitted();
11137
11212
  }
11138
11213
  });
11139
11214
  }
@@ -11451,7 +11526,7 @@ const formDirectiveFactory = function (isNgForm) {
11451
11526
  attrParam.$observe(nameAttr, (newValue) => {
11452
11527
  if (controller.$name === newValue) return;
11453
11528
  scope.$target[controller.$name] = undefined;
11454
- controller.$$parentForm.$$renameControl(controller, newValue);
11529
+ controller.$$parentForm._renameControl(controller, newValue);
11455
11530
 
11456
11531
  if (
11457
11532
  scope.$target !== controller.$$parentForm &&
@@ -11674,12 +11749,12 @@ const ngModelMinErr = minErr("ngModel");
11674
11749
  */
11675
11750
 
11676
11751
  class NgModelController {
11677
- static $nonscope = true;
11752
+ /* @ignore */ static $nonscope = true;
11678
11753
  /* @ignore */ static $inject = [
11679
- "$scope",
11754
+ $injectTokens._scope,
11680
11755
  $injectTokens._exceptionHandler,
11681
- "$attrs",
11682
- "$element",
11756
+ $injectTokens._attrs,
11757
+ $injectTokens._element,
11683
11758
  $injectTokens._parse,
11684
11759
  $injectTokens._animate,
11685
11760
  $injectTokens._interpolate,
@@ -11711,19 +11786,19 @@ class NgModelController {
11711
11786
  /** @type {any} */
11712
11787
  this.$$rawModelValue = undefined; // stores the parsed modelValue / model set from scope regardless of validity.
11713
11788
 
11714
- /** @type {any} */
11789
+ /** @type {import("./interface.ts").ModelValidators} */
11715
11790
  this.$validators = {};
11716
11791
 
11717
- /** @type {any} */
11792
+ /** @type {import("./interface.ts").AsyncModelValidators} */
11718
11793
  this.$asyncValidators = {};
11719
11794
 
11720
- /** @type {Array<any>} */
11795
+ /** @type {Array<import("./interface.ts").ModelParser>} */
11721
11796
  this.$parsers = [];
11722
11797
 
11723
- /** @type {Array<any>} */
11798
+ /** @type {Array<import("./interface.ts").ModelFormatter>} */
11724
11799
  this.$formatters = [];
11725
11800
 
11726
- /** @type {Array<any>} */
11801
+ /** @type {Array<import("./interface.ts").ModelViewChangeListener>} */
11727
11802
  this.$viewChangeListeners = [];
11728
11803
 
11729
11804
  /** @type {boolean} */
@@ -11754,15 +11829,15 @@ class NgModelController {
11754
11829
  // Attach the correct context to the event handler function for updateOn
11755
11830
  this.$$updateEventHandler = this.$$updateEventHandler.bind(this);
11756
11831
 
11757
- this.$$parsedNgModel = $parse($attr.ngModel);
11758
- this.$$parsedNgModelAssign = this.$$parsedNgModel.assign;
11832
+ this._parsedNgModel = $parse($attr.ngModel);
11833
+ this._parsedNgModelAssign = this._parsedNgModel.assign;
11759
11834
 
11760
11835
  /**
11761
11836
  * @type {import("../../core/parse/interface.ts").CompiledExpression |
11762
11837
  * (function(ng.Scope): any)}
11763
11838
  */
11764
- this.$$ngModelGet = this.$$parsedNgModel;
11765
- this.$$ngModelSet = this.$$parsedNgModelAssign;
11839
+ this._ngModelGet = this._parsedNgModel;
11840
+ this._ngModelSet = this._parsedNgModelAssign;
11766
11841
  this.$$pendingDebounce = null;
11767
11842
  this.$$parserValid = undefined;
11768
11843
 
@@ -11911,8 +11986,8 @@ class NgModelController {
11911
11986
 
11912
11987
  const invokeModelSetter = this.$$parse(`${this.$$attr.ngModel}($$$p)`);
11913
11988
 
11914
- this.$$ngModelGet = ($scope) => {
11915
- let modelValue = this.$$parsedNgModel($scope);
11989
+ this._ngModelGet = ($scope) => {
11990
+ let modelValue = this._parsedNgModel($scope);
11916
11991
 
11917
11992
  if (isFunction(modelValue)) {
11918
11993
  modelValue = invokeModelGetter($scope);
@@ -11920,14 +11995,14 @@ class NgModelController {
11920
11995
 
11921
11996
  return modelValue;
11922
11997
  };
11923
- this.$$ngModelSet = ($scope, newValue) => {
11924
- if (isFunction(this.$$parsedNgModel($scope))) {
11998
+ this._ngModelSet = ($scope, newValue) => {
11999
+ if (isFunction(this._parsedNgModel($scope))) {
11925
12000
  invokeModelSetter($scope, { $$$p: newValue });
11926
12001
  } else {
11927
- this.$$parsedNgModelAssign($scope, newValue);
12002
+ this._parsedNgModelAssign($scope, newValue);
11928
12003
  }
11929
12004
  };
11930
- } else if (!this.$$parsedNgModel.assign) {
12005
+ } else if (!this._parsedNgModel.assign) {
11931
12006
  throw ngModelMinErr(
11932
12007
  "nonassign",
11933
12008
  "Expression '{0}' is non-assignable. Element: {1}",
@@ -12403,7 +12478,7 @@ class NgModelController {
12403
12478
  if (isNumberNaN(this.$modelValue)) {
12404
12479
  // this.$modelValue has not been touched yet...
12405
12480
  // @ts-ignore
12406
- this.$modelValue = this.$$ngModelGet(this.$$scope);
12481
+ this.$modelValue = this._ngModelGet(this.$$scope);
12407
12482
  }
12408
12483
  const prevModelValue = this.$modelValue;
12409
12484
 
@@ -12440,13 +12515,15 @@ class NgModelController {
12440
12515
  // intentional loose equality
12441
12516
  // eslint-disable-next-line eqeqeq
12442
12517
  if (that.$modelValue != prevModelValue) {
12518
+ if (isNull(that.$modelValue) && prevModelValue === "") return;
12519
+
12443
12520
  that.$$writeModelToScope();
12444
12521
  }
12445
12522
  }
12446
12523
  }
12447
12524
 
12448
12525
  $$writeModelToScope() {
12449
- this.$$ngModelSet(this.$$scope, this.$modelValue);
12526
+ this._ngModelSet(this.$$scope, this.$modelValue);
12450
12527
  Object.values(this.$viewChangeListeners).forEach((listener) => {
12451
12528
  try {
12452
12529
  listener();
@@ -12564,7 +12641,7 @@ class NgModelController {
12564
12641
  * **Note:** it is not possible to override the `getterSetter` option.
12565
12642
  * </div>
12566
12643
  *
12567
- * @param {Object} options a hash of settings to override the previous options
12644
+ * @param {import("../../interface.ts").NgModelOptions} options a hash of settings to override the previous options
12568
12645
  *
12569
12646
  */
12570
12647
  $overrideModelOptions(options) {
@@ -12763,7 +12840,7 @@ function setupModelWatcher(ctrl) {
12763
12840
  // ng-change executes in apply phase
12764
12841
  // 4. view should be changed back to 'a'
12765
12842
  ctrl.$$scope.$watch("value", () => {
12766
- const modelValue = ctrl.$$ngModelGet(ctrl.$$scope);
12843
+ const modelValue = ctrl._ngModelGet(ctrl.$$scope);
12767
12844
 
12768
12845
  // if scope model value and ngModel value are out of sync
12769
12846
  // This cannot be moved to the action function, because it would not catch the
@@ -12812,7 +12889,7 @@ function ngModelDirective() {
12812
12889
 
12813
12890
  attr.$observe("name", (newValue) => {
12814
12891
  if (modelCtrl.$name !== newValue) {
12815
- modelCtrl.$$parentForm.$$renameControl(modelCtrl, newValue);
12892
+ modelCtrl.$$parentForm._renameControl(modelCtrl, newValue);
12816
12893
  }
12817
12894
  });
12818
12895
  const deregisterWatch = scope.$watch(attr.ngModel, (val) => {
@@ -13982,6 +14059,40 @@ function ngValueDirective() {
13982
14059
  };
13983
14060
  }
13984
14061
 
14062
+ /**
14063
+ * @param {Date} date
14064
+ * @param {any} timezone
14065
+ * @param {undefined} [reverse]
14066
+ */
14067
+ function convertTimezoneToLocal(date, timezone, reverse) {
14068
+ const doReverse = 1;
14069
+
14070
+ const dateTimezoneOffset = date.getTimezoneOffset();
14071
+
14072
+ const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
14073
+
14074
+ return addDateMinutes(
14075
+ date,
14076
+ doReverse * (timezoneOffset - dateTimezoneOffset),
14077
+ );
14078
+ }
14079
+
14080
+ const MS_PER_MINUTE = 60_000; // 60,000 ms in a minute
14081
+
14082
+ /**
14083
+ * @param {any} timezone
14084
+ * @param {number} [fallback]
14085
+ * @returns {number}
14086
+ */
14087
+ function timezoneToOffset(timezone, fallback) {
14088
+ const requestedTimezoneOffset =
14089
+ Date.parse(`Jan 01, 1970 00:00:00 ${timezone}`) / MS_PER_MINUTE;
14090
+
14091
+ return isNumberNaN(requestedTimezoneOffset)
14092
+ ? (fallback ?? 0)
14093
+ : requestedTimezoneOffset;
14094
+ }
14095
+
13985
14096
  scriptDirective.$inject = [$injectTokens._templateCache];
13986
14097
 
13987
14098
  /**
@@ -14011,8 +14122,6 @@ class SelectController {
14011
14122
  "selectValueMap",
14012
14123
  "emptyOption",
14013
14124
  "optionsMap",
14014
- "$scope",
14015
- "$element",
14016
14125
  ];
14017
14126
 
14018
14127
  /**
@@ -14040,8 +14149,8 @@ class SelectController {
14040
14149
  /** @type {boolean} */
14041
14150
  this.multiple = false;
14042
14151
 
14043
- /** @type {HTMLOptionElement} */
14044
- this.unknownOption = document.createElement("option");
14152
+ /** @private @type {HTMLOptionElement} */
14153
+ this._unknownOption = document.createElement("option");
14045
14154
 
14046
14155
  /** @type {boolean} */
14047
14156
  this.hasEmptyOption = false;
@@ -14073,10 +14182,10 @@ class SelectController {
14073
14182
  renderUnknownOption(val) {
14074
14183
  const unknownVal = this.generateUnknownOptionValue(val);
14075
14184
 
14076
- this.unknownOption.value = unknownVal;
14077
- this.$element.prepend(this.unknownOption);
14078
- this.unknownOption.selected = true;
14079
- this.unknownOption.setAttribute("selected", "selected");
14185
+ this._unknownOption.value = unknownVal;
14186
+ this.$element.prepend(this._unknownOption);
14187
+ this._unknownOption.selected = true;
14188
+ this._unknownOption.setAttribute("selected", "selected");
14080
14189
  this.$element.value = unknownVal;
14081
14190
  }
14082
14191
 
@@ -14087,9 +14196,9 @@ class SelectController {
14087
14196
  updateUnknownOption(val) {
14088
14197
  const unknownVal = this.generateUnknownOptionValue(val);
14089
14198
 
14090
- this.unknownOption.value = unknownVal;
14091
- this.unknownOption.selected = true;
14092
- this.unknownOption.setAttribute("selected", "selected");
14199
+ this._unknownOption.value = unknownVal;
14200
+ this._unknownOption.selected = true;
14201
+ this._unknownOption.setAttribute("selected", "selected");
14093
14202
  this.$element.value = unknownVal;
14094
14203
  }
14095
14204
 
@@ -14110,7 +14219,7 @@ class SelectController {
14110
14219
  * Remove the unknown option from the select element if it exists.
14111
14220
  */
14112
14221
  removeUnknownOption() {
14113
- if (this.unknownOption.parentElement) this.unknownOption.remove();
14222
+ if (this._unknownOption.parentElement) this._unknownOption.remove();
14114
14223
  }
14115
14224
 
14116
14225
  /**
@@ -14235,7 +14344,7 @@ class SelectController {
14235
14344
  * @returns {boolean} Whether the unknown option is currently selected.
14236
14345
  */
14237
14346
  $isUnknownOptionSelected() {
14238
- return this.$element.options[0] === this.unknownOption;
14347
+ return this.$element.options[0] === this._unknownOption;
14239
14348
  }
14240
14349
 
14241
14350
  /**
@@ -14256,7 +14365,7 @@ class SelectController {
14256
14365
  if (isNullOrUndefined(value) && this.emptyOption) {
14257
14366
  this.removeUnknownOption();
14258
14367
  this.selectEmptyOption();
14259
- } else if (this.unknownOption.parentElement) {
14368
+ } else if (this._unknownOption.parentElement) {
14260
14369
  this.updateUnknownOption(value);
14261
14370
  } else {
14262
14371
  this.renderUnknownOption(value);
@@ -14415,7 +14524,7 @@ class SelectController {
14415
14524
  }
14416
14525
 
14417
14526
  /**
14418
- * @returns {import('../../interface.ts').Directive}
14527
+ * @returns {ng.Directive}
14419
14528
  */
14420
14529
  function selectDirective() {
14421
14530
  return {
@@ -14638,7 +14747,9 @@ function ngBindDirective() {
14638
14747
  scope.$watch(
14639
14748
  attr.ngBind,
14640
14749
  (value) => {
14641
- element.textContent = stringify$1(deProxy(value));
14750
+ element.textContent = /** @type {string} */ (
14751
+ stringify$1(deProxy(value))
14752
+ );
14642
14753
  },
14643
14754
  isDefined(attr.lazy),
14644
14755
  );
@@ -14647,17 +14758,17 @@ function ngBindDirective() {
14647
14758
  }
14648
14759
 
14649
14760
  /**
14650
- * @returns {import('../../interface.ts').Directive}
14761
+ * @returns {ng.Directive}
14651
14762
  */
14652
14763
  function ngBindTemplateDirective() {
14653
14764
  return {
14654
14765
  /**
14655
14766
  * @param {ng.Scope} _scope
14656
14767
  * @param {Element} element
14657
- * @param {import('../../core/compile/attributes.js').Attributes} attr
14768
+ * @param {ng.Attributes} attr
14658
14769
  */
14659
14770
  link(_scope, element, attr) {
14660
- attr.$observe("ngBindTemplate", (value) => {
14771
+ attr.$observe("ngBindTemplate", (/** @type {string | null} */ value) => {
14661
14772
  element.textContent = isUndefined(value) ? "" : value;
14662
14773
  });
14663
14774
  },
@@ -14666,8 +14777,8 @@ function ngBindTemplateDirective() {
14666
14777
 
14667
14778
  ngBindHtmlDirective.$inject = [$injectTokens._parse];
14668
14779
  /**
14669
- * @param {import('../../core/parse/interface.ts').ParseService} $parse
14670
- * @returns {import('../../interface.ts').Directive}
14780
+ * @param {ng.ParseService} $parse
14781
+ * @returns {ng.Directive}
14671
14782
  */
14672
14783
  function ngBindHtmlDirective($parse) {
14673
14784
  return {
@@ -14956,7 +15067,7 @@ function ngShowDirective($animate) {
14956
15067
 
14957
15068
  ngHideDirective.$inject = [$injectTokens._animate];
14958
15069
  /**
14959
- * @returns {import('../../interface.ts').Directive}
15070
+ * @returns {ng.Directive}
14960
15071
  */
14961
15072
  function ngHideDirective($animate) {
14962
15073
  return {
@@ -14998,7 +15109,7 @@ function ngIfDirective($animate) {
14998
15109
  * @param {Element} $element
14999
15110
  * @param {ng.Attributes} $attr
15000
15111
  * @param {*} _ctrl
15001
- * @param {*} $transclude
15112
+ * @param {ng.TranscludeFn} $transclude
15002
15113
  */
15003
15114
  link($scope, $element, $attr, _ctrl, $transclude) {
15004
15115
  /** @type {Element | null | undefined} */
@@ -15013,23 +15124,28 @@ function ngIfDirective($animate) {
15013
15124
  $scope.$watch($attr.ngIf, (value) => {
15014
15125
  if (value) {
15015
15126
  if (!childScope) {
15016
- $transclude((clone, newScope) => {
15017
- childScope = newScope;
15018
- // Note: We only need the first/last node of the cloned nodes.
15019
- // However, we need to keep the reference to the dom wrapper as it might be changed later
15020
- // by a directive with templateUrl when its template arrives.
15021
- block = clone;
15022
-
15023
- if (hasAnimate(clone)) {
15024
- $animate.enter(
15025
- clone,
15026
- /** @type {Element} */ ($element.parentElement),
15027
- $element,
15028
- );
15029
- } else {
15030
- $element.after(clone);
15031
- }
15032
- });
15127
+ $transclude(
15128
+ (
15129
+ /** @type {Element} */ clone,
15130
+ /** @type {ng.Scope} */ newScope,
15131
+ ) => {
15132
+ childScope = newScope;
15133
+ // Note: We only need the first/last node of the cloned nodes.
15134
+ // However, we need to keep the reference to the dom wrapper as it might be changed later
15135
+ // by a directive with templateUrl when its template arrives.
15136
+ block = clone;
15137
+
15138
+ if (hasAnimate(/** @type {Node} */ (clone))) {
15139
+ $animate.enter(
15140
+ /** @type {Element} */ (clone),
15141
+ /** @type {Element} */ ($element.parentElement),
15142
+ $element,
15143
+ );
15144
+ } else {
15145
+ $element.after(/** @type {Node} */ (clone));
15146
+ }
15147
+ },
15148
+ );
15033
15149
  }
15034
15150
  } else {
15035
15151
  if (previousElements) {
@@ -15225,7 +15341,7 @@ function ngIncludeFillContentDirective($compile) {
15225
15341
  }
15226
15342
 
15227
15343
  /**
15228
- * @returns {import('../../interface.ts').Directive}
15344
+ * @returns {ng.Directive}
15229
15345
  */
15230
15346
  function ngInitDirective() {
15231
15347
  return {
@@ -15247,7 +15363,7 @@ function ngInitDirective() {
15247
15363
  }
15248
15364
 
15249
15365
  /**
15250
- * @returns {import('../../interface.ts').Directive}
15366
+ * @returns {ng.Directive}
15251
15367
  */
15252
15368
  function ngNonBindableDirective() {
15253
15369
  return {
@@ -15393,7 +15509,7 @@ function ngRepeatDirective($animate) {
15393
15509
  if (keyIdentifier) scope[keyIdentifier] = key;
15394
15510
 
15395
15511
  if (value) {
15396
- scope.$target.$$hashKey = value.$$hashKey;
15512
+ scope.$target._hashKey = value._hashKey;
15397
15513
  }
15398
15514
  scope.$index = index;
15399
15515
  scope.$first = index === 0;
@@ -15721,7 +15837,7 @@ function ngSwitchDirective($animate) {
15721
15837
 
15722
15838
  // asks for $scope to fool the BC controller module
15723
15839
  controller: [
15724
- "$scope",
15840
+ $injectTokens._scope,
15725
15841
  class {
15726
15842
  constructor() {
15727
15843
  this.cases = {};
@@ -15750,19 +15866,20 @@ function ngSwitchDirective($animate) {
15750
15866
 
15751
15867
  let ii;
15752
15868
 
15869
+ let runner;
15870
+
15753
15871
  // Start with the last, in case the array is modified during the loop
15754
15872
  while (previousLeaveAnimations.length) {
15755
15873
  $animate.cancel(previousLeaveAnimations.pop());
15756
15874
  }
15757
15875
 
15758
15876
  for (i = 0, ii = selectedScopes.length; i < ii; ++i) {
15759
- const selected = getBlockNodes(selectedElements[i].clone);
15877
+ const selected = selectedElements[i].clone;
15760
15878
 
15761
15879
  selectedScopes[i].$destroy();
15762
15880
 
15763
15881
  if (hasAnimate(selected)) {
15764
- const runner = (previousLeaveAnimations[i] =
15765
- $animate.leave(selected));
15882
+ runner = previousLeaveAnimations[i] = $animate.leave(selected);
15766
15883
 
15767
15884
  runner.done(spliceFactory(previousLeaveAnimations, i));
15768
15885
  } else {
@@ -15792,7 +15909,13 @@ function ngSwitchDirective($animate) {
15792
15909
  selectedElements.push(block);
15793
15910
 
15794
15911
  if (hasAnimate(caseElement)) {
15795
- $animate.enter(caseElement, anchor.parentElement, anchor);
15912
+ if (runner) {
15913
+ requestAnimationFrame(() => {
15914
+ $animate.enter(caseElement, anchor.parentElement, anchor);
15915
+ });
15916
+ } else {
15917
+ $animate.enter(caseElement, anchor.parentElement, anchor);
15918
+ }
15796
15919
  } else {
15797
15920
  domInsert(caseElement, anchor.parentElement, anchor);
15798
15921
  }
@@ -15805,7 +15928,7 @@ function ngSwitchDirective($animate) {
15805
15928
  }
15806
15929
 
15807
15930
  /**
15808
- * @returns {import('../../interface.ts').Directive}
15931
+ * @returns {ng.Directive}
15809
15932
  */
15810
15933
  function ngSwitchWhenDirective() {
15811
15934
  return {
@@ -15835,7 +15958,7 @@ function ngSwitchWhenDirective() {
15835
15958
  }
15836
15959
 
15837
15960
  /**
15838
- * @returns {import('../../interface.ts').Directive}
15961
+ * @returns {ng.Directive}
15839
15962
  */
15840
15963
  function ngSwitchDefaultDirective() {
15841
15964
  return {
@@ -17465,13 +17588,21 @@ function AnimateProvider($provide) {
17465
17588
  *
17466
17589
  * @param {Element} element - the element which will be inserted into the DOM
17467
17590
  * @param {Element} parent - the parent element which will append the element as a child (so long as the after element is not present)
17468
- * @param {Element} [after] - after the sibling element after which the element will be appended
17591
+ * @param {ChildNode | null | undefined} [after] - after the sibling element after which the element will be appended
17469
17592
  * @param {import("./interface.ts").AnimationOptions} [options] - an optional collection of options/styles that will be applied to the element.
17470
17593
  * @returns {import('./runner/animate-runner.js').AnimateRunner} the animation runner
17471
17594
  */
17472
17595
  enter(element, parent, after, options) {
17473
17596
  parent = parent || after.parentElement;
17474
- animatedomInsert(element, parent, after);
17597
+
17598
+ if (
17599
+ isInstanceOf(element, HTMLElement) &&
17600
+ isInstanceOf(parent, HTMLElement)
17601
+ ) {
17602
+ animatedomInsert(element, parent, after);
17603
+ } else {
17604
+ domInsert(element, parent, after);
17605
+ }
17475
17606
 
17476
17607
  return $$animateQueue.push(
17477
17608
  element,
@@ -17494,7 +17625,15 @@ function AnimateProvider($provide) {
17494
17625
  */
17495
17626
  move(element, parent, after, options) {
17496
17627
  parent = parent || after.parentElement;
17497
- animatedomInsert(element, parent, after);
17628
+
17629
+ if (
17630
+ isInstanceOf(element, HTMLElement) &&
17631
+ isInstanceOf(parent, HTMLElement)
17632
+ ) {
17633
+ animatedomInsert(element, parent, after);
17634
+ } else {
17635
+ domInsert(element, parent, after);
17636
+ }
17498
17637
 
17499
17638
  return $$animateQueue.push(
17500
17639
  element,
@@ -17533,7 +17672,7 @@ function AnimateProvider($provide) {
17533
17672
  *
17534
17673
  * @param {Element} element the element which the CSS classes will be applied to
17535
17674
  * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces)
17536
- * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
17675
+ * @param {import("./interface.ts").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element.
17537
17676
  * @return {import('./runner/animate-runner.js').AnimateRunner}} animationRunner the animation runner
17538
17677
  */
17539
17678
  addClass(element, className, options) {
@@ -17553,7 +17692,7 @@ function AnimateProvider($provide) {
17553
17692
  *
17554
17693
  * @param {Element} element the element which the CSS classes will be applied to
17555
17694
  * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces)
17556
- * @param {import("./interface").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
17695
+ * @param {import("./interface.ts").AnimationOptions} [options] an optional collection of options/styles that will be applied to the element. *
17557
17696
  * @return {import('./runner/animate-runner.js').AnimateRunner} animationRunner the animation runner
17558
17697
  */
17559
17698
  removeClass(element, className, options) {
@@ -18175,55 +18314,6 @@ function orderByFilter($parse) {
18175
18314
  }
18176
18315
  }
18177
18316
 
18178
- $IsStateFilter.$inject = [$injectTokens._state];
18179
-
18180
- /**
18181
- * `isState` Filter: truthy if the current state is the parameter
18182
- *
18183
- * Translates to [[StateService.is]] `$state.is("stateName")`.
18184
- *
18185
- * #### Example:
18186
- * ```html
18187
- * <div ng-if="'stateName' | isState">show if state is 'stateName'</div>
18188
- * ```
18189
- *
18190
- * @param {import('./state/state-service.js').StateProvider} $state
18191
- * @returns {ng.FilterFn}
18192
- */
18193
- function $IsStateFilter($state) {
18194
- const isFilter = (state, params, options) =>
18195
- $state.is(state, params, options);
18196
-
18197
- isFilter.$stateful = true;
18198
-
18199
- return isFilter;
18200
- }
18201
-
18202
- $IncludedByStateFilter.$inject = [$injectTokens._state];
18203
-
18204
- /**
18205
- * `includedByState` Filter: truthy if the current state includes the parameter
18206
- *
18207
- * Translates to [[StateService.includes]]` $state.is("fullOrPartialStateName")`.
18208
- *
18209
- * #### Example:
18210
- * ```html
18211
- * <div ng-if="'fullOrPartialStateName' | includedByState">show if state includes 'fullOrPartialStateName'</div>
18212
- * ```
18213
- *
18214
- * @param {import('./state/state-service.js').StateProvider} $state
18215
- * @returns {ng.FilterFn}
18216
- */
18217
- function $IncludedByStateFilter($state) {
18218
- const includesFilter = function (state, params, options) {
18219
- return $state.includes(state, params, options);
18220
- };
18221
-
18222
- includesFilter.$stateful = true;
18223
-
18224
- return includesFilter;
18225
- }
18226
-
18227
18317
  /* @ignore */
18228
18318
  const SUFFIX = "Filter";
18229
18319
 
@@ -18247,8 +18337,6 @@ class FilterProvider {
18247
18337
  json: jsonFilter,
18248
18338
  limitTo: limitToFilter,
18249
18339
  orderBy: orderByFilter,
18250
- isState: $IsStateFilter,
18251
- includedByState: $IncludedByStateFilter,
18252
18340
  }).forEach(([k, v]) =>
18253
18341
  this.register(k, /** @type {ng.FilterFactory} */ (v)),
18254
18342
  );
@@ -18372,9 +18460,9 @@ class ASTInterpreter {
18372
18460
  : function (scope, locals) {
18373
18461
  let lastValue;
18374
18462
 
18375
- expressions.forEach((exp) => {
18376
- lastValue = exp(scope, locals);
18377
- });
18463
+ for (let i = 0, j = expressions.length; i < j; i++) {
18464
+ lastValue = expressions[i](scope, locals);
18465
+ }
18378
18466
 
18379
18467
  return lastValue;
18380
18468
  };
@@ -19021,7 +19109,7 @@ function findConstantAndWatchExpressions(ast, $filter, parentIsPure) {
19021
19109
 
19022
19110
  let argsToWatch;
19023
19111
 
19024
- let isStatelessFilter;
19112
+ let isFilter;
19025
19113
 
19026
19114
  const decoratedNode = /** @type {DecoratedASTNode} */ (ast);
19027
19115
 
@@ -19152,10 +19240,8 @@ function findConstantAndWatchExpressions(ast, $filter, parentIsPure) {
19152
19240
 
19153
19241
  return decoratedNode;
19154
19242
  case ASTType._CallExpression:
19155
- isStatelessFilter = ast.filter
19156
- ? isStateless($filter, ast.callee.name)
19157
- : false;
19158
- allConstants = isStatelessFilter;
19243
+ isFilter = ast.filter;
19244
+ allConstants = isFilter;
19159
19245
  argsToWatch = [];
19160
19246
  ast.arguments.forEach((expr) => {
19161
19247
  decorated = findConstantAndWatchExpressions(expr, $filter, astIsPure);
@@ -19163,7 +19249,7 @@ function findConstantAndWatchExpressions(ast, $filter, parentIsPure) {
19163
19249
  argsToWatch.push.apply(argsToWatch, decorated.toWatch);
19164
19250
  });
19165
19251
  decoratedNode.constant = allConstants;
19166
- decoratedNode.toWatch = isStatelessFilter ? argsToWatch : [decoratedNode];
19252
+ decoratedNode.toWatch = isFilter ? argsToWatch : [decoratedNode];
19167
19253
 
19168
19254
  return decoratedNode;
19169
19255
  case ASTType._AssignmentExpression:
@@ -19310,12 +19396,6 @@ function isPure(node, parentIsPure) {
19310
19396
  return undefined === parentIsPure ? PURITY_RELATIVE : parentIsPure;
19311
19397
  }
19312
19398
 
19313
- function isStateless($filter, filterName) {
19314
- const fn = $filter(filterName);
19315
-
19316
- return !fn.$stateful;
19317
- }
19318
-
19319
19399
  /**
19320
19400
  * Converts parameter to strings property name for use as keys in an object.
19321
19401
  * Any non-string object, including a number, is typecasted into a string via the toString method.
@@ -20357,7 +20437,7 @@ class Parser {
20357
20437
  const fn = this._astCompiler.compile(ast);
20358
20438
 
20359
20439
  fn.literal = isLiteral(ast);
20360
- fn.constant = isConstant(ast);
20440
+ fn.constant = !!ast.constant;
20361
20441
 
20362
20442
  return fn;
20363
20443
  }
@@ -20375,18 +20455,25 @@ class Parser {
20375
20455
  }
20376
20456
  }
20377
20457
 
20458
+ /**
20459
+ * @param {import("../ast/ast-node.d.ts").ASTNode} ast
20460
+ * @returns {boolean}
20461
+ */
20378
20462
  function isLiteral(ast) {
20379
- return (
20380
- ast.body.length === 0 ||
20381
- (ast.body.length === 1 &&
20382
- (ast.body[0].expression.type === ASTType._Literal ||
20383
- ast.body[0].expression.type === ASTType._ArrayExpression ||
20384
- ast.body[0].expression.type === ASTType._ObjectExpression))
20385
- );
20386
- }
20463
+ const { body } = ast;
20387
20464
 
20388
- function isConstant(ast) {
20389
- return ast.constant;
20465
+ if (body && body.length === 1) {
20466
+ switch (body[0].expression?.type) {
20467
+ case ASTType._Literal:
20468
+ case ASTType._ArrayExpression:
20469
+ case ASTType._ObjectExpression:
20470
+ return true;
20471
+ default:
20472
+ return false;
20473
+ }
20474
+ } else {
20475
+ return true;
20476
+ }
20390
20477
  }
20391
20478
 
20392
20479
  class ParseProvider {
@@ -20431,7 +20518,7 @@ class ParseProvider {
20431
20518
  /**
20432
20519
  *
20433
20520
  * @param {(any) => any} $filter
20434
- * @returns {import('./interface').ParseService}
20521
+ * @returns {import('./interface.ts').ParseService}
20435
20522
  */
20436
20523
  function ($filter) {
20437
20524
  /** @type {import("./lexer/lexer.js").LexerOptions} */
@@ -20482,7 +20569,7 @@ class ParseProvider {
20482
20569
  /**
20483
20570
  * @param {Function} parsedExpression
20484
20571
  * @param interceptorFn
20485
- * @returns {import('./interface').CompiledExpression|*}
20572
+ * @returns {import('./interface.ts').CompiledExpression|*}
20486
20573
  */
20487
20574
  function addInterceptor(parsedExpression, interceptorFn) {
20488
20575
  if (!interceptorFn) {
@@ -20611,7 +20698,7 @@ function addWatchDelegate(parsedExpression) {
20611
20698
  * @param {ng.Scope} scope
20612
20699
  * @param {Function} listener
20613
20700
  * @param {*} objectEquality
20614
- * @param {import('./interface').CompiledExpression} parsedExpression
20701
+ * @param {import('./interface.ts').CompiledExpression} parsedExpression
20615
20702
  * @returns {any}
20616
20703
  */
20617
20704
  function inputsWatchDelegate(
@@ -21178,19 +21265,19 @@ let urlUpdatedByLocation = false;
21178
21265
  * The pathname, beginning with "/"
21179
21266
  * @type {string}
21180
21267
  */
21181
- let $$path;
21268
+ let _path;
21182
21269
 
21183
21270
  /**
21184
- * @type {Object.<string,boolean|Array>}
21271
+ * @type {Object.<string,boolean|Array<any>>}
21185
21272
  */
21186
- let $$search;
21273
+ let _search;
21187
21274
 
21188
21275
  /**
21189
21276
  * @ignore
21190
21277
  * The hash string, minus the hash symbol
21191
21278
  * @type {string}
21192
21279
  */
21193
- let $$hash;
21280
+ let _hash;
21194
21281
 
21195
21282
  class Location {
21196
21283
  /**
@@ -21227,14 +21314,14 @@ class Location {
21227
21314
  * Current url
21228
21315
  * @type {string}
21229
21316
  */
21230
- this.$$url = undefined;
21317
+ this._url = undefined;
21231
21318
 
21232
21319
  /**
21233
21320
  * @ignore
21234
21321
  * Callback to update browser url
21235
- * @type {Function}
21322
+ * @type {Function | undefined}
21236
21323
  */
21237
- this.$$updateBrowser = undefined;
21324
+ this._updateBrowser = undefined;
21238
21325
  }
21239
21326
 
21240
21327
  /**
@@ -21265,7 +21352,7 @@ class Location {
21265
21352
  * @return {string} url
21266
21353
  */
21267
21354
  getUrl() {
21268
- return this.$$url;
21355
+ return this._url;
21269
21356
  }
21270
21357
 
21271
21358
  /**
@@ -21277,8 +21364,8 @@ class Location {
21277
21364
  setPath(path) {
21278
21365
  const newPath = path !== null ? path.toString() : "";
21279
21366
 
21280
- $$path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
21281
- this.$$compose();
21367
+ _path = newPath.charAt(0) === "/" ? newPath : `/${newPath}`;
21368
+ this._compose();
21282
21369
 
21283
21370
  return this;
21284
21371
  }
@@ -21290,7 +21377,7 @@ class Location {
21290
21377
  * @return {string}
21291
21378
  */
21292
21379
  getPath() {
21293
- return $$path;
21380
+ return _path;
21294
21381
  }
21295
21382
 
21296
21383
  /**
@@ -21299,8 +21386,8 @@ class Location {
21299
21386
  * @return {Location} hash
21300
21387
  */
21301
21388
  setHash(hash) {
21302
- $$hash = hash !== null ? hash.toString() : "";
21303
- this.$$compose();
21389
+ _hash = hash !== null ? hash.toString() : "";
21390
+ this._compose();
21304
21391
 
21305
21392
  return this;
21306
21393
  }
@@ -21310,7 +21397,7 @@ class Location {
21310
21397
  * @return {string} hash
21311
21398
  */
21312
21399
  getHash() {
21313
- return $$hash;
21400
+ return _hash;
21314
21401
  }
21315
21402
 
21316
21403
  /**
@@ -21325,7 +21412,7 @@ class Location {
21325
21412
  case 1:
21326
21413
  if (isString(search) || isNumber(search)) {
21327
21414
  search = search.toString();
21328
- $$search = parseKeyValue(search);
21415
+ _search = parseKeyValue(search);
21329
21416
  } else if (isObject(search)) {
21330
21417
  search = structuredClone(search, {});
21331
21418
  // remove object undefined or null properties
@@ -21333,7 +21420,7 @@ class Location {
21333
21420
  if (isNull(value)) delete search[key];
21334
21421
  });
21335
21422
 
21336
- $$search = search;
21423
+ _search = search;
21337
21424
  } else {
21338
21425
  throw $locationMinErr(
21339
21426
  "isrcharg",
@@ -21343,14 +21430,14 @@ class Location {
21343
21430
  break;
21344
21431
  default:
21345
21432
  if (isUndefined(paramValue) || paramValue === null) {
21346
- delete $$search[search];
21433
+ delete _search[search];
21347
21434
  } else {
21348
21435
  // @ts-ignore
21349
- $$search[search] = paramValue;
21436
+ _search[search] = paramValue;
21350
21437
  }
21351
21438
  }
21352
21439
 
21353
- this.$$compose();
21440
+ this._compose();
21354
21441
 
21355
21442
  return this;
21356
21443
  }
@@ -21361,20 +21448,20 @@ class Location {
21361
21448
  * @returns {Object} Search object or Location object
21362
21449
  */
21363
21450
  getSearch() {
21364
- return $$search;
21451
+ return _search;
21365
21452
  }
21366
21453
 
21367
21454
  /**
21368
21455
  * @private
21369
21456
  * Compose url and update `url` and `absUrl` property
21370
21457
  */
21371
- $$compose() {
21372
- this.$$url = normalizePath($$path, $$search, $$hash);
21458
+ _compose() {
21459
+ this._url = normalizePath(_path, _search, _hash);
21373
21460
  this.absUrl = this.html5
21374
- ? this.appBaseNoFile + this.$$url.substring(1)
21375
- : this.appBase + (this.$$url ? this.hashPrefix + this.$$url : "");
21461
+ ? this.appBaseNoFile + this._url.substring(1)
21462
+ : this.appBase + (this._url ? this.hashPrefix + this._url : "");
21376
21463
  urlUpdatedByLocation = true;
21377
- setTimeout(() => this.$$updateBrowser && this.$$updateBrowser());
21464
+ setTimeout(() => this._updateBrowser && this._updateBrowser());
21378
21465
  }
21379
21466
 
21380
21467
  /**
@@ -21485,11 +21572,11 @@ class Location {
21485
21572
 
21486
21573
  parseAppUrl(pathUrl, true);
21487
21574
 
21488
- if (!$$path) {
21489
- $$path = "/";
21575
+ if (!_path) {
21576
+ _path = "/";
21490
21577
  }
21491
21578
 
21492
- this.$$compose();
21579
+ this._compose();
21493
21580
  } else {
21494
21581
  const withoutBaseUrl =
21495
21582
  stripBaseUrl(this.appBase, url) ||
@@ -21523,9 +21610,9 @@ class Location {
21523
21610
 
21524
21611
  parseAppUrl(withoutHashUrl, false);
21525
21612
 
21526
- $$path = removeWindowsDriveName($$path, withoutHashUrl, this.appBase);
21613
+ _path = removeWindowsDriveName(_path, withoutHashUrl, this.appBase);
21527
21614
 
21528
- this.$$compose();
21615
+ this._compose();
21529
21616
 
21530
21617
  /*
21531
21618
  * In Windows, on an anchor node on documents loaded from
@@ -21575,16 +21662,17 @@ class LocationProvider {
21575
21662
  rewriteLinks: true,
21576
21663
  };
21577
21664
 
21578
- /** @type {Array<import("./interface.ts").UrlChangeListener>} */
21579
- this.urlChangeListeners = [];
21580
- this.urlChangeInit = false;
21581
-
21582
- /** @type {History['state']} */
21583
- this.cachedState = null;
21584
- /** @type {History['state']} */
21585
- this.lastHistoryState = null;
21586
- /** @type {string} */
21587
- this.lastBrowserUrl = window.location.href;
21665
+ /** @private @type {Array<import("./interface.ts").UrlChangeListener>} */
21666
+ this._urlChangeListeners = [];
21667
+ /** @private */
21668
+ this._urlChangeInit = false;
21669
+
21670
+ /** @private @type {History['state']} */
21671
+ this._cachedState = null;
21672
+ /** @private @type {History['state']} */
21673
+ this._lastHistoryState = null;
21674
+ /** @private @type {string} */
21675
+ this._lastBrowserUrl = window.location.href;
21588
21676
  this.cacheState();
21589
21677
  }
21590
21678
 
@@ -21607,12 +21695,12 @@ class LocationProvider {
21607
21695
  if (url) {
21608
21696
  url = new URL(url).href;
21609
21697
 
21610
- if (this.lastBrowserUrl === url && this.lastHistoryState === state) {
21698
+ if (this._lastBrowserUrl === url && this._lastHistoryState === state) {
21611
21699
  return this;
21612
21700
  }
21613
21701
 
21614
- this.lastBrowserUrl = url;
21615
- this.lastHistoryState = state;
21702
+ this._lastBrowserUrl = url;
21703
+ this._lastHistoryState = state;
21616
21704
  history.pushState(state, "", url);
21617
21705
  this.cacheState();
21618
21706
  }
@@ -21633,7 +21721,7 @@ class LocationProvider {
21633
21721
  * @returns {History['state']} The cached state.
21634
21722
  */
21635
21723
  state() {
21636
- return this.cachedState;
21724
+ return this._cachedState;
21637
21725
  }
21638
21726
 
21639
21727
  /**
@@ -21645,9 +21733,9 @@ class LocationProvider {
21645
21733
  const currentState = history.state ?? null;
21646
21734
 
21647
21735
  if (!equals$1(currentState, this.lastCachedState)) {
21648
- this.cachedState = currentState;
21736
+ this._cachedState = currentState;
21649
21737
  this.lastCachedState = currentState;
21650
- this.lastHistoryState = currentState;
21738
+ this._lastHistoryState = currentState;
21651
21739
  }
21652
21740
  }
21653
21741
 
@@ -21655,20 +21743,20 @@ class LocationProvider {
21655
21743
  * Fires the state or URL change event.
21656
21744
  */
21657
21745
  #fireStateOrUrlChange() {
21658
- const prevLastHistoryState = this.lastHistoryState;
21746
+ const prevLastHistoryState = this._lastHistoryState;
21659
21747
 
21660
21748
  this.cacheState();
21661
21749
 
21662
21750
  if (
21663
- this.lastBrowserUrl === this.getBrowserUrl() &&
21664
- prevLastHistoryState === this.cachedState
21751
+ this._lastBrowserUrl === this.getBrowserUrl() &&
21752
+ prevLastHistoryState === this._cachedState
21665
21753
  ) {
21666
21754
  return;
21667
21755
  }
21668
- this.lastBrowserUrl = this.getBrowserUrl();
21669
- this.lastHistoryState = this.cachedState;
21670
- this.urlChangeListeners.forEach((listener) => {
21671
- listener(trimEmptyHash(window.location.href), this.cachedState);
21756
+ this._lastBrowserUrl = this.getBrowserUrl();
21757
+ this._lastHistoryState = this._cachedState;
21758
+ this._urlChangeListeners.forEach((listener) => {
21759
+ listener(trimEmptyHash(window.location.href), this._cachedState);
21672
21760
  });
21673
21761
  }
21674
21762
 
@@ -21679,7 +21767,7 @@ class LocationProvider {
21679
21767
  * @returns void
21680
21768
  */
21681
21769
  #onUrlChange(callback) {
21682
- if (!this.urlChangeInit) {
21770
+ if (!this._urlChangeInit) {
21683
21771
  window.addEventListener(
21684
21772
  "popstate",
21685
21773
  this.#fireStateOrUrlChange.bind(this),
@@ -21688,9 +21776,9 @@ class LocationProvider {
21688
21776
  "hashchange",
21689
21777
  this.#fireStateOrUrlChange.bind(this),
21690
21778
  );
21691
- this.urlChangeInit = true;
21779
+ this._urlChangeInit = true;
21692
21780
  }
21693
- this.urlChangeListeners.push(callback);
21781
+ this._urlChangeListeners.push(callback);
21694
21782
  }
21695
21783
 
21696
21784
  $get = [
@@ -21926,12 +22014,16 @@ class LocationProvider {
21926
22014
  }
21927
22015
  };
21928
22016
 
21929
- $location.$$updateBrowser = updateBrowser;
22017
+ $location._updateBrowser = updateBrowser;
21930
22018
  updateBrowser();
21931
22019
  $rootScope.$on("$updateBrowser", updateBrowser);
21932
22020
 
21933
22021
  return $location;
21934
22022
 
22023
+ /**
22024
+ * @param {string} oldUrl
22025
+ * @param {any} oldState
22026
+ */
21935
22027
  function afterLocationChange(oldUrl, oldState) {
21936
22028
  $rootScope.$broadcast(
21937
22029
  "$locationChangeSuccess",
@@ -22085,13 +22177,13 @@ function parseAppUrl(url, html5Mode) {
22085
22177
  ? match.pathname.substring(1)
22086
22178
  : match.pathname;
22087
22179
 
22088
- $$path = decodePath(path, html5Mode);
22089
- $$search = parseKeyValue(match.search);
22090
- $$hash = decodeURIComponent(match.hash);
22180
+ _path = decodePath(path, html5Mode);
22181
+ _search = parseKeyValue(match.search);
22182
+ _hash = decodeURIComponent(match.hash);
22091
22183
 
22092
22184
  // make sure path starts with '/';
22093
- if ($$path && $$path.charAt(0) !== "/") {
22094
- $$path = `/${$$path}`;
22185
+ if (_path && _path.charAt(0) !== "/") {
22186
+ _path = `/${_path}`;
22095
22187
  }
22096
22188
  }
22097
22189
 
@@ -22251,7 +22343,8 @@ class LogProvider {
22251
22343
  * @param {string} type
22252
22344
  */
22253
22345
  _consoleLog(type) {
22254
- const console = window.console || {};
22346
+ const console =
22347
+ window.console || /** @type {Partial<Record<string, Function>>} */ ({});
22255
22348
 
22256
22349
  const logFn =
22257
22350
  console[type] ||
@@ -22260,7 +22353,7 @@ class LogProvider {
22260
22353
  /* empty */
22261
22354
  });
22262
22355
 
22263
- return (...args) => {
22356
+ return (/** @type {any[]} */ ...args) => {
22264
22357
  const formattedArgs = args.map((arg) => this._formatError(arg));
22265
22358
 
22266
22359
  return logFn.apply(console, formattedArgs);
@@ -22775,7 +22868,7 @@ class Scope {
22775
22868
  let scheduled = foreignListeners;
22776
22869
 
22777
22870
  // filter for repeaters
22778
- const hashKey = this.$target.$$hashKey;
22871
+ const hashKey = this.$target._hashKey;
22779
22872
 
22780
22873
  if (hashKey) {
22781
22874
  scheduled = [];
@@ -22783,7 +22876,7 @@ class Scope {
22783
22876
  for (let i = 0, l = foreignListeners.length; i < l; i++) {
22784
22877
  const listener = foreignListeners[i];
22785
22878
 
22786
- if (listener.originalTarget.$$hashKey === hashKey) {
22879
+ if (listener.originalTarget._hashKey === hashKey) {
22787
22880
  scheduled.push(listener);
22788
22881
  }
22789
22882
  }
@@ -24247,7 +24340,7 @@ function ngMessagesIncludeDirective($templateRequest, $compile) {
24247
24340
  if (isString(html) && !html.trim()) ; else {
24248
24341
  // Non-empty template - compile and link
24249
24342
  $compile(html)($scope, (contents) => {
24250
- isIntanceOf(contents, Node) && element.after(contents);
24343
+ isInstanceOf(contents, Node) && element.after(contents);
24251
24344
  });
24252
24345
  }
24253
24346
  });
@@ -24398,11 +24491,7 @@ const nativeAriaNodeNames = [
24398
24491
  ];
24399
24492
 
24400
24493
  const isNodeOneOf = function (elem, nodeTypeArray) {
24401
- if (nodeTypeArray.indexOf(elem.nodeName) !== -1) {
24402
- return true;
24403
- }
24404
-
24405
- return false;
24494
+ return nodeTypeArray.indexOf(elem.nodeName) !== -1;
24406
24495
  };
24407
24496
 
24408
24497
  /**
@@ -27640,7 +27729,7 @@ class RafSchedulerProvider {
27640
27729
  _nextTick() {
27641
27730
  if (!this._queue.length) return;
27642
27731
 
27643
- const items = this._queue.shift();
27732
+ const items = /** @type{Array<() => void>} */ (this._queue.shift());
27644
27733
 
27645
27734
  items.forEach((fn) => fn());
27646
27735
 
@@ -28577,7 +28666,7 @@ function applyPairs(memo, keyValTuple) {
28577
28666
  /**
28578
28667
  * Returns the last element of an array, or undefined if the array is empty.
28579
28668
  * @template T
28580
- * @param {T[]} arr - The input array.
28669
+ * @param {any[]|string} arr - The input array.
28581
28670
  * @returns {T | undefined} The last element or undefined.
28582
28671
  */
28583
28672
  function tail(arr) {
@@ -28648,16 +28737,16 @@ const silentRejection = (error) =>
28648
28737
  *
28649
28738
  * ```
28650
28739
  *
28651
- * @param fn
28740
+ * @param {Function} fn
28652
28741
  * @returns {*|function(): (*|any)}
28653
28742
  */
28654
28743
  function curry(fn) {
28655
- const curried = (...args) => {
28744
+ const curried = (/** @type {any[]} */ ...args) => {
28656
28745
  if (args.length >= fn.length) {
28657
28746
  return fn(...args);
28658
28747
  }
28659
28748
 
28660
- return (...nextArgs) => curried(...args, ...nextArgs);
28749
+ return (/** @type {any} */ ...nextArgs) => curried(...args, ...nextArgs);
28661
28750
  };
28662
28751
 
28663
28752
  return curried;
@@ -28670,7 +28759,13 @@ function curry(fn) {
28670
28759
  * let getName = propEq("name", "blarg");
28671
28760
  * getName(obj) === true
28672
28761
  */
28673
- const propEq = curry((name, _val, obj) => obj && obj[name] === _val);
28762
+ const propEq = curry(
28763
+ (
28764
+ /** @type {string | number} */ name,
28765
+ /** @type {any} */ _val,
28766
+ /** @type {{ [x: string]: any; }} */ obj,
28767
+ ) => obj && obj[name] === _val,
28768
+ );
28674
28769
  /**
28675
28770
  * Given a dotted property name, returns a function that returns a nested property from an object, or undefined
28676
28771
  * let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, };
@@ -28679,10 +28774,11 @@ const propEq = curry((name, _val, obj) => obj && obj[name] === _val);
28679
28774
  * let propNotFound = prop("this.property.doesnt.exist");
28680
28775
  * propNotFound(obj) === undefined
28681
28776
  */
28682
- const parse = (path) => {
28777
+ const parse = (/** @type {string} */ path) => {
28683
28778
  const parts = path.split(".");
28684
28779
 
28685
- return (obj) => parts.reduce((acc, key) => acc && acc[key], obj);
28780
+ return (/** @type {any} */ obj) =>
28781
+ parts.reduce((acc, key) => acc && acc[key], obj);
28686
28782
  };
28687
28783
 
28688
28784
  /**
@@ -28707,7 +28803,12 @@ function is(ctor) {
28707
28803
  };
28708
28804
  }
28709
28805
 
28710
- /** Given a value, returns a function which returns the value */
28806
+ /**
28807
+ * Given a value, returns a function which returns that value.
28808
+ * @template T
28809
+ * @param {T} value - The value to wrap in a function.
28810
+ * @returns {() => T} A function that returns the given value.
28811
+ */
28711
28812
  const val = (value) => () => value;
28712
28813
 
28713
28814
  /**
@@ -28724,31 +28825,28 @@ const val = (value) => () => value;
28724
28825
  * of size 2: [ predicate, mapFn ]
28725
28826
  *
28726
28827
  * These 2-tuples should be put in an outer array.
28727
- *
28728
- * @example
28729
- * ```
28730
- *
28731
- * // Here's a 2-tuple where the first element is the isString predicate
28732
- * // and the second element is a function that returns a description of the input
28733
- * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
28734
- *
28735
- * // Second tuple: predicate "isNumber", mapfn returns a description
28736
- * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
28737
- *
28738
- * let third = [ (input) => input === null, (input) => `Oh, null...` ];
28739
- *
28740
- * let fourth = [ (input) => input === undefined, (input) => `notdefined` ];
28741
- *
28742
- * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
28743
- *
28744
- * console.log(descriptionOf(undefined)); // 'notdefined'
28745
- * console.log(descriptionOf(55)); // '(55) That's a number!'
28746
- * console.log(descriptionOf("foo")); // 'Here's your string foo'
28747
- * ```
28748
- *
28749
- * @param struct A 2D array. Each element of the array should be an array, a 2-tuple,
28750
- * with a Predicate and a mapping/output function
28751
- * @returns {function(any): *}
28828
+ * @example ```
28829
+
28830
+ // Here's a 2-tuple where the first element is the isString predicate
28831
+ // and the second element is a function that returns a description of the input
28832
+ let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
28833
+
28834
+ // Second tuple: predicate "isNumber", mapfn returns a description
28835
+ let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
28836
+
28837
+ let third = [ (input) => input === null, (input) => `Oh, null...` ];
28838
+
28839
+ let fourth = [ (input) => input === undefined, (input) => `notdefined` ];
28840
+
28841
+ let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
28842
+
28843
+ console.log(descriptionOf(undefined)); // 'notdefined'
28844
+ console.log(descriptionOf(55)); // '(55) That's a number!'
28845
+ console.log(descriptionOf("foo")); // 'Here's your string foo'
28846
+ ```
28847
+ * @param {string | any[]} struct A 2D array. Each element of the array should be an array, a 2-tuple,
28848
+ with a Predicate and a mapping/output function
28849
+ * @returns {function(any):*}
28752
28850
  */
28753
28851
  function pattern(struct) {
28754
28852
  return function (item) {
@@ -29408,17 +29506,23 @@ class RouterProvider {
29408
29506
  /**
29409
29507
  * @type {number}
29410
29508
  */
29411
- this.lastStartedTransitionId = -1;
29509
+ this._lastStartedTransitionId = -1;
29412
29510
 
29413
29511
  /**
29414
29512
  * @type {Queue<import("./transition/transition.js").Transition>}
29415
29513
  */
29416
- this.transitionHistory = new Queue([], 1);
29514
+ this._transitionHistory = new Queue(
29515
+ /** @type {Array<import("./transition/transition.js").Transition>} */ ([]),
29516
+ 1,
29517
+ );
29417
29518
 
29418
29519
  /**
29419
29520
  * @type {Queue<import("./transition/transition.js").Transition>}
29420
29521
  */
29421
- this.successfulTransitions = new Queue([], 1);
29522
+ this._successfulTransitions = new Queue(
29523
+ /** @type {Array<import("./transition/transition.js").Transition>} */ ([]),
29524
+ 1,
29525
+ );
29422
29526
 
29423
29527
  /**
29424
29528
  * @type {import("./state/interface.ts").StateDeclaration|undefined}
@@ -29517,10 +29621,17 @@ function fnToString(fn) {
29517
29621
  return (_fn && _fn.toString()) || "undefined";
29518
29622
  }
29519
29623
 
29624
+ /**
29625
+ * @param {any} value
29626
+ * @returns {string|*|string}
29627
+ */
29520
29628
  function stringify(value) {
29629
+ /**
29630
+ * @type {any[]}
29631
+ */
29521
29632
  const seen = [];
29522
29633
 
29523
- const isRejection = (obj) => {
29634
+ const isRejection = (/** @type {Promise<any>} */ obj) => {
29524
29635
  return (
29525
29636
  obj &&
29526
29637
  typeof obj.then === "function" &&
@@ -29528,7 +29639,9 @@ function stringify(value) {
29528
29639
  );
29529
29640
  };
29530
29641
 
29531
- const hasToString = (obj) =>
29642
+ const hasToString = (
29643
+ /** @type {{ constructor: ObjectConstructor; toString: any; }} */ obj,
29644
+ ) =>
29532
29645
  isObject(obj) &&
29533
29646
  !isArray(obj) &&
29534
29647
  obj.constructor !== Object &&
@@ -29538,12 +29651,23 @@ function stringify(value) {
29538
29651
  [isUndefined, val("undefined")],
29539
29652
  [isNull, val("null")],
29540
29653
  [isPromise, val("[Promise]")],
29541
- [isRejection, (reg) => reg._transitionRejection.toString()],
29542
- [hasToString, (str) => str.toString()],
29654
+ [
29655
+ isRejection,
29656
+ (
29657
+ /** @type {{ _transitionRejection: { toString: () => any; }; }} */ reg,
29658
+ ) => reg._transitionRejection.toString(),
29659
+ ],
29660
+ [
29661
+ hasToString,
29662
+ (/** @type {{ toString: () => any; }} */ str) => str.toString(),
29663
+ ],
29543
29664
  [isInjectable, functionToString],
29544
- [val(true), (bool) => bool],
29665
+ [val(true), (/** @type {any} */ bool) => bool],
29545
29666
  ]);
29546
29667
 
29668
+ /**
29669
+ * @param {any} item
29670
+ */
29547
29671
  function format(item) {
29548
29672
  if (isObject(item)) {
29549
29673
  if (seen.indexOf(item) !== -1) return "[circular ref]";
@@ -29566,7 +29690,9 @@ function stringify(value) {
29566
29690
  );
29567
29691
  }
29568
29692
 
29569
- const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
29693
+ const stripLastPathElement = (/** @type {string} */ str) =>
29694
+ str.replace(/\/[^/]*$/, "");
29695
+
29570
29696
  /**
29571
29697
  * Splits on a delimiter, but returns the delimiters in the array
29572
29698
  *
@@ -29576,12 +29702,14 @@ const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
29576
29702
  * splitOnSlashes("/foo"); // ["/", "foo"]
29577
29703
  * splitOnSlashes("/foo/"); // ["/", "foo", "/"]
29578
29704
  * ```
29705
+ * @param {string} delim
29579
29706
  */
29580
29707
  function splitOnDelim(delim) {
29581
29708
  const re = new RegExp(`(${delim})`, "g");
29582
29709
 
29583
- return (str) => str.split(re).filter(Boolean);
29710
+ return (/** @type {string} */ str) => str.split(re).filter(Boolean);
29584
29711
  }
29712
+
29585
29713
  /**
29586
29714
  * Reduce fn that joins neighboring strings
29587
29715
  *
@@ -29593,10 +29721,12 @@ function splitOnDelim(delim) {
29593
29721
  * let arr = ["foo", "bar", 1, "baz", "", "qux" ];
29594
29722
  * arr.reduce(joinNeighborsR, []) // ["foobar", 1, "bazqux" ]
29595
29723
  * ```
29724
+ * @param {string | any[]} acc
29725
+ * @param {unknown} str
29596
29726
  */
29597
29727
  function joinNeighborsR(acc, str) {
29598
- if (isString(tail(acc)) && isString(str))
29599
- return acc.slice(0, -1).concat(tail(acc) + str);
29728
+ if (isString(tail(/** @type {string} */ (acc))) && isString(str))
29729
+ return acc.slice(0, -1).concat(tail(/** @type {string} */ (acc)) + str);
29600
29730
 
29601
29731
  return pushR(acc, str);
29602
29732
  }
@@ -32166,18 +32296,24 @@ class RegisteredHook {
32166
32296
  this._deregistered = true;
32167
32297
  }
32168
32298
  }
32169
- /** Return a registration function of the requested type. */
32170
- function makeEvent(registry, transitionService, eventType) {
32299
+ /**
32300
+ * Return a registration function of the requested type.
32301
+ * @param {ng.TransitionProvider| import("./transition.js").Transition} hookSource
32302
+ * @param {ng.TransitionProvider} transitionService
32303
+ * @param {import("./transition-event-type.js").TransitionEventType} eventType
32304
+ * @returns {( matchObject: any, callback: Function, options?: Record<string, any> ) => () => void }
32305
+ */
32306
+ function makeEvent(hookSource, transitionService, eventType) {
32171
32307
  // Create the object which holds the registered transition hooks.
32172
- const _registeredHooks = (registry._registeredHooks =
32173
- registry._registeredHooks || {});
32308
+ const _registeredHooks = (hookSource._registeredHooks =
32309
+ hookSource._registeredHooks || {});
32174
32310
 
32175
32311
  const hooks = (_registeredHooks[eventType.name] = []);
32176
32312
 
32177
32313
  const removeHookFn = (x) => removeFrom(hooks, x);
32178
32314
 
32179
32315
  // Create hook registration function on the HookRegistry for the event
32180
- registry[eventType.name] = hookRegistrationFn;
32316
+ hookSource[eventType.name] = hookRegistrationFn;
32181
32317
  function hookRegistrationFn(matchObject, callback, options = {}) {
32182
32318
  const registeredHook = new RegisteredHook(
32183
32319
  transitionService,
@@ -32222,7 +32358,7 @@ class HookBuilder {
32222
32358
  * @returns
32223
32359
  */
32224
32360
  buildHooksForPhase(phase) {
32225
- return this.transition._transitionService
32361
+ return this.transition._transitionProvider
32226
32362
  ._getEvents(phase)
32227
32363
  .map((type) => this.buildHooks(type))
32228
32364
  .reduce(unnestR, [])
@@ -32283,7 +32419,7 @@ class HookBuilder {
32283
32419
  state,
32284
32420
  hook,
32285
32421
  _options,
32286
- this.transition._transitionService._$exceptionHandler,
32422
+ this.transition._transitionProvider._$exceptionHandler,
32287
32423
  );
32288
32424
 
32289
32425
  return { hook, node, transitionHook };
@@ -32312,7 +32448,7 @@ class HookBuilder {
32312
32448
  const isCreate = hookType.hookPhase === TransitionHookPhase._CREATE;
32313
32449
 
32314
32450
  // Instance and Global hook registries
32315
- const $transitions = this.transition._transitionService;
32451
+ const $transitions = this.transition._transitionProvider;
32316
32452
 
32317
32453
  const registries = isCreate
32318
32454
  ? [$transitions]
@@ -32377,7 +32513,11 @@ class Transition {
32377
32513
  * @type {import('../router.js').RouterProvider}
32378
32514
  */
32379
32515
  this._globals = globals;
32380
- this._transitionService = transitionService;
32516
+
32517
+ /** @type {ng.TransitionProvider} */
32518
+ this._transitionProvider = transitionService;
32519
+
32520
+ /** @type {PromiseWithResolvers<any>} */
32381
32521
  this._deferred = Promise.withResolvers();
32382
32522
 
32383
32523
  /**
@@ -32433,10 +32573,12 @@ class Transition {
32433
32573
  * (which can then be used to register hooks)
32434
32574
  */
32435
32575
  createTransitionHookRegFns() {
32436
- this._transitionService
32576
+ this._transitionProvider
32437
32577
  ._getEvents()
32438
32578
  .filter((type) => type.hookPhase !== TransitionHookPhase._CREATE)
32439
- .forEach((type) => makeEvent(this, this._transitionService, type));
32579
+ .forEach((type) => {
32580
+ return makeEvent(this, this._transitionProvider, type);
32581
+ });
32440
32582
  }
32441
32583
 
32442
32584
  getHooks(hookName) {
@@ -32447,7 +32589,7 @@ class Transition {
32447
32589
  const enteringStates = this._treeChanges.entering.map((node) => node.state);
32448
32590
 
32449
32591
  PathUtils.applyViewConfigs(
32450
- this._transitionService.$view,
32592
+ this._transitionProvider.$view,
32451
32593
  this._treeChanges.to,
32452
32594
  enteringStates,
32453
32595
  );
@@ -32767,7 +32909,7 @@ class Transition {
32767
32909
  );
32768
32910
 
32769
32911
  targetState = targetState.withOptions(newOptions, true);
32770
- const newTransition = this._transitionService.create(
32912
+ const newTransition = this._transitionProvider.create(
32771
32913
  this._treeChanges.from,
32772
32914
  targetState,
32773
32915
  );
@@ -32953,9 +33095,9 @@ class Transition {
32953
33095
  const startTransition = () => {
32954
33096
  const { _globals } = this;
32955
33097
 
32956
- _globals.lastStartedTransitionId = this.$id;
33098
+ _globals._lastStartedTransitionId = this.$id;
32957
33099
  _globals.transition = this;
32958
- _globals.transitionHistory.enqueue(this);
33100
+ _globals._transitionHistory.enqueue(this);
32959
33101
  trace.traceTransitionStart(this);
32960
33102
 
32961
33103
  return Promise.resolve();
@@ -33296,7 +33438,7 @@ const updateGlobalState = (trans) => {
33296
33438
  const globals = trans._globals;
33297
33439
 
33298
33440
  const transitionSuccessful = () => {
33299
- globals.successfulTransitions.enqueue(trans);
33441
+ globals._successfulTransitions.enqueue(trans);
33300
33442
  globals.$current = trans.$to();
33301
33443
  globals.current = globals.$current.self;
33302
33444
  copy(trans.params(), globals.params);
@@ -33345,12 +33487,19 @@ function registerLazyLoadHook(
33345
33487
  stateRegistry,
33346
33488
  ) {
33347
33489
  return transitionService.onBefore(
33348
- { entering: (state) => !!state.lazyLoad },
33349
- (transition) => {
33490
+ {
33491
+ entering: (state) => {
33492
+ return !!state.lazyLoad;
33493
+ },
33494
+ },
33495
+ /** @param {import("../transition/transition.js").Transition} transition*/ (
33496
+ transition,
33497
+ ) => {
33350
33498
  function retryTransition() {
33351
33499
  if (transition.originalTransition().options().source !== "url") {
33352
33500
  // The original transition was not triggered via url sync
33353
33501
  // The lazy state should be loaded now, so re-try the original transition
33502
+
33354
33503
  const orig = transition.targetState();
33355
33504
 
33356
33505
  return stateService.target(
@@ -33649,7 +33798,7 @@ class TransitionProvider {
33649
33798
 
33650
33799
  /** @type {ng.ExceptionHandlerService} */
33651
33800
  this._$exceptionHandler = $exceptionHandler.handler;
33652
- globals.successfulTransitions.onEvict(treeChangesCleanup);
33801
+ globals._successfulTransitions.onEvict(treeChangesCleanup);
33653
33802
  }
33654
33803
 
33655
33804
  $get = [
@@ -33934,8 +34083,15 @@ class StateProvider {
33934
34083
  * @param {ng.ExceptionHandlerProvider} exceptionHandlerProvider
33935
34084
  */
33936
34085
  constructor(globals, transitionService, exceptionHandlerProvider) {
34086
+ /**
34087
+ * @type {ng.RouterProvider}
34088
+ */
33937
34089
  this.globals = globals;
34090
+ /**
34091
+ * @type {ng.TransitionProvider}
34092
+ */
33938
34093
  this.transitionService = transitionService;
34094
+
33939
34095
  this.stateRegistry = undefined;
33940
34096
 
33941
34097
  /** @type {ng.UrlService} */
@@ -34090,7 +34246,7 @@ class StateProvider {
34090
34246
 
34091
34247
  const { globals } = this;
34092
34248
 
34093
- const latestThing = () => globals.transitionHistory.peekTail();
34249
+ const latestThing = () => globals._transitionHistory.peekTail();
34094
34250
 
34095
34251
  const latest = latestThing();
34096
34252
 
@@ -34305,7 +34461,7 @@ class StateProvider {
34305
34461
  getCurrentPath() {
34306
34462
  const { globals } = this;
34307
34463
 
34308
- const latestSuccess = globals.successfulTransitions.peekTail();
34464
+ const latestSuccess = globals._successfulTransitions.peekTail();
34309
34465
 
34310
34466
  const rootPath = () => [new PathNode(this.stateRegistry.root())];
34311
34467
 
@@ -34364,7 +34520,7 @@ class StateProvider {
34364
34520
  */
34365
34521
  const rejectedTransitionHandler = (trans) => (error) => {
34366
34522
  if (error instanceof Rejection) {
34367
- const isLatest = this.globals.lastStartedTransitionId <= trans.$id;
34523
+ const isLatest = this.globals._lastStartedTransitionId <= trans.$id;
34368
34524
 
34369
34525
  if (error.type === RejectType._IGNORED) {
34370
34526
  isLatest && this.urlService.update();
@@ -34660,10 +34816,10 @@ class ViewScrollProvider {
34660
34816
  return $anchorScroll;
34661
34817
  }
34662
34818
 
34663
- return async function ($element) {
34819
+ return (/** @type {Element} */ $element) => {
34664
34820
  validateInstanceOf($element, Element, "$element");
34665
34821
 
34666
- return setTimeout(() => {
34822
+ setTimeout(() => {
34667
34823
  $element.scrollIntoView(false);
34668
34824
  }, 0);
34669
34825
  };
@@ -34828,7 +34984,9 @@ class TemplateFactoryProvider {
34828
34984
  fromProvider(provider, params, context) {
34829
34985
  const deps = annotate(provider);
34830
34986
 
34831
- const providerFn = isArray(provider) ? tail(provider) : provider;
34987
+ const providerFn = isArray(provider)
34988
+ ? /** @type {Function} */ (tail(provider))
34989
+ : provider;
34832
34990
 
34833
34991
  const resolvable = new Resolvable("", providerFn, deps);
34834
34992
 
@@ -35594,8 +35752,6 @@ function encodeDashes(str) {
35594
35752
  );
35595
35753
  }
35596
35754
 
35597
- /** @typedef {import('./interface.ts').StateDeclaration} StateDeclaration */
35598
-
35599
35755
  /**
35600
35756
  * Internal representation of a ng-router state.
35601
35757
  *
@@ -35605,16 +35761,16 @@ function encodeDashes(str) {
35605
35761
  *
35606
35762
  * This class prototypally inherits from the corresponding [[StateDeclaration]].
35607
35763
  * Each of its own properties (i.e., `hasOwnProperty`) are built using builders from the [[StateBuilder]].
35608
- * @implements {StateDeclaration}
35764
+ * @implements {ng.StateDeclaration}
35609
35765
  */
35610
35766
  class StateObject {
35611
- name = undefined;
35612
- navigable = undefined;
35767
+ name;
35768
+ navigable;
35613
35769
  /** @type {?StateObject} */
35614
- parent = undefined;
35615
- params = undefined;
35616
- url = undefined;
35617
- includes = undefined;
35770
+ parent;
35771
+ params;
35772
+ url;
35773
+ includes;
35618
35774
 
35619
35775
  /**
35620
35776
  * @param {import('./interface.ts').StateDeclaration} config
@@ -35633,7 +35789,7 @@ class StateObject {
35633
35789
  */
35634
35790
  const nameGlob = this.name ? Glob.fromString(this.name) : null;
35635
35791
 
35636
- this.__stateObjectCache = { nameGlob };
35792
+ this._stateObjectCache = { nameGlob };
35637
35793
  }
35638
35794
 
35639
35795
  /**
@@ -35715,7 +35871,7 @@ class StateObject {
35715
35871
  /** Predicate which returns true if the object is a [[StateDeclaration]] object */
35716
35872
  StateObject.isStateDeclaration = (obj) => isFunction(obj.$$state);
35717
35873
  /** Predicate which returns true if the object is an internal [[StateObject]] object */
35718
- StateObject.isState = (obj) => isObject(obj.__stateObjectCache);
35874
+ StateObject.isState = (obj) => isObject(obj._stateObjectCache);
35719
35875
 
35720
35876
  /**
35721
35877
  * Creates a [[UrlRule]]
@@ -36019,20 +36175,6 @@ function defaultRuleSortFn(a, b) {
36019
36175
  return idSort(a, b);
36020
36176
  }
36021
36177
 
36022
- function getHandlerFn(handler) {
36023
- if (
36024
- !isFunction(handler) &&
36025
- !isString(handler) &&
36026
- !is(TargetState)(handler) &&
36027
- !TargetState.isDef(handler)
36028
- ) {
36029
- throw new Error(
36030
- "'handler' must be a string, function, TargetState, or have a state: 'newtarget' property",
36031
- );
36032
- }
36033
-
36034
- return isFunction(handler) ? handler : val(handler);
36035
- }
36036
36178
  /**
36037
36179
  * API for managing URL rules
36038
36180
  *
@@ -36049,102 +36191,7 @@ class UrlRules {
36049
36191
  this._sortFn = defaultRuleSortFn;
36050
36192
  this._rules = [];
36051
36193
  this._id = 0;
36052
- this.urlRuleFactory = urlRuleFactory;
36053
- }
36054
-
36055
- /**
36056
- * Defines the initial state, path, or behavior to use when the app starts.
36057
- *
36058
- * This rule defines the initial/starting state for the application.
36059
- *
36060
- * This rule is triggered the first time the URL is checked (when the app initially loads).
36061
- * The rule is triggered only when the url matches either `""` or `"/"`.
36062
- *
36063
- * Note: The rule is intended to be used when the root of the application is directly linked to.
36064
- * When the URL is *not* `""` or `"/"` and doesn't match other rules, the [[otherwise]] rule is triggered.
36065
- * This allows 404-like behavior when an unknown URL is deep-linked.
36066
- *
36067
- * #### Example:
36068
- * Start app at `home` state.
36069
- * ```js
36070
- * .initial({ state: 'home' });
36071
- * ```
36072
- *
36073
- * #### Example:
36074
- * Start app at `/home` (by url)
36075
- * ```js
36076
- * .initial('/home');
36077
- * ```
36078
- *
36079
- * #### Example:
36080
- * When no other url rule matches, go to `home` state
36081
- * ```js
36082
- * .initial((matchValue, url, router) => {
36083
- * console.log('initial state');
36084
- * return { state: 'home' };
36085
- * })
36086
- * ```
36087
- *
36088
- * @param handler The initial state or url path, or a function which returns the state or url path (or performs custom logic).
36089
- */
36090
- initial(handler) {
36091
- const handlerFn = getHandlerFn(handler);
36092
-
36093
- const matchFn = (urlParts, router) =>
36094
- router.globals.transitionHistory.size() === 0 &&
36095
- !!/^\/?$/.exec(urlParts.path);
36096
-
36097
- this.rule(this.urlRuleFactory.create(matchFn, handlerFn));
36098
- }
36099
-
36100
- /**
36101
- * Defines the state, url, or behavior to use when no other rule matches the URL.
36102
- *
36103
- * This rule is matched when *no other rule* matches.
36104
- * It is generally used to handle unknown URLs (similar to "404" behavior, but on the client side).
36105
- *
36106
- * - If `handler` a string, it is treated as a url redirect
36107
- *
36108
- * #### Example:
36109
- * When no other url rule matches, redirect to `/index`
36110
- * ```js
36111
- * .otherwise('/index');
36112
- * ```
36113
- *
36114
- * - If `handler` is an object with a `state` property, the state is activated.
36115
- *
36116
- * #### Example:
36117
- * When no other url rule matches, redirect to `home` and provide a `dashboard` parameter value.
36118
- * ```js
36119
- * .otherwise({ state: 'home', params: { dashboard: 'default' } });
36120
- * ```
36121
- *
36122
- * - If `handler` is a function, the function receives the current url ([[UrlParts]]) and the [[UIRouter]] object.
36123
- * The function can perform actions, and/or return a value.
36124
- *
36125
- * #### Example:
36126
- * When no other url rule matches, manually trigger a transition to the `home` state
36127
- * ```js
36128
- * .otherwise((matchValue, urlParts, router) => {
36129
- * router.stateService.go('home');
36130
- * });
36131
- * ```
36132
- *
36133
- * #### Example:
36134
- * When no other url rule matches, go to `home` state
36135
- * ```js
36136
- * .otherwise((matchValue, urlParts, router) => {
36137
- * return { state: 'home' };
36138
- * });
36139
- * ```
36140
- *
36141
- * @param handler The url path to redirect to, or a function which returns the url path (or performs custom logic).
36142
- */
36143
- otherwise(handler) {
36144
- const handlerFn = getHandlerFn(handler);
36145
-
36146
- this._otherwiseFn = this.urlRuleFactory.create(val(true), handlerFn);
36147
- this._sorted = false;
36194
+ this._urlRuleFactory = urlRuleFactory;
36148
36195
  }
36149
36196
 
36150
36197
  /**
@@ -36166,7 +36213,7 @@ class UrlRules {
36166
36213
  * A rule should have a `match` function which returns truthy if the rule matched.
36167
36214
  * It should also have a `handler` function which is invoked if the rule is the best match.
36168
36215
  *
36169
- * @return a function that deregisters the rule
36216
+ * @returns {() => void } a function that deregisters the rule
36170
36217
  */
36171
36218
  rule(rule) {
36172
36219
  if (!UrlRuleFactory.isUrlRule(rule)) throw new Error("invalid rule");
@@ -36186,7 +36233,7 @@ class UrlRules {
36186
36233
  rules() {
36187
36234
  this.ensureSorted();
36188
36235
 
36189
- return this._rules.concat(this._otherwiseFn ? [this._otherwiseFn] : []);
36236
+ return this._rules;
36190
36237
  }
36191
36238
 
36192
36239
  /**
@@ -36330,7 +36377,7 @@ class UrlRules {
36330
36377
  * @return the registered [[UrlRule]]
36331
36378
  */
36332
36379
  when(matcher, handler, options) {
36333
- const rule = this.urlRuleFactory.create(matcher, handler);
36380
+ const rule = this._urlRuleFactory.create(matcher, handler);
36334
36381
 
36335
36382
  if (isDefined(options && options.priority))
36336
36383
  rule.priority = options.priority;
@@ -36380,31 +36427,32 @@ class UrlService {
36380
36427
 
36381
36428
  /**
36382
36429
  * @param {ng.LocationProvider} $locationProvider
36383
- * @param {import("../../router/state/state-service.js").StateProvider} stateService
36430
+ * @param {import("../../router/state/state-service.js").StateProvider} stateProvider
36384
36431
  * @param {import("../router.js").RouterProvider} globals
36385
36432
  * @param {import("../../router/url/url-config.js").UrlConfigProvider} urlConfigProvider
36386
36433
  */
36387
- constructor($locationProvider, stateService, globals, urlConfigProvider) {
36434
+ constructor($locationProvider, stateProvider, globals, urlConfigProvider) {
36388
36435
  /** @private */
36389
36436
  this._locationProvider = $locationProvider;
36390
- this.stateService = stateService;
36437
+ this.stateService = stateProvider;
36391
36438
 
36392
- /** Provides services related to the URL */
36393
- this.urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);
36439
+ /** @type {UrlRuleFactory} Provides services related to the URL */
36440
+ this._urlRuleFactory = new UrlRuleFactory(this, this.stateService, globals);
36394
36441
 
36395
36442
  /**
36396
36443
  * The nested [[UrlRules]] API for managing URL rules and rewrites
36444
+ * @ignore
36397
36445
  * @type {UrlRules}
36398
36446
  */
36399
- this.rules = new UrlRules(this.urlRuleFactory);
36447
+ this._rules = new UrlRules(this._urlRuleFactory);
36400
36448
  /**
36401
36449
  * The nested [[UrlConfig]] API to configure the URL and retrieve URL information
36402
36450
  * @type {import("./url-config.js").UrlConfigProvider}
36403
36451
  */
36404
- this.config = urlConfigProvider;
36452
+ this._config = urlConfigProvider;
36405
36453
 
36406
- /** Creates a new [[Param]] for a given location (DefType) */
36407
- this.paramFactory = new ParamFactory(this.config);
36454
+ /** @type {ParamFactory} Creates a new [[Param]] for a given location (DefType) */
36455
+ this._paramFactory = new ParamFactory(this._config);
36408
36456
 
36409
36457
  this._urlListeners = [];
36410
36458
  }
@@ -36666,7 +36714,7 @@ class UrlService {
36666
36714
  */
36667
36715
  match(url) {
36668
36716
  url = Object.assign({ path: "", search: {}, hash: "" }, url);
36669
- const rules = this.rules.rules();
36717
+ const rules = this._rules.rules();
36670
36718
 
36671
36719
  // Checks a single rule. Returns { rule: rule, match: match, weight: weight } if it matched, or undefined
36672
36720
  /**
@@ -36777,7 +36825,7 @@ class UrlService {
36777
36825
  * @returns The UrlMatcher.
36778
36826
  */
36779
36827
  compile(urlPattern, config) {
36780
- const urlConfig = this.config;
36828
+ const urlConfig = this._config;
36781
36829
 
36782
36830
  // backward-compatible support for config.params -> config.state.params
36783
36831
  const params = config && !config.state && config.params;
@@ -36791,7 +36839,7 @@ class UrlService {
36791
36839
  return new UrlMatcher(
36792
36840
  urlPattern,
36793
36841
  urlConfig.paramTypes,
36794
- this.paramFactory,
36842
+ this._paramFactory,
36795
36843
  Object.assign(globalConfig, config),
36796
36844
  );
36797
36845
  }
@@ -36828,8 +36876,10 @@ function appendBasePath(url, isHtml5, absolute, baseHref) {
36828
36876
  }
36829
36877
 
36830
36878
  class StateMatcher {
36831
- constructor(_states) {
36832
- this._states = _states;
36879
+ /** @param {import("./interface.ts").StateStore} states */
36880
+ constructor(states) {
36881
+ /** @type {import("./interface.ts").StateStore} */
36882
+ this._states = states;
36833
36883
  }
36834
36884
 
36835
36885
  isRelative(stateName) {
@@ -36854,12 +36904,10 @@ class StateMatcher {
36854
36904
  ) {
36855
36905
  return state;
36856
36906
  } else if (isStr && matchGlob) {
36857
- const _states = Object.values(this._states);
36907
+ const states = Object.values(this._states);
36858
36908
 
36859
- const matches = _states.filter(
36860
- (_state) =>
36861
- _state.__stateObjectCache.nameGlob &&
36862
- _state.__stateObjectCache.nameGlob.matches(name),
36909
+ const matches = states.filter((stateObj) =>
36910
+ stateObj._stateObjectCache.nameGlob?.matches(name),
36863
36911
  );
36864
36912
 
36865
36913
  if (matches.length > 1) {
@@ -37188,11 +37236,11 @@ function resolvablesBuilder(state) {
37188
37236
  class StateBuilder {
37189
37237
  /**
37190
37238
  * @param {import('./state-matcher.js').StateMatcher} matcher
37191
- * @param urlService
37239
+ * @param {ng.UrlService} urlService
37192
37240
  */
37193
37241
  constructor(matcher, urlService) {
37194
- this.matcher = matcher;
37195
- this.$injector = undefined;
37242
+ this._matcher = matcher;
37243
+ this._$injector = undefined;
37196
37244
  const self = this;
37197
37245
 
37198
37246
  const root = () => matcher.find("");
@@ -37202,7 +37250,7 @@ class StateBuilder {
37202
37250
 
37203
37251
  return matcher.find(self.parentName(state)) || root();
37204
37252
  }
37205
- this.builders = {
37253
+ this._builders = {
37206
37254
  name: [(state) => state.name],
37207
37255
  self: [selfBuilder],
37208
37256
  parent: [parentBuilder],
@@ -37212,7 +37260,7 @@ class StateBuilder {
37212
37260
  // Keep track of the closest ancestor state that has a URL (i.e. is navigable)
37213
37261
  navigable: [getNavigableBuilder(isRoot)],
37214
37262
  // TODO
37215
- params: [getParamsBuilder(urlService.paramFactory)],
37263
+ params: [getParamsBuilder(urlService._paramFactory)],
37216
37264
  // Each framework-specific ng-router implementation should define its own `views` builder
37217
37265
  // e.g., src/ng1/statebuilders/views.ts
37218
37266
  views: [],
@@ -37225,7 +37273,7 @@ class StateBuilder {
37225
37273
  }
37226
37274
 
37227
37275
  builder(name, fn) {
37228
- const { builders } = this;
37276
+ const { _builders: builders } = this;
37229
37277
 
37230
37278
  const array = builders[name] || [];
37231
37279
 
@@ -37248,7 +37296,7 @@ class StateBuilder {
37248
37296
  * @returns the built State object
37249
37297
  */
37250
37298
  build(state) {
37251
- const { matcher, builders } = this;
37299
+ const { _matcher: matcher, _builders: builders } = this;
37252
37300
 
37253
37301
  const parent = this.parentName(state);
37254
37302
 
@@ -37324,13 +37372,14 @@ function getToken(provider) {
37324
37372
  class StateQueueManager {
37325
37373
  /**
37326
37374
  * @param {import("./state-registry.js").StateRegistryProvider} stateRegistry
37327
- * @param {*} urlServiceRules
37328
- * @param {Record<string, ng.StateObject>} states
37375
+ * @param {import("../url/url-rules.js").UrlRules} urlServiceRules
37376
+ * @param {import("./interface.ts").StateStore} states
37329
37377
  * @param {*} builder
37330
37378
  * @param {*} listeners
37331
37379
  */
37332
37380
  constructor(stateRegistry, urlServiceRules, states, builder, listeners) {
37333
37381
  this.stateRegistry = stateRegistry;
37382
+ /** @type {import("../url/url-rules.js").UrlRules} */
37334
37383
  this.urlServiceRules = urlServiceRules;
37335
37384
  this.states = states;
37336
37385
  this.builder = builder;
@@ -37426,11 +37475,16 @@ class StateQueueManager {
37426
37475
  return states;
37427
37476
  }
37428
37477
 
37478
+ /**
37479
+ *
37480
+ * @param {ng.StateDeclaration} state
37481
+ * @returns {() => void} a function that deregisters the rule
37482
+ */
37429
37483
  attachRoute(state) {
37430
37484
  if (state.abstract || !state.url) return;
37431
37485
  const rulesApi = this.urlServiceRules;
37432
37486
 
37433
- rulesApi.rule(rulesApi.urlRuleFactory.create(state));
37487
+ rulesApi.rule(rulesApi._urlRuleFactory.create(state));
37434
37488
  }
37435
37489
  }
37436
37490
 
@@ -37456,12 +37510,12 @@ class StateRegistryProvider {
37456
37510
  * @param {ng.ViewService} viewService
37457
37511
  */
37458
37512
  constructor(urlService, stateService, globals, viewService) {
37459
- /** @type {Record<string, import("./state-object.js").StateObject>} */
37513
+ /** @type {import("./interface.ts").StateStore} */
37460
37514
  this.states = {};
37461
37515
 
37462
37516
  stateService.stateRegistry = this; // <- circular wiring
37463
37517
  this.urlService = urlService;
37464
- this.urlServiceRules = urlService.rules;
37518
+ this.urlServiceRules = urlService._rules;
37465
37519
  this.$injector = undefined;
37466
37520
  this.listeners = [];
37467
37521
  this.matcher = new StateMatcher(this.states);
@@ -37496,7 +37550,7 @@ class StateRegistryProvider {
37496
37550
  */
37497
37551
  ($injector) => {
37498
37552
  this.$injector = $injector;
37499
- this.builder.$injector = $injector;
37553
+ this.builder._$injector = $injector;
37500
37554
 
37501
37555
  return this;
37502
37556
  },
@@ -37622,7 +37676,7 @@ class StateRegistryProvider {
37622
37676
  }
37623
37677
 
37624
37678
  _deregisterTree(state) {
37625
- const all = this.get().map((x) => x.$$state());
37679
+ const all = this.getAll().map((x) => x.$$state());
37626
37680
 
37627
37681
  const getChildren = (states) => {
37628
37682
  const _children = all.filter((x) => states.indexOf(x.parent) !== -1);
@@ -37661,11 +37715,18 @@ class StateRegistryProvider {
37661
37715
  * @returns {import('./state-object').StateObject[]} a list of removed states
37662
37716
  */
37663
37717
  deregister(stateOrName) {
37664
- const _state = this.get(stateOrName);
37718
+ const state =
37719
+ /** @type {import("./interface.ts").BuiltStateDeclaration} */ (
37720
+ this.get(stateOrName)
37721
+ );
37665
37722
 
37666
- if (!_state)
37723
+ if (!state)
37667
37724
  throw new Error(`Can't deregister state; not found: ${stateOrName}`);
37668
- const deregisteredStates = this._deregisterTree(_state.$$state());
37725
+ const deregisteredStates = this._deregisterTree(
37726
+ /** @type {import("./interface.ts").BuiltStateDeclaration} */ (
37727
+ state
37728
+ ).$$state(),
37729
+ );
37669
37730
 
37670
37731
  this.listeners.forEach((listener) =>
37671
37732
  listener(
@@ -38757,15 +38818,18 @@ function ngChannelDirective($eventBus) {
38757
38818
 
38758
38819
  const hasTemplateContent = element.childNodes.length > 0;
38759
38820
 
38760
- const unsubscribe = $eventBus.subscribe(channel, (value) => {
38761
- if (hasTemplateContent) {
38762
- if (isObject(value)) {
38763
- scope.$merge(value);
38821
+ const unsubscribe = $eventBus.subscribe(
38822
+ channel,
38823
+ (/** @type {string | Object} */ value) => {
38824
+ if (hasTemplateContent) {
38825
+ if (isObject(value)) {
38826
+ scope.$merge(value);
38827
+ }
38828
+ } else if (isString(value)) {
38829
+ element.innerHTML = value;
38764
38830
  }
38765
- } else {
38766
- element.innerHTML = value;
38767
- }
38768
- });
38831
+ },
38832
+ );
38769
38833
 
38770
38834
  scope.$on("$destroy", () => unsubscribe());
38771
38835
  },
@@ -38777,7 +38841,7 @@ ngSetterDirective.$inject = [$injectTokens._parse, $injectTokens._log];
38777
38841
  /**
38778
38842
  * @param {ng.ParseService} $parse
38779
38843
  * @param {ng.LogService} $log
38780
- * @returns {import('interface.ts').Directive}
38844
+ * @returns {ng.Directive}
38781
38845
  */
38782
38846
  function ngSetterDirective($parse, $log) {
38783
38847
  return {
@@ -38799,7 +38863,7 @@ function ngSetterDirective($parse, $log) {
38799
38863
  return;
38800
38864
  }
38801
38865
 
38802
- const updateModel = (value) => {
38866
+ const updateModel = (/** @type {string} */ value) => {
38803
38867
  assignModel(scope, value.trim());
38804
38868
  };
38805
38869
 
@@ -38937,7 +39001,7 @@ class PubSub {
38937
39001
 
38938
39002
  let called = false;
38939
39003
 
38940
- const wrapper = (...args) => {
39004
+ const wrapper = (/** @type {any[]} */ ...args) => {
38941
39005
  if (called) return;
38942
39006
  called = true;
38943
39007
 
@@ -39084,28 +39148,206 @@ function ngElDirective() {
39084
39148
  }
39085
39149
 
39086
39150
  /**
39087
- * SSE Provider
39088
- *
39089
- * Usage:
39090
- * const source = $sse('/events', {
39091
- * onMessage: (data) => console.log(data),
39092
- * onError: (err) => console.error(err),
39093
- * retryDelay: 2000,
39094
- * heartbeatTimeout: 10000,
39095
- * });
39096
- *
39097
- * source.close();
39151
+ * Shared Stream Connection Manager
39152
+ * Handles reconnect, heartbeat, and event callbacks for SSE or WebSocket
39098
39153
  */
39154
+ class StreamConnection {
39155
+ /**
39156
+ * @param {() => EventSource | WebSocket} createFn - Function that creates a new EventSource or WebSocket.
39157
+ * @param {ng.StreamConnectionConfig} config - Configuration object with callbacks, retries, heartbeat, transformMessage.
39158
+ * @param {ng.LogService} log - Optional logger (default: console).
39159
+ */
39160
+ constructor(createFn, config = {}, log = console) {
39161
+ /** @private @type {() => EventSource | WebSocket} */
39162
+ this._createFn = createFn;
39163
+ this._config = {
39164
+ retryDelay: 1000,
39165
+ maxRetries: Infinity,
39166
+ heartbeatTimeout: 15000,
39167
+ transformMessage: (/** @type {string} */ data) => {
39168
+ try {
39169
+ return JSON.parse(data);
39170
+ } catch {
39171
+ return data;
39172
+ }
39173
+ },
39174
+ ...config,
39175
+ };
39176
+ this._log = log;
39177
+ this._retryCount = 0;
39178
+ this._closed = false;
39179
+ this._heartbeatTimer = undefined;
39180
+ /** @type {EventSource | WebSocket | null} */
39181
+ this._connection = null;
39182
+
39183
+ this.connect();
39184
+ }
39185
+
39186
+ /**
39187
+ * Establishes a new connection using the provided createFn.
39188
+ * Closes any existing connection before creating a new one.
39189
+ */
39190
+ connect() {
39191
+ if (this._closed) return;
39192
+
39193
+ // Close the old connection if it exists
39194
+ if (this._connection && typeof this._connection.close === "function") {
39195
+ this._connection.close();
39196
+ }
39197
+
39198
+ // Create new connection
39199
+ this._connection = this._createFn();
39200
+
39201
+ // Bind events for the new connection
39202
+ this._bindEvents();
39203
+ }
39204
+
39205
+ /**
39206
+ * Sends data over a WebSocket connection.
39207
+ * Logs a warning if called on a non-WebSocket connection.
39208
+ * @param {any} data - Data to send.
39209
+ */
39210
+ send(data) {
39211
+ if (this._connection instanceof WebSocket) {
39212
+ this._connection.send(JSON.stringify(data));
39213
+ } else {
39214
+ this._log.warn("Send is only supported on WebSocket connections");
39215
+ }
39216
+ }
39217
+
39218
+ /**
39219
+ * Closes the connection manually and clears the heartbeat timer.
39220
+ */
39221
+ close() {
39222
+ this._closed = true;
39223
+ clearTimeout(this._heartbeatTimer);
39224
+
39225
+ if (this._connection && this._connection.close) {
39226
+ this._connection.close();
39227
+ }
39228
+ }
39229
+
39230
+ /**
39231
+ * @private
39232
+ * Binds event handlers to the underlying connection (EventSource or WebSocket)
39233
+ * for open, message, error, and close events.
39234
+ */
39235
+ _bindEvents() {
39236
+ const conn = this._connection;
39237
+
39238
+ if (conn instanceof EventSource) {
39239
+ conn.addEventListener("open", (err) => this._handleOpen(err));
39240
+ conn.addEventListener("message", (err) =>
39241
+ this._handleMessage(err.data, err),
39242
+ );
39243
+ conn.addEventListener("error", (err) => this._handleError(err));
39244
+ } else if (conn instanceof WebSocket) {
39245
+ conn.onopen = (err) => this._handleOpen(err);
39246
+ conn.onmessage = (err) => this._handleMessage(err.data, err);
39247
+ conn.onerror = (err) => this._handleError(err);
39248
+ conn.onclose = () => this._handleClose();
39249
+ }
39250
+ }
39251
+
39252
+ /**
39253
+ * @private
39254
+ * Handles the open event from the connection.
39255
+ * @param {Event} event - The open event.
39256
+ */
39257
+ _handleOpen(event) {
39258
+ this._retryCount = 0;
39259
+ this._config.onOpen?.(event);
39260
+ this._resetHeartbeat();
39261
+ }
39262
+
39263
+ /**
39264
+ * @private
39265
+ * Handles incoming messages, applies the transformMessage function,
39266
+ * and calls the onMessage callback.
39267
+ * @param {any} data - Raw message data.
39268
+ * @param {Event} event - The message event.
39269
+ */
39270
+ _handleMessage(data, event) {
39271
+ try {
39272
+ data = this._config.transformMessage?.(data) ?? data;
39273
+ } catch {
39274
+ /* empty */
39275
+ }
39276
+ this._config.onMessage?.(data, event);
39277
+ this._resetHeartbeat();
39278
+ }
39279
+
39280
+ /**
39281
+ * @private
39282
+ * Handles errors emitted from the connection.
39283
+ * Calls onError callback and schedules a reconnect.
39284
+ * @param {any} err - Error object or message.
39285
+ */
39286
+ _handleError(err) {
39287
+ this._config.onError?.(err);
39288
+ this._scheduleReconnect();
39289
+ }
39290
+
39291
+ /**
39292
+ * @private
39293
+ * Handles close events for WebSocket connections.
39294
+ * Triggers reconnect logic.
39295
+ */
39296
+ _handleClose() {
39297
+ this._scheduleReconnect();
39298
+ }
39299
+
39300
+ /**
39301
+ * @private
39302
+ * Schedules a reconnect attempt based on retryCount and config.maxRetries.
39303
+ * Calls onReconnect callback if reconnecting.
39304
+ */
39305
+ _scheduleReconnect() {
39306
+ if (this._closed) return;
39307
+
39308
+ if (this._retryCount < this._config.maxRetries) {
39309
+ this._retryCount++;
39310
+ this._config.onReconnect?.(this._retryCount);
39311
+ setTimeout(() => this.connect(), this._config.retryDelay);
39312
+ } else {
39313
+ this._log.warn("StreamConnection: Max retries reached");
39314
+ }
39315
+ }
39316
+
39317
+ /**
39318
+ * @private
39319
+ * Resets the heartbeat timer. If the timer expires, the connection is closed
39320
+ * and a reconnect is attempted.
39321
+ */
39322
+ _resetHeartbeat() {
39323
+ if (!this._config.heartbeatTimeout) return;
39324
+
39325
+ clearTimeout(this._heartbeatTimer);
39326
+ this._heartbeatTimer = setTimeout(() => {
39327
+ this._log.warn("StreamConnection: heartbeat timeout, reconnecting...");
39328
+ this._closeInternal();
39329
+ this._retryCount++;
39330
+ this._config.onReconnect?.(this._retryCount);
39331
+ this.connect();
39332
+ }, this._config.heartbeatTimeout);
39333
+ }
39334
+
39335
+ /**
39336
+ * @private
39337
+ */
39338
+ _closeInternal() {
39339
+ clearTimeout(this._heartbeatTimer);
39340
+ this._connection?.close();
39341
+ }
39342
+ }
39343
+
39099
39344
  class SseProvider {
39100
39345
  constructor() {
39101
- /**
39102
- * Optional provider-level defaults
39103
- * @type {ng.SseConfig}
39104
- */
39346
+ /** @type {ng.SseConfig} */
39105
39347
  this.defaults = {
39106
39348
  retryDelay: 1000,
39107
39349
  maxRetries: Infinity,
39108
- heartbeatTimeout: 15000, // 15 seconds
39350
+ heartbeatTimeout: 15000,
39109
39351
  transformMessage(data) {
39110
39352
  try {
39111
39353
  return JSON.parse(data);
@@ -39118,20 +39360,32 @@ class SseProvider {
39118
39360
 
39119
39361
  $get = [
39120
39362
  $injectTokens._log,
39121
- /**
39122
- * Returns the $sse service function
39123
- * @param {ng.LogService} log
39124
- * @returns {ng.SseService}
39125
- */
39126
- (log) => {
39363
+ /** @param {ng.LogService} log */ (log) => {
39127
39364
  this._$log = log;
39128
39365
 
39366
+ /** @type {ng.SseService} */
39129
39367
  return (url, config = {}) => {
39130
39368
  const mergedConfig = { ...this.defaults, ...config };
39131
39369
 
39132
39370
  const finalUrl = this.#buildUrl(url, mergedConfig.params);
39133
39371
 
39134
- return this.#createConnection(finalUrl, mergedConfig);
39372
+ return new StreamConnection(
39373
+ () =>
39374
+ new EventSource(finalUrl, {
39375
+ withCredentials: !!mergedConfig.withCredentials,
39376
+ }),
39377
+ {
39378
+ ...mergedConfig,
39379
+ onMessage: (data, event) => {
39380
+ // Cast Event -> MessageEvent safely
39381
+ mergedConfig.onMessage?.(
39382
+ data,
39383
+ /** @type{MessageEvent} */ (event),
39384
+ );
39385
+ },
39386
+ },
39387
+ this._$log,
39388
+ );
39135
39389
  };
39136
39390
  },
39137
39391
  ];
@@ -39141,6 +39395,7 @@ class SseProvider {
39141
39395
  * @param {string} url
39142
39396
  * @param {Record<string, any>=} params
39143
39397
  * @returns {string}
39398
+ * @throws {URIError}
39144
39399
  */
39145
39400
  #buildUrl(url, params) {
39146
39401
  if (!params) return url;
@@ -39150,91 +39405,6 @@ class SseProvider {
39150
39405
 
39151
39406
  return url + (url.includes("?") ? "&" : "?") + query;
39152
39407
  }
39153
-
39154
- /**
39155
- * Creates a managed SSE connection with reconnect and heartbeat
39156
- * @param {string} url
39157
- * @param {ng.SseConfig} config
39158
- * @returns {import("./interface.ts").SseConnection}
39159
- */
39160
- #createConnection(url, config) {
39161
- let es;
39162
-
39163
- let retryCount = 0;
39164
-
39165
- let closed = false;
39166
-
39167
- let heartbeatTimer;
39168
-
39169
- const connect = () => {
39170
- if (closed) return;
39171
-
39172
- es = new EventSource(url, {
39173
- withCredentials: !!config.withCredentials,
39174
- });
39175
-
39176
- es.addEventListener("open", (event) => {
39177
- retryCount = 0;
39178
- config.onOpen?.(event);
39179
-
39180
- if (config.heartbeatTimeout) resetHeartbeat();
39181
- });
39182
-
39183
- es.addEventListener("message", (event) => {
39184
- let { data } = event;
39185
-
39186
- try {
39187
- data = config.transformMessage ? config.transformMessage(data) : data;
39188
- } catch {
39189
- /* empty */
39190
- }
39191
- config.onMessage?.(data, event);
39192
-
39193
- if (config.heartbeatTimeout) resetHeartbeat();
39194
- });
39195
-
39196
- es.addEventListener("error", (err) => {
39197
- config.onError?.(err);
39198
-
39199
- if (closed) return;
39200
- es.close();
39201
-
39202
- if (retryCount < config.maxRetries) {
39203
- retryCount++;
39204
- config.onReconnect?.(retryCount);
39205
- setTimeout(connect, config.retryDelay);
39206
- } else {
39207
- this._$log.warn("SSE: Max retries reached");
39208
- }
39209
- });
39210
- };
39211
-
39212
- const resetHeartbeat = () => {
39213
- clearTimeout(heartbeatTimer);
39214
- heartbeatTimer = setTimeout(() => {
39215
- this._$log.warn("SSE: heartbeat timeout, reconnecting...");
39216
- es.close();
39217
- config.onReconnect?.(++retryCount);
39218
- connect();
39219
- }, config.heartbeatTimeout);
39220
- };
39221
-
39222
- connect();
39223
-
39224
- return {
39225
- close() {
39226
- closed = true;
39227
- clearTimeout(heartbeatTimer);
39228
- es.close();
39229
- },
39230
- connect() {
39231
- if (closed === false) {
39232
- close();
39233
- }
39234
- connect();
39235
- },
39236
- };
39237
- }
39238
39408
  }
39239
39409
 
39240
39410
  /**
@@ -39329,11 +39499,7 @@ class CookieProvider {
39329
39499
  this.defaults = {};
39330
39500
  }
39331
39501
 
39332
- $get = [
39333
- $injectTokens._exceptionHandler,
39334
- /** @param {ng.ExceptionHandlerService} $exceptionHandler */
39335
- ($exceptionHandler) => new CookieService(this.defaults, $exceptionHandler),
39336
- ];
39502
+ $get = () => new CookieService(this.defaults);
39337
39503
  }
39338
39504
 
39339
39505
  /**
@@ -39347,14 +39513,10 @@ class CookieService {
39347
39513
  /**
39348
39514
  * @param {ng.CookieOptions} defaults
39349
39515
  * Default cookie attributes defined by `$cookiesProvider.defaults`.
39350
- * @param {ng.ExceptionHandlerService} $exceptionHandler
39351
39516
  */
39352
- constructor(defaults, $exceptionHandler) {
39517
+ constructor(defaults) {
39353
39518
  /** @private @type {ng.CookieOptions} */
39354
39519
  this._defaults = Object.freeze({ ...defaults });
39355
-
39356
- /** @private @type {ng.ExceptionHandlerService} */
39357
- this._$exceptionHandler = $exceptionHandler;
39358
39520
  }
39359
39521
 
39360
39522
  /**
@@ -39366,14 +39528,9 @@ class CookieService {
39366
39528
  */
39367
39529
  get(key) {
39368
39530
  validateIsString(key, "key");
39531
+ const all = parseCookies();
39369
39532
 
39370
- try {
39371
- const all = parseCookies();
39372
-
39373
- return all[key] || null;
39374
- } catch (err) {
39375
- throw this._$exceptionHandler(err);
39376
- }
39533
+ return all[key] || null;
39377
39534
  }
39378
39535
 
39379
39536
  /**
@@ -39391,13 +39548,7 @@ class CookieService {
39391
39548
 
39392
39549
  if (!raw) return null;
39393
39550
 
39394
- try {
39395
- return /** @type {T} */ (JSON.parse(raw));
39396
- } catch (err) {
39397
- this._$exceptionHandler(err);
39398
-
39399
- return null;
39400
- }
39551
+ return /** @type {T} */ (JSON.parse(raw));
39401
39552
  }
39402
39553
 
39403
39554
  /**
@@ -39407,11 +39558,7 @@ class CookieService {
39407
39558
  * @throws {URIError} – If decodeURIComponent fails
39408
39559
  */
39409
39560
  getAll() {
39410
- try {
39411
- return parseCookies();
39412
- } catch (err) {
39413
- return this._$exceptionHandler(err);
39414
- }
39561
+ return parseCookies();
39415
39562
  }
39416
39563
 
39417
39564
  /**
@@ -39420,6 +39567,7 @@ class CookieService {
39420
39567
  * @param {string} key
39421
39568
  * @param {string} value
39422
39569
  * @param {ng.CookieOptions} [options]
39570
+ * @throws {URIError} if key or value cannot be encoded
39423
39571
  */
39424
39572
  put(key, value, options = {}) {
39425
39573
  validateIsString(key, "key");
@@ -39428,14 +39576,10 @@ class CookieService {
39428
39576
 
39429
39577
  const encodedVal = encodeURIComponent(value);
39430
39578
 
39431
- try {
39432
- document.cookie = `${encodedKey}=${encodedVal}${buildOptions({
39433
- ...this._defaults,
39434
- ...options,
39435
- })}`;
39436
- } catch (err) {
39437
- this._$exceptionHandler(err);
39438
- }
39579
+ document.cookie = `${encodedKey}=${encodedVal}${buildOptions({
39580
+ ...this._defaults,
39581
+ ...options,
39582
+ })}`;
39439
39583
  }
39440
39584
 
39441
39585
  /**
@@ -39449,19 +39593,9 @@ class CookieService {
39449
39593
  putObject(key, value, options) {
39450
39594
  validateIsString(key, "key");
39451
39595
  validateRequired(value, "value");
39452
- assert(!isNullOrUndefined(value), BADARGVALUE);
39596
+ const str = JSON.stringify(value);
39453
39597
 
39454
- try {
39455
- const str = JSON.stringify(value);
39456
-
39457
- this.put(key, str, options);
39458
- } catch (err) {
39459
- this._$exceptionHandler(
39460
- new TypeError(
39461
- `badserialize: "${key}" => ${/** @type {Error} */ (err).message}`,
39462
- ),
39463
- );
39464
- }
39598
+ this.put(key, str, options);
39465
39599
  }
39466
39600
 
39467
39601
  /**
@@ -40110,6 +40244,37 @@ class RestProvider {
40110
40244
  ];
40111
40245
  }
40112
40246
 
40247
+ /**
40248
+ * @returns {ng.Directive}
40249
+ */
40250
+ function ngListenerDirective() {
40251
+ return {
40252
+ scope: false,
40253
+ link: (scope, element, attrs) => {
40254
+ const channel = attrs.ngListener || element.id;
40255
+
40256
+ const hasTemplateContent = element.childNodes.length;
40257
+
40258
+ /** @type {EventListener} */
40259
+ const fn = (event) => {
40260
+ const value = /** @type {CustomEvent} */ (event).detail;
40261
+
40262
+ if (hasTemplateContent) {
40263
+ if (isObject(value)) {
40264
+ scope.$merge(value);
40265
+ }
40266
+ } else if (isString(value)) {
40267
+ element.innerHTML = value;
40268
+ }
40269
+ };
40270
+
40271
+ element.addEventListener(channel, fn);
40272
+
40273
+ scope.$on("$destroy", () => element.removeEventListener(channel, fn));
40274
+ },
40275
+ };
40276
+ }
40277
+
40113
40278
  /**
40114
40279
  * Initializes core `ng` module.
40115
40280
  * @param {ng.Angular} angular
@@ -40159,6 +40324,7 @@ function registerNgModule(angular) {
40159
40324
  ngInclude: ngIncludeDirective,
40160
40325
  ngInject: ngInjectDirective,
40161
40326
  ngInit: ngInitDirective,
40327
+ ngListener: ngListenerDirective,
40162
40328
  ngMessages: ngMessagesDirective,
40163
40329
  ngMessage: ngMessageDirective,
40164
40330
  ngMessageExp: ngMessageExpDirective,
@@ -40287,8 +40453,10 @@ const STRICT_DI = "strict-di";
40287
40453
  /** @type {ModuleRegistry} */
40288
40454
  const moduleRegistry = {};
40289
40455
 
40290
- class Angular {
40456
+ class Angular extends EventTarget {
40291
40457
  constructor() {
40458
+ super();
40459
+
40292
40460
  /** @private @type {!Array<string|any>} */
40293
40461
  this._bootsrappedModules = [];
40294
40462
 
@@ -40302,7 +40470,7 @@ class Angular {
40302
40470
  * @public
40303
40471
  * @type {string} `version` from `package.json`
40304
40472
  */
40305
- this.version = "0.15.0"; //inserted via rollup plugin
40473
+ this.version = "0.15.1"; //inserted via rollup plugin
40306
40474
 
40307
40475
  /**
40308
40476
  * Gets the controller instance for a given element, if exists. Defaults to "ngControllerController"