@sumaris-net/ngx-components 2.18.0-beta1 → 2.18.0-beta11

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/esm2022/public_api.mjs +2 -1
  2. package/esm2022/src/app/core/account/account.page.mjs +1 -2
  3. package/esm2022/src/app/core/auth/auth.form.mjs +1 -2
  4. package/esm2022/src/app/core/form/array/testing/form-array.test.mjs +1 -2
  5. package/esm2022/src/app/core/form/entity/entity-editor-modal.class.mjs +1 -2
  6. package/esm2022/src/app/core/form/entity/entity-editor.class.mjs +1 -2
  7. package/esm2022/src/app/core/form/entity/tab-editor.class.mjs +1 -2
  8. package/esm2022/src/app/core/form/form-container.class.mjs +6 -3
  9. package/esm2022/src/app/core/form/form.utils.mjs +5 -2
  10. package/esm2022/src/app/core/form/properties/properties.utils.mjs +60 -0
  11. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +1 -2
  12. package/esm2022/src/app/core/menu/menu.component.mjs +1 -2
  13. package/esm2022/src/app/core/menu/menu.service.mjs +1 -2
  14. package/esm2022/src/app/core/services/account.service.mjs +3 -3
  15. package/esm2022/src/app/core/services/config.service.mjs +1 -2
  16. package/esm2022/src/app/core/services/model/entity.model.mjs +3 -9
  17. package/esm2022/src/app/core/services/model/peer.model.mjs +11 -2
  18. package/esm2022/src/app/core/services/network.service.mjs +4 -3
  19. package/esm2022/src/app/core/services/platform.service.mjs +1 -2
  20. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +8 -7
  21. package/esm2022/src/app/core/settings/settings.page.mjs +5 -5
  22. package/esm2022/src/app/core/table/async-table.class.mjs +1 -2
  23. package/esm2022/src/app/core/table/entities-table-datasource.class.mjs +1 -2
  24. package/esm2022/src/app/core/table/table.class.mjs +1 -2
  25. package/esm2022/src/app/shared/form/field.component.mjs +1 -2
  26. package/esm2022/src/app/shared/forms.mjs +45 -3
  27. package/esm2022/src/app/shared/functions.mjs +1 -2
  28. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +3 -3
  29. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +37 -9
  30. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +1 -2
  31. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +1 -2
  32. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +1 -2
  33. package/esm2022/src/app/shared/material/datetime/material.date.mjs +1 -2
  34. package/esm2022/src/app/shared/material/datetime/material.dateshort.mjs +4 -3
  35. package/esm2022/src/app/shared/material/datetime/material.datetime.mjs +1 -2
  36. package/esm2022/src/app/shared/material/duration/material.duration.mjs +1 -2
  37. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +1 -2
  38. package/esm2022/src/app/shared/material/swipe/material.swipe.mjs +1 -2
  39. package/esm2022/src/app/shared/toolbar/toolbar.mjs +1 -2
  40. package/esm2022/src/app/shared/upload-file/testing/upload-file.testing.mjs +1 -2
  41. package/esm2022/src/app/shared/validator/validators.mjs +3 -2
  42. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +1 -2
  43. package/esm2022/src/app/social/message/message.modal.mjs +1 -2
  44. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +1 -2
  45. package/fesm2022/sumaris-net.ngx-components.mjs +233 -92
  46. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  47. package/package.json +2 -2
  48. package/public_api.d.ts +1 -0
  49. package/src/app/core/form/form.utils.d.ts +4 -1
  50. package/src/app/core/form/properties/properties.utils.d.ts +27 -0
  51. package/src/app/core/services/model/entity.model.d.ts +3 -2
  52. package/src/app/core/services/model/peer.model.d.ts +1 -0
  53. package/src/app/shared/forms.d.ts +19 -0
  54. package/src/app/shared/hotkeys/hotkeys.service.d.ts +16 -2
  55. package/src/app/shared/validator/validators.d.ts +2 -0
  56. package/src/assets/i18n/en-US.json +1 -0
  57. package/src/assets/i18n/en.json +1 -0
  58. package/src/assets/i18n/fr.json +1 -0
  59. package/src/assets/manifest.json +1 -1
@@ -2,7 +2,6 @@ import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Directive, Pipe, Injectable, EventEmitter, Output, Optional, Inject, NgModule, forwardRef, Component, ChangeDetectionStrategy, Input, ViewChildren, HostBinding, HostListener, ElementRef, booleanAttribute, numberAttribute, ViewChild, ANIMATION_MODULE_TYPE, RendererStyleFlags2, CUSTOM_ELEMENTS_SCHEMA, inject, ViewEncapsulation, APP_INITIALIZER, ChangeDetectorRef } from '@angular/core';
3
3
  import { firstValueFrom, shareReplay, tap, of, timer, Subject, merge, delay, isObservable, from, Subscription, BehaviorSubject, fromEvent, noop as noop$a, Observable, forkJoin, defer, timeout, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, fromEventPattern, interval, combineLatest, mergeMap as mergeMap$1, EMPTY, switchMap as switchMap$1 } from 'rxjs';
4
4
  import { catchError, map, filter, takeUntil, first, switchMap, tap as tap$1, debounceTime, startWith, distinctUntilChanged, mergeMap, skip, finalize, throttleTime, bufferWhen, mapTo, distinctUntilKeyChanged, take } from 'rxjs/operators';
5
- import { setTimeout as setTimeout$1 } from '@rx-angular/cdk/zone-less/browser';
6
5
  import * as i3 from '@angular/common';
7
6
  import { CommonModule, DOCUMENT, Location } from '@angular/common';
8
7
  import { CdkTableModule } from '@angular/cdk/table';
@@ -35,7 +34,7 @@ import * as i1 from '@angular/material-moment-adapter';
35
34
  import { MatMomentDateModule } from '@angular/material-moment-adapter';
36
35
  import { isMoment as isMoment$1 } from 'moment/moment';
37
36
  import * as i1$3 from '@angular/forms';
38
- import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, NG_VALUE_ACCESSOR, Validators, ReactiveFormsModule, FormControl, FormGroup, FormsModule } from '@angular/forms';
37
+ import { AbstractControl, UntypedFormArray, UntypedFormGroup, UntypedFormControl, Validators, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormControl, FormGroup, FormsModule } from '@angular/forms';
39
38
  import { maskitoWithPlaceholder, maskitoEventHandler, maskitoDateOptionsGenerator, maskitoTimeOptionsGenerator } from '@maskito/kit';
40
39
  import * as i1$2 from '@angular/platform-browser';
41
40
  import { HammerGestureConfig, HammerModule } from '@angular/platform-browser';
@@ -558,7 +557,7 @@ function setPropertyByPath(obj, path, value) {
558
557
  function sleep(ms) {
559
558
  if (ms <= 0)
560
559
  return Promise.resolve();
561
- return new Promise((resolve) => setTimeout$1(resolve, ms));
560
+ return new Promise((resolve) => setTimeout(resolve, ms));
562
561
  }
563
562
  function round(value) {
564
563
  if (isNotNilOrNaN(value)) {
@@ -2493,6 +2492,8 @@ class SharedValidators {
2493
2492
  pattern: 'ERROR.FIELD_NOT_VALID_PATTERN',
2494
2493
  unique: 'ERROR.FIELD_NOT_UNIQUE',
2495
2494
  entity: 'ERROR.FIELD_INVALID',
2495
+ invalid: 'ERROR.FIELD_INVALID',
2496
+ inconsistent: 'ERROR.FIELD_INCONSISTENT',
2496
2497
  equals: 'ERROR.FIELD_NOT_EQUALS',
2497
2498
  };
2498
2499
  static latitude(control) {
@@ -3022,7 +3023,7 @@ class SharedAsyncValidators {
3022
3023
  // Clear added validator. Must be done NOW (without delay) because generally a new Job is given just after
3023
3024
  form.clearAsyncValidators();
3024
3025
  // Stop the job, with a delay to let the last execution finished
3025
- setTimeout$1(() => {
3026
+ setTimeout(() => {
3026
3027
  $dispose.next();
3027
3028
  $dispose.unsubscribe();
3028
3029
  }, debounceTime);
@@ -3512,6 +3513,20 @@ function getFormErrors(control, opts) {
3512
3513
  }
3513
3514
  // Form array
3514
3515
  else if (control instanceof UntypedFormArray) {
3516
+ // Copy errors
3517
+ if (control.errors) {
3518
+ if (opts.controlName) {
3519
+ opts.result[opts.controlName] = {
3520
+ ...control.errors,
3521
+ };
3522
+ }
3523
+ else {
3524
+ opts.result = {
3525
+ ...opts.result,
3526
+ ...control.errors,
3527
+ };
3528
+ }
3529
+ }
3515
3530
  control.controls.forEach((child, index) => {
3516
3531
  getFormErrors(child, {
3517
3532
  ...opts,
@@ -3554,6 +3569,34 @@ function disableControls(form, paths, opts) {
3554
3569
  control.disable(opts);
3555
3570
  });
3556
3571
  }
3572
+ function enableControls(form, paths, opts) {
3573
+ (paths || []).forEach((path) => {
3574
+ const control = getControlFromPath(form, path);
3575
+ if (control)
3576
+ control.enable(opts);
3577
+ });
3578
+ }
3579
+ function enableControl(control, opts) {
3580
+ this.setControlEnabled(control, true, opts);
3581
+ }
3582
+ function disableControl(control, opts) {
3583
+ this.setControlEnabled(control, false, { required: false, ...opts });
3584
+ }
3585
+ function setControlEnabled(control, enabled, opts) {
3586
+ if (enabled) {
3587
+ if (isNotNil(opts?.required) && opts.required && !control.hasValidator(Validators.required)) {
3588
+ control.addValidators(Validators.required);
3589
+ }
3590
+ control.enable(opts);
3591
+ }
3592
+ else {
3593
+ control.disable(opts);
3594
+ if (isNotNil(opts?.required) && !opts.required && control.hasValidator(Validators.required)) {
3595
+ control.removeValidators(Validators.required);
3596
+ }
3597
+ control.reset(null, opts);
3598
+ }
3599
+ }
3557
3600
  function addValueInArray(arrayControl, createControl, equals, isEmpty, value, options) {
3558
3601
  const disabled = arrayControl.disabled;
3559
3602
  let hasChanged = false;
@@ -3922,6 +3965,9 @@ class AppFormUtils {
3922
3965
  static logFormErrors = logFormErrors;
3923
3966
  static getControlFromPath = getControlFromPath;
3924
3967
  static filterNumberInput = filterNumberInput;
3968
+ static enabledControls = enableControls;
3969
+ static enabledControl = enableControl;
3970
+ static disableControl = disableControl;
3925
3971
  static disableControls = disableControls;
3926
3972
  static selectInputContent = selectInputContent;
3927
3973
  /**
@@ -5247,7 +5293,7 @@ class MatDuration {
5247
5293
  set tabindex(value) {
5248
5294
  if (this._tabindex !== value) {
5249
5295
  this._tabindex = value;
5250
- setTimeout$1(() => this.updateTabIndex());
5296
+ setTimeout(() => this.updateTabIndex());
5251
5297
  }
5252
5298
  }
5253
5299
  get tabindex() {
@@ -5399,7 +5445,7 @@ class MatDuration {
5399
5445
  focus() {
5400
5446
  if (!this.matInputs.length)
5401
5447
  return;
5402
- setTimeout$1(() => {
5448
+ setTimeout(() => {
5403
5449
  const elementRef = this.matInputs[0]; // get the first element
5404
5450
  if (isFocusableElement(elementRef)) {
5405
5451
  elementRef.focus();
@@ -5415,7 +5461,7 @@ class MatDuration {
5415
5461
  if (isNil(this._tabindex) || this._tabindex === -1)
5416
5462
  return; // skip
5417
5463
  // Focus to first input
5418
- setTimeout$1(() => {
5464
+ setTimeout(() => {
5419
5465
  this.matInputs.forEach((elementRef, index) => {
5420
5466
  setTabIndex(elementRef, this._tabindex + index);
5421
5467
  });
@@ -5815,7 +5861,7 @@ class MatBooleanField {
5815
5861
  set tabindex(value) {
5816
5862
  if (this._tabindex !== value) {
5817
5863
  this._tabindex = value;
5818
- setTimeout$1(() => this.updateTabIndex());
5864
+ setTimeout(() => this.updateTabIndex());
5819
5865
  }
5820
5866
  }
5821
5867
  get tabindex() {
@@ -5891,7 +5937,7 @@ class MatBooleanField {
5891
5937
  this.checkboxButton.checked = value;
5892
5938
  }
5893
5939
  }
5894
- setTimeout$1(() => {
5940
+ setTimeout(() => {
5895
5941
  this.updateFakeInput();
5896
5942
  this.updateTabIndex();
5897
5943
  });
@@ -5931,7 +5977,7 @@ class MatBooleanField {
5931
5977
  this._focused = true;
5932
5978
  this._onTouchedCallback();
5933
5979
  this.markForCheck();
5934
- setTimeout$1(() => {
5980
+ setTimeout(() => {
5935
5981
  // Add a blur listener on each inputs
5936
5982
  const inputElements = this.inputsElements;
5937
5983
  inputElements.forEach((el) => (el.onblur = (e) => {
@@ -7147,7 +7193,7 @@ class MatAutocompleteField {
7147
7193
  if (!event || event.defaultPrevented)
7148
7194
  return;
7149
7195
  // Need a timeout to prevent early blur event without triggering formChange event
7150
- setTimeout$1(() => {
7196
+ setTimeout(() => {
7151
7197
  // Ignore event from mat-option
7152
7198
  if ((event.relatedTarget instanceof HTMLElement && event.relatedTarget.tagName === 'MAT-OPTION') ||
7153
7199
  // Or autocomplete panel is open because event.relatedTarget is null (cf. https://github.com/angular/components/issues/24182)
@@ -8334,7 +8380,7 @@ class MatDate {
8334
8380
  focus() {
8335
8381
  if (!this._matInput)
8336
8382
  return;
8337
- setTimeout$1(() => {
8383
+ setTimeout(() => {
8338
8384
  if (isFocusableElement(this._matInput.nativeElement)) {
8339
8385
  this._matInput.nativeElement.focus();
8340
8386
  }
@@ -8505,7 +8551,7 @@ class MatDate {
8505
8551
  if (isNil(this._tabindex) || this._tabindex === -1)
8506
8552
  return; // skip
8507
8553
  // Focus to input
8508
- setTimeout$1(() => {
8554
+ setTimeout(() => {
8509
8555
  setTabIndex(this._matInput, this._tabindex);
8510
8556
  this.markForCheck();
8511
8557
  });
@@ -8805,7 +8851,7 @@ class MatDateTime {
8805
8851
  const matInput = this._matInputs.first;
8806
8852
  if (!matInput)
8807
8853
  return;
8808
- setTimeout$1(() => {
8854
+ setTimeout(() => {
8809
8855
  if (isFocusableElement(matInput.nativeElement)) {
8810
8856
  matInput.nativeElement.focus();
8811
8857
  }
@@ -9148,7 +9194,7 @@ class MatDateTime {
9148
9194
  if (isNil(this._tabindex) || this._tabindex === -1)
9149
9195
  return; // skip
9150
9196
  // Focus to first input
9151
- setTimeout$1(() => {
9197
+ setTimeout(() => {
9152
9198
  this._matInputs.forEach((elementRef, index) => {
9153
9199
  setTabIndex(elementRef, this._tabindex + index);
9154
9200
  });
@@ -9420,7 +9466,7 @@ class MatDateShort {
9420
9466
  focus() {
9421
9467
  if (!this._matInput)
9422
9468
  return;
9423
- setTimeout$1(() => {
9469
+ setTimeout(() => {
9424
9470
  if (isFocusableElement(this._matInput.nativeElement)) {
9425
9471
  this._matInput.nativeElement.focus();
9426
9472
  }
@@ -9496,7 +9542,9 @@ class MatDateShort {
9496
9542
  updateTranslations(translations) {
9497
9543
  const datePattern = translations['COMMON.DATE_YEAR_PATTERN'] !== 'COMMON.DATE_YEAR_PATTERN' ? translations['COMMON.DATE_YEAR_PATTERN'] : 'YYYY';
9498
9544
  this.updatePattern(datePattern);
9499
- const yearPlaceholder = translations['COMMON.DATE_YEAR_PLACEHOLDER'] !== 'COMMON.DATE_YEAR_PLACEHOLDER' ? translations['COMMON.DATE_YEAR_PLACEHOLDER'] : datePattern.toLowerCase();
9545
+ const yearPlaceholder = translations['COMMON.DATE_YEAR_PLACEHOLDER'] !== 'COMMON.DATE_YEAR_PLACEHOLDER'
9546
+ ? translations['COMMON.DATE_YEAR_PLACEHOLDER']
9547
+ : datePattern.toLowerCase();
9500
9548
  this.updateMaskOptions(yearPlaceholder);
9501
9549
  }
9502
9550
  updatePattern(pattern) {
@@ -9578,7 +9626,7 @@ class MatDateShort {
9578
9626
  if (isNil(this._tabindex) || this._tabindex === -1)
9579
9627
  return; // skip
9580
9628
  // Focus to input
9581
- setTimeout$1(() => {
9629
+ setTimeout(() => {
9582
9630
  setTabIndex(this._matInput, this._tabindex);
9583
9631
  this.markForCheck();
9584
9632
  });
@@ -9745,7 +9793,7 @@ class MatSwipeField {
9745
9793
  set tabindex(value) {
9746
9794
  if (this._tabindex !== value) {
9747
9795
  this._tabindex = value;
9748
- setTimeout$1(() => this.updateTabIndex());
9796
+ setTimeout(() => this.updateTabIndex());
9749
9797
  }
9750
9798
  }
9751
9799
  get tabindex() {
@@ -9827,7 +9875,7 @@ class MatSwipeField {
9827
9875
  focus() {
9828
9876
  // show slides component
9829
9877
  this.showSlides = true;
9830
- setTimeout$1(() => {
9878
+ setTimeout(() => {
9831
9879
  if (this.prevButton) {
9832
9880
  this.prevButton.focus();
9833
9881
  }
@@ -9870,7 +9918,7 @@ class MatSwipeField {
9870
9918
  this._value = value;
9871
9919
  this.showSlides = isNotNil(this._value);
9872
9920
  this.updateSlides();
9873
- setTimeout$1(() => this.updateTabIndex());
9921
+ setTimeout(() => this.updateTabIndex());
9874
9922
  }
9875
9923
  this._writing = false;
9876
9924
  this.markForCheck();
@@ -9883,10 +9931,10 @@ class MatSwipeField {
9883
9931
  this._value = undefined;
9884
9932
  this.formControl.patchValue(null, { emitEvent: false });
9885
9933
  this.showSlides = false;
9886
- setTimeout$1(() => {
9934
+ setTimeout(() => {
9887
9935
  this.updateTabIndex();
9888
9936
  this.slideTo(0);
9889
- setTimeout$1(() => {
9937
+ setTimeout(() => {
9890
9938
  this._writing = false;
9891
9939
  }, 100);
9892
9940
  });
@@ -11096,6 +11144,65 @@ class TreeItemEntityUtils {
11096
11144
  }
11097
11145
  }
11098
11146
 
11147
+ class AppPropertiesUtils {
11148
+ /**
11149
+ * Converts an array of Property objects to an object map.
11150
+ *
11151
+ * @param {Property[]} [sources] - The array of Property objects to convert.
11152
+ * @param {Object} [opts] - Options for the conversion.
11153
+ * @param {boolean} [opts.omitNilOrBlank] - If set to true, properties with nil or blank values will be omitted from the resulting object.
11154
+ * @return {PropertiesMap} The resulting object map where keys are property keys and values are property values.
11155
+ */
11156
+ static arrayAsObject(sources, opts) {
11157
+ return ((sources || [])
11158
+ // Serialize each item
11159
+ .map(AppPropertyUtils.asObject)
11160
+ // Fill a JSON object
11161
+ .reduce((res, item) => {
11162
+ if (isNilOrBlank(item.key))
11163
+ return res;
11164
+ if (isNilOrBlank(item.value) && opts?.omitNilOrBlank !== false)
11165
+ return res;
11166
+ res[item.key] = item.value;
11167
+ return res;
11168
+ }, {}));
11169
+ }
11170
+ /**
11171
+ * Converts an object into an array of properties.
11172
+ *
11173
+ * @param {PropertiesMap} [source] - The source object containing properties to convert.
11174
+ * @return {Property[]} An array of properties derived from the source object.
11175
+ */
11176
+ static arrayFromObject(source) {
11177
+ if (Array.isArray(source))
11178
+ return source; // Already an array
11179
+ return Object.getOwnPropertyNames(source || {}).map((key) => ({
11180
+ key,
11181
+ value: source[key],
11182
+ }));
11183
+ }
11184
+ }
11185
+ class AppPropertyUtils {
11186
+ static asObject(source) {
11187
+ if (!source)
11188
+ return undefined;
11189
+ // Serialize key (WARNING: can be an object, when using autocomplete field to edit a key - see AppPropertiesForm)
11190
+ const key = source.key?.key ?? source.key;
11191
+ // Serialize the value
11192
+ let value = source.value;
11193
+ if (Array.isArray(value)) {
11194
+ value = value
11195
+ .map((v) => v?.id ?? v)
11196
+ .filter(isNotNil)
11197
+ .join(',');
11198
+ }
11199
+ else {
11200
+ value = value?.id ?? value;
11201
+ }
11202
+ return { key, value };
11203
+ }
11204
+ }
11205
+
11099
11206
  function entityToString(obj, properties) {
11100
11207
  return (obj && obj.id && joinPropertiesPath(obj, properties || ['name'])) || undefined;
11101
11208
  }
@@ -11179,14 +11286,7 @@ class EntityUtils {
11179
11286
  value: source[key],
11180
11287
  }));
11181
11288
  }
11182
- static getPropertyArrayAsObject(source) {
11183
- return (source || []).reduce((res, item) => {
11184
- // Warning: when using <app-properties-form> key can be an object, used by autocomplete field
11185
- const key = typeof item.key === 'object' ? item.key?.key : item.key;
11186
- res[key] = item.value;
11187
- return res;
11188
- }, {});
11189
- }
11289
+ static getPropertyArrayAsObject = AppPropertiesUtils.arrayAsObject;
11190
11290
  static copyIdAndUpdateDate(source, target) {
11191
11291
  if (!source)
11192
11292
  return;
@@ -11560,6 +11660,9 @@ let Peer = class Peer extends Entity {
11560
11660
  .filter(isNotNilOrBlank);
11561
11661
  return [noTrailingSlash(this.fromObject(peer).url)].concat(...paths).join('/');
11562
11662
  }
11663
+ static equals(p1, p2) {
11664
+ return p1 && p2 && Peer_1.fromObject(p1).equals(p2);
11665
+ }
11563
11666
  dns;
11564
11667
  ipv4;
11565
11668
  ipv6;
@@ -11590,7 +11693,13 @@ let Peer = class Peer extends Entity {
11590
11693
  this.path = source.path || '';
11591
11694
  }
11592
11695
  equals(other) {
11593
- return super.equals(other) && this.pubkey === other.pubkey && this.url === other.url;
11696
+ return (
11697
+ // Same entity (by id)
11698
+ (isNotNil(this.id) && isNotNil(other.id) && this.id === other.id) ||
11699
+ // Same pubkey (if defined)
11700
+ ((!this.pubkey || !other.pubkey || this.pubkey === other.pubkey) &&
11701
+ // Same url
11702
+ this.url === other.url));
11594
11703
  }
11595
11704
  /**
11596
11705
  * Return the peer URL (without trailing slash)
@@ -13278,7 +13387,7 @@ class AppFormField {
13278
13387
  return;
13279
13388
  this._onDefinitionChanged(this._definition);
13280
13389
  if (this.autocompleteField) {
13281
- setTimeout$1(() => this.autocompleteField?.reloadItems(value));
13390
+ setTimeout(() => this.autocompleteField?.reloadItems(value));
13282
13391
  }
13283
13392
  }
13284
13393
  /* -- protected method -- */
@@ -13356,7 +13465,7 @@ class AppFormField {
13356
13465
  }
13357
13466
  updateTabIndex(timeout) {
13358
13467
  if (this.tabindex && this.tabindex !== -1) {
13359
- setTimeout$1(() => {
13468
+ setTimeout(() => {
13360
13469
  const element = asInputElement(this.matInput);
13361
13470
  if (element) {
13362
13471
  element.tabIndex = this.tabindex;
@@ -13681,16 +13790,17 @@ class HotkeysDialogComponent {
13681
13790
  this.hotkeys = Array.from(this.data);
13682
13791
  }
13683
13792
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HotkeysDialogComponent, deps: [{ token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
13684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: HotkeysDialogComponent, selector: "ng-component", ngImport: i0, template: "<table>\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;margin-bottom:1rem;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6;padding-left:0}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
13793
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: HotkeysDialogComponent, selector: "ng-component", ngImport: i0, template: "<table class=\"ion-padding\">\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{vertical-align:top;border-top:1px solid #dee2e6;padding:.75rem}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
13685
13794
  }
13686
13795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HotkeysDialogComponent, decorators: [{
13687
13796
  type: Component,
13688
- args: [{ template: "<table>\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;margin-bottom:1rem;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6;padding-left:0}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"] }]
13797
+ args: [{ template: "<table class=\"ion-padding\">\n <tbody>\n <tr *ngFor=\"let keys of hotkeys\">\n <td>{{ keys[1] | translate }}</td>\n\n <td class=\"text-right\">\n <kbd>{{ keys[0] }}</kbd>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host table{border-collapse:collapse;width:100%;color:#212529}:host th{font-weight:500;text-align:left;vertical-align:bottom;padding:.75rem;border-top:1px solid #dee2e6;border-bottom:2px solid #dee2e6}:host td{vertical-align:top;border-top:1px solid #dee2e6;padding:.75rem}:host kbd{margin-right:6px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px #c6cbd1;color:#444d56;display:inline-block;font-size:12px;line-height:10px;padding:3px 5px;vertical-align:middle}\n"] }]
13689
13798
  }], ctorParameters: () => [{ type: undefined, decorators: [{
13690
13799
  type: Inject,
13691
13800
  args: [MAT_DIALOG_DATA]
13692
13801
  }] }] });
13693
13802
 
13803
+ const APP_HOTKEYS_CONFIG = new InjectionToken('HotKeysConfig');
13694
13804
  class Hotkeys {
13695
13805
  eventManager;
13696
13806
  dialog;
@@ -13703,14 +13813,24 @@ class Hotkeys {
13703
13813
  element: this._document,
13704
13814
  preventDefault: true,
13705
13815
  };
13706
- constructor(eventManager, dialog, modalController, popoverController) {
13816
+ _dialogRef;
13817
+ _config;
13818
+ constructor(eventManager, dialog, modalController, popoverController, config) {
13707
13819
  this.eventManager = eventManager;
13708
13820
  this.dialog = dialog;
13709
13821
  this.modalController = modalController;
13710
13822
  this.popoverController = popoverController;
13711
- if (this._debug)
13712
- console.debug('[hotkeys] Starting hotkeys service... Press Shift+? to get help modal.');
13713
- this.addShortcut({ keys: 'shift.?' }).subscribe(() => this.openHelpModal());
13823
+ this._config = {
13824
+ enableHelpModal: true,
13825
+ openHelpModalShortcut: 'F1',
13826
+ ...config,
13827
+ };
13828
+ // Add shortcut to open help modal
13829
+ if (this._config.enableHelpModal) {
13830
+ this.addShortcut({ keys: this._config.openHelpModalShortcut }).subscribe(() => this.openHelpModal());
13831
+ if (this._debug)
13832
+ console.debug(`[hotkeys] Starting hotkeys service... Press ${this._config.openHelpModalShortcut} to get help modal.`);
13833
+ }
13714
13834
  // For DEV only
13715
13835
  //this._debug = !environment.production;
13716
13836
  }
@@ -13751,12 +13871,23 @@ class Hotkeys {
13751
13871
  });
13752
13872
  }
13753
13873
  openHelpModal() {
13754
- this.dialog.open(HotkeysDialogComponent, {
13874
+ if (this._dialogRef) {
13875
+ this._dialogRef.close(true);
13876
+ return;
13877
+ }
13878
+ this._dialogRef = this.dialog.open(HotkeysDialogComponent, {
13755
13879
  width: '500px',
13756
13880
  data: this._hotkeys,
13757
13881
  });
13882
+ this._dialogRef
13883
+ .afterClosed()
13884
+ .pipe(first())
13885
+ .subscribe(() => {
13886
+ // Forget the dialog ref
13887
+ this._dialogRef = null;
13888
+ });
13758
13889
  }
13759
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, deps: [{ token: i1$2.EventManager }, { token: i2$4.MatDialog }, { token: i2$1.ModalController }, { token: i2$1.PopoverController }], target: i0.ɵɵFactoryTarget.Injectable });
13890
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, deps: [{ token: i1$2.EventManager }, { token: i2$4.MatDialog }, { token: i2$1.ModalController }, { token: i2$1.PopoverController }, { token: APP_HOTKEYS_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
13760
13891
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, providedIn: 'root' });
13761
13892
  }
13762
13893
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: Hotkeys, decorators: [{
@@ -13764,7 +13895,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
13764
13895
  args: [{
13765
13896
  providedIn: 'root',
13766
13897
  }]
13767
- }], ctorParameters: () => [{ type: i1$2.EventManager }, { type: i2$4.MatDialog }, { type: i2$1.ModalController }, { type: i2$1.PopoverController }] });
13898
+ }], ctorParameters: () => [{ type: i1$2.EventManager }, { type: i2$4.MatDialog }, { type: i2$1.ModalController }, { type: i2$1.PopoverController }, { type: undefined, decorators: [{
13899
+ type: Optional
13900
+ }, {
13901
+ type: Inject,
13902
+ args: [APP_HOTKEYS_CONFIG]
13903
+ }] }] });
13768
13904
 
13769
13905
  class SharedHotkeysModule {
13770
13906
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SharedHotkeysModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -16418,7 +16554,7 @@ class TextPopover {
16418
16554
  this.enable();
16419
16555
  }
16420
16556
  ngAfterViewInit() {
16421
- setTimeout$1(() => this.form.setValue({ text: this.text }), 0);
16557
+ setTimeout(() => this.form.setValue({ text: this.text }), 0);
16422
16558
  }
16423
16559
  async onValidate(event) {
16424
16560
  await waitWhilePending(this.form);
@@ -16871,7 +17007,9 @@ class NetworkService extends StartableObservableService {
16871
17007
  return this.dataSubject.value?.clone();
16872
17008
  }
16873
17009
  set peer(peer) {
16874
- this.restart(peer);
17010
+ if (!Peer.equals(this.peer, peer)) {
17011
+ this.restart(peer);
17012
+ }
16875
17013
  }
16876
17014
  get connectionTimeout() {
16877
17015
  return this._connectionTimeout;
@@ -17013,7 +17151,7 @@ class NetworkService extends StartableObservableService {
17013
17151
  if (online) {
17014
17152
  // Call success callback (async)
17015
17153
  if (opts && opts.onRetrySuccess) {
17016
- setTimeout$1(opts.onRetrySuccess);
17154
+ setTimeout(opts.onRetrySuccess);
17017
17155
  }
17018
17156
  return true;
17019
17157
  }
@@ -19630,7 +19768,7 @@ class AccountService extends BaseGraphqlService {
19630
19768
  this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
19631
19769
  this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));
19632
19770
  // Force network to wait account service, after getting connection to the peer
19633
- this.network.on('beforeTryOnlineFinish', async (online) => {
19771
+ this.registerSubscription(this.network.on('beforeTryOnlineFinish', async (online) => {
19634
19772
  // If online, wait a full restart, because it can force offline mode
19635
19773
  if (online && (!this.started || this.isLogin())) {
19636
19774
  console.debug('[account] Force networkService.tryOnline() to wait, that graphql and account service is restarted...');
@@ -19638,7 +19776,7 @@ class AccountService extends BaseGraphqlService {
19638
19776
  if (!this.started)
19639
19777
  await this.ready();
19640
19778
  }
19641
- });
19779
+ }));
19642
19780
  }
19643
19781
  async ngOnStart() {
19644
19782
  await Promise.all([
@@ -20997,7 +21135,7 @@ class ConfigService extends BaseGraphqlService {
20997
21135
  }
20998
21136
  // Save it into local storage, for next startup
20999
21137
  if (data) {
21000
- setTimeout$1(() => this.storeLocally(data), 2000);
21138
+ setTimeout(() => this.storeLocally(data), 2000);
21001
21139
  }
21002
21140
  // If not loaded remotely: try to restore it
21003
21141
  else {
@@ -21322,7 +21460,7 @@ class PlatformService extends StartableService {
21322
21460
  }));
21323
21461
  if (this._mobile) {
21324
21462
  // Hide the splashscreen (if mobile) - after 1s - and play start sound
21325
- setTimeout$1(async () => {
21463
+ setTimeout(async () => {
21326
21464
  await SplashScreen.hide();
21327
21465
  // Play startup sound
21328
21466
  this.audioProvider.playStartupSound();
@@ -21978,7 +22116,7 @@ class ToolbarComponent {
21978
22116
  async toggleSearchBar() {
21979
22117
  this.showSearchBar = !this.showSearchBar;
21980
22118
  if (this.showSearchBar && this.searchbar) {
21981
- setTimeout$1(() => {
22119
+ setTimeout(() => {
21982
22120
  this.searchbar.setFocus();
21983
22121
  this.markForCheck();
21984
22122
  }, 300);
@@ -22030,7 +22168,7 @@ class ToolbarComponent {
22030
22168
  return;
22031
22169
  // Distinguish simple and double tap
22032
22170
  this._closeTapCount = event.tapCount;
22033
- setTimeout$1(() => {
22171
+ setTimeout(() => {
22034
22172
  // Event is obsolete (a new tap event occur)
22035
22173
  if (event.tapCount < this._closeTapCount) {
22036
22174
  // Ignore event
@@ -22052,7 +22190,7 @@ class ToolbarComponent {
22052
22190
  // Distinguish simple and double tap
22053
22191
  else {
22054
22192
  this._validateTapCount = event.tapCount;
22055
- setTimeout$1(() => {
22193
+ setTimeout(() => {
22056
22194
  // Event is obsolete (a new tap event occur)
22057
22195
  if (event.tapCount < this._validateTapCount) {
22058
22196
  // Ignore event
@@ -23959,7 +24097,7 @@ class AppImageGalleryComponent {
23959
24097
  this.onAfterEditRow.emit(row);
23960
24098
  }
23961
24099
  // Hide the toolbar, because the focus have been given to the event's origin (the edit button)
23962
- setTimeout$1(() => this.hideCardToolbar(cardToolbar), 750);
24100
+ setTimeout(() => this.hideCardToolbar(cardToolbar), 750);
23963
24101
  }
23964
24102
  showCardToolbar(cardToolbar) {
23965
24103
  const el = cardToolbar['el'];
@@ -26151,7 +26289,7 @@ class MenuService extends StartableObservableService {
26151
26289
  handler: () => {
26152
26290
  this.accountService.logout();
26153
26291
  // Back to home
26154
- setTimeout$1(() => this.navController.navigateRoot('/'), 100);
26292
+ setTimeout(() => this.navController.navigateRoot('/'), 100);
26155
26293
  },
26156
26294
  },
26157
26295
  ],
@@ -26678,7 +26816,7 @@ class MenuComponent {
26678
26816
  this.splitPane.when = value;
26679
26817
  this.detectChanges();
26680
26818
  // Propagate to the menu service
26681
- setTimeout$1(() => this.menuService.setSplitPaneShowWhen(value), 200);
26819
+ setTimeout(() => this.menuService.setSplitPaneShowWhen(value), 200);
26682
26820
  }
26683
26821
  }
26684
26822
  toggleSplitPaneShow(event) {
@@ -26718,7 +26856,7 @@ class MenuComponent {
26718
26856
  }
26719
26857
  markAsLoaded(opts) {
26720
26858
  if (this.loading) {
26721
- setTimeout$1(() => {
26859
+ setTimeout(() => {
26722
26860
  this.loading = false;
26723
26861
  if (!opts || opts.emitEvent !== false)
26724
26862
  this.markForCheck();
@@ -27943,7 +28081,7 @@ class AppAuthForm extends AppForm {
27943
28081
  const data = this.form.value;
27944
28082
  this.showPwd = false; // Hide password
27945
28083
  this.error = null; // Reset error
27946
- setTimeout$1(() => this.onSubmit.emit({
28084
+ setTimeout(() => this.onSubmit.emit({
27947
28085
  username: data.username,
27948
28086
  password: data.password,
27949
28087
  offline: data.offline,
@@ -27951,7 +28089,7 @@ class AppAuthForm extends AppForm {
27951
28089
  }
27952
28090
  register() {
27953
28091
  this.onCancel.emit();
27954
- setTimeout$1(async () => {
28092
+ setTimeout(async () => {
27955
28093
  const modal = await this.modalCtrl.create({
27956
28094
  component: RegisterModal,
27957
28095
  backdropDismiss: false,
@@ -27962,7 +28100,7 @@ class AppAuthForm extends AppForm {
27962
28100
  resetPassword() {
27963
28101
  this.onCancel.emit();
27964
28102
  const data = this.form.value;
27965
- setTimeout$1(async () => {
28103
+ setTimeout(async () => {
27966
28104
  const modal = await this.modalCtrl.create({
27967
28105
  component: AppResetPasswordModal,
27968
28106
  componentProps: {
@@ -28588,15 +28726,16 @@ class LocalSettingsValidatorService extends AppValidatorService {
28588
28726
  });
28589
28727
  }
28590
28728
  getPropertiesArray(data) {
28591
- const propertiesFormArray = new AppFormArray((value) => this.propertyValidator.getFormGroup(value, { valueMaxLength: 2000 }), (v1, v2) => this.propertyValidator.equals(v1, v2), (value) => this.propertyValidator.isEmpty(value), {
28729
+ const fromArray = new AppFormArray((value) => this.propertyValidator.getFormGroup(value, { valueMaxLength: 2000 }), (v1, v2) => this.propertyValidator.equals(v1, v2), (value) => this.propertyValidator.isEmpty(value), {
28592
28730
  allowReuseControls: false,
28593
28731
  allowEmptyArray: true,
28594
28732
  });
28595
28733
  if (data) {
28596
- const values = EntityUtils.getMapAsArray(data);
28597
- propertiesFormArray.patchValue(values);
28734
+ const values = AppPropertiesUtils.arrayFromObject(data);
28735
+ if (isNotEmptyArray(values))
28736
+ fromArray.patchValue(values);
28598
28737
  }
28599
- return propertiesFormArray;
28738
+ return fromArray;
28600
28739
  }
28601
28740
  getPropertyFormGroup(data) {
28602
28741
  return this.formBuilder.group({
@@ -29075,7 +29214,7 @@ class SettingsPage extends AppForm {
29075
29214
  // Apply inheritance
29076
29215
  this.setAccountInheritance(data.accountInheritance, { emitEvent: false });
29077
29216
  // Add a delay, because of option menu that is always opened after save!!
29078
- setTimeout$1(() => {
29217
+ setTimeout(() => {
29079
29218
  this.saving = false;
29080
29219
  this.markForCheck();
29081
29220
  }, 400);
@@ -29165,7 +29304,7 @@ class SettingsPage extends AppForm {
29165
29304
  }
29166
29305
  async getValue() {
29167
29306
  const json = this.form.value;
29168
- json.properties = EntityUtils.getPropertyArrayAsObject(json.properties);
29307
+ json.properties = AppPropertiesUtils.arrayAsObject(json.properties);
29169
29308
  // Override properties from account
29170
29309
  if (json.accountInheritance && this.isLogin) {
29171
29310
  const account = this.accountService.account;
@@ -29219,11 +29358,11 @@ class SettingsPage extends AppForm {
29219
29358
  this.cd.markForCheck();
29220
29359
  }
29221
29360
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SettingsPage, deps: [{ token: i0.Injector }, { token: PlatformService }, { token: i2$1.NavController }, { token: LocalSettingsValidatorService }, { token: i2$1.AlertController }, { token: i1$1.TranslateService }, { token: i1$3.UntypedFormBuilder }, { token: AccountService }, { token: LocalSettingsService }, { token: i0.ChangeDetectorRef }, { token: NetworkService }, { token: APP_LOCALES }, { token: APP_SETTINGS_MENU_ITEMS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
29222
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], viewQueries: [{ propertyName: "propertiesForm", first: true, predicate: ["propertiesForm"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <!-- dark mode (if mobile) -->\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2$1.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i8$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i12$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesForm, selector: "app-properties-form", inputs: ["formArrayName", "formArray", "options", "chipColor", "mobile", "appearance", "subscriptSizing", "showHintKey", "hintKeyPrefix", "showMoreButton", "showMoreButtonTitle", "showAddButton", "definitions"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29361
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.8", type: SettingsPage, selector: "page-settings", providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], viewQueries: [{ propertyName: "propertiesForm", first: true, predicate: ["propertiesForm"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n", dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2$1.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2$1.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2$1.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2$1.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2$1.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2$1.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2$1.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2$1.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2$1.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2$1.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2$1.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2$1.IonRow, selector: "ion-row" }, { kind: "component", type: i2$1.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i1$1.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i8$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i8$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i9$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i12$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "disabledEscape", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: AppPropertiesForm, selector: "app-properties-form", inputs: ["formArrayName", "formArray", "options", "chipColor", "mobile", "appearance", "subscriptSizing", "showHintKey", "hintKeyPrefix", "showMoreButton", "showMoreButtonTitle", "showAddButton", "definitions"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
29223
29362
  }
29224
29363
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: SettingsPage, decorators: [{
29225
29364
  type: Component,
29226
- args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <!-- dark mode (if mobile) -->\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
29365
+ args: [{ selector: 'page-settings', providers: [{ provide: ValidatorService, useExisting: LocalSettingsValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar\n [title]=\"'SETTINGS.TITLE' | translate\"\n color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n (onClose)=\"close($event)\"\n>\n <ion-buttons slot=\"end\">\n <!-- options menu -->\n <ion-button [matMenuTriggerFor]=\"optionsMenu\">\n <mat-icon slot=\"icon-only\">more_vert</mat-icon>\n </ion-button>\n </ion-buttons>\n</app-toolbar>\n\n<!-- Options menu -->\n<mat-menu #optionsMenu=\"matMenu\">\n <!-- Clear cache -->\n <button mat-menu-item [disabled]=\"saving\" (click)=\"clearCache($event)\">\n <mat-icon><ion-icon name=\"trash-outline\"></ion-icon></mat-icon>\n <ion-label translate>SETTINGS.BTN_CLEAR_CACHE</ion-label>\n </button>\n\n <!-- Reset -->\n <button mat-menu-item [disabled]=\"saving || !dirty\" (click)=\"cancel($event)\">\n <mat-icon><ion-icon name=\"refresh\"></ion-icon></mat-icon>\n <mat-label translate>COMMON.BTN_RESET</mat-label>\n </button>\n\n <!-- additional items -->\n @if (!loading) {\n @for (item of menuItems; track item) {\n @if (item.path) {\n <a mat-menu-item class=\"{{ item.cssClass }} {{ item.color }}\" (click)=\"executeAction($event, item)\">\n <mat-icon *ngIf=\"item.icon\"><ion-icon [name]=\"item.icon\"></ion-icon></mat-icon>\n <mat-icon *ngIf=\"item.matIcon\">{{ item.matIcon }}</mat-icon>\n <mat-label translate>{{ item.title }}</mat-label>\n </a>\n } @else if (!item.action) {\n <!-- divider -->\n <mat-divider class=\"{{ item.cssClass }} {{ item.color }}\">\n <mat-label translate>{{ item.title }}</mat-label>\n </mat-divider>\n }\n }\n }\n</mat-menu>\n\n<ion-content>\n <form [formGroup]=\"form\" novalidate (ngSubmit)=\"save($event)\" class=\"form-container\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <!-- left margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n\n <ion-col class=\"ion-padding\">\n <!-- error -->\n <ion-item *ngIf=\"error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <ion-list-header class=\"hidden-xs hidden-xxs\" translate>SETTINGS.DESCRIPTION</ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <ion-item lines=\"none\">\n <!-- account inheritance (desktop) -->\n @if (!mobile) {\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- check box (if desktop) -->\n <mat-checkbox (change)=\"setAccountInheritance($event.checked)\" [checked]=\"accountInheritance\">\n <span translate>SETTINGS.INHERIT_FROM_ACCOUNT</span>\n </mat-checkbox>\n\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n } @else {\n <!-- account inheritance (if mobile) -->\n <mat-form-field [hidden]=\"!isLogin\">\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.INHERIT_FROM_ACCOUNT</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"setAccountInheritance($event.checked)\"\n [checked]=\"accountInheritance\"\n ></mat-slide-toggle>\n <mat-error *ngIf=\"form.controls.accountInheritance.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n }\n </ion-item>\n </ion-list>\n\n @if (settings.enableDarkMode) {\n <ion-list-header><h3 translate>SETTINGS.DISPLAY_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- locale -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"language\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LOCALE' | translate }}</mat-label>\n <mat-select formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{ item.value }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.locale.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- dark mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"moon\"></ion-icon>\n\n <input matInput hidden formControlName=\"darkMode\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.BTN_DARK_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"toggleDarkMode($event.checked)\"\n [checked]=\"darkMode\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n </ion-list>\n }\n\n <!-- Network entry -->\n <ion-list-header><h3 translate>SETTINGS.NETWORK_DIVIDER</h3></ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Peer address -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"cloud\"></ion-icon>\n\n <mat-label>{{ 'SETTINGS.PEER_URL' | translate }}</mat-label>\n <input matInput type=\"text\" formControlName=\"peerUrl\" required />\n\n <button\n mat-icon-button\n type=\"button\"\n matSuffix\n (click)=\"showSelectPeerModal()\"\n tabindex=\"-1\"\n [title]=\"'SETTINGS.BTN_CHANGE_PEER' | translate\"\n >\n <mat-icon>search</mat-icon>\n </button>\n\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('required')\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerAlive')\" translate>\n SETTINGS.ERROR.PEER_NOT_REACHABLE\n </mat-error>\n <mat-error *ngIf=\"form.controls.peerUrl.hasError('peerNotCompatible')\" translate>\n SETTINGS.ERROR.PEER_NOT_COMPATIBLE\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- Offline mode (if mobile) -->\n @if (mobile) {\n <ion-item lines=\"none\">\n <mat-form-field>\n <input matInput hidden formControlName=\"accountInheritance\" type=\"text\" />\n\n <!-- slide toggle -->\n <ion-text translate>SETTINGS.OFFLINE_MODE</ion-text>\n <mat-slide-toggle\n matSuffix\n (change)=\"network.setForceOffline($event.checked)\"\n [checked]=\"network.offline\"\n ></mat-slide-toggle>\n </mat-form-field>\n </ion-item>\n }\n </ion-list>\n\n <!-- Data entry -->\n <ion-list-header>\n <h3 translate>SETTINGS.DATA_ENTRY_DIVIDER</h3>\n </ion-list-header>\n\n <ion-list [inset]=\"mobile\">\n <!-- Usage mode -->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"id-card\"></ion-icon>\n <mat-label>{{ 'SETTINGS.USAGE_MODE' | translate }}</mat-label>\n <mat-select formControlName=\"usageMode\" required>\n <mat-option *ngFor=\"let item of usageModes\" [value]=\"item\">\n {{ 'SETTINGS.USAGE_MODES.' + item | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.usageMode.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n\n <!-- lat/long format-->\n <ion-item lines=\"none\">\n <mat-form-field>\n <ion-icon matPrefix name=\"locate\"></ion-icon>\n <mat-label>{{ 'SETTINGS.LAT_LONG_FORMAT' | translate }}</mat-label>\n <mat-select formControlName=\"latLongFormat\" required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{ 'COMMON.LAT_LONG.' + item + '_PLACEHOLDER' | translate }}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"form.controls.latLongFormat.hasError('required')\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n </ion-item>\n </ion-list>\n\n <!-- fields options -->\n <app-properties-form\n #propertiesForm\n formArrayName=\"properties\"\n [definitions]=\"propertyDefinitions\"\n [options]=\"{ allowEmptyArray: true }\"\n [mobile]=\"mobile\"\n [showAddButton]=\"!mobile\"\n [showHintKey]=\"isAdmin\"\n ></app-properties-form>\n </ion-col>\n\n <!-- right margin -->\n <ion-col size=\"0\" size-lg=\"1\" size-xl=\"2\">&nbsp;</ion-col>\n </ion-row>\n </ion-grid>\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar\n (onCancel)=\"cancel()\"\n (onSave)=\"save($event)\"\n [disabled]=\"!form.dirty || saving\"\n ></app-form-buttons-bar>\n</ion-footer>\n" }]
29227
29366
  }], ctorParameters: () => [{ type: i0.Injector }, { type: PlatformService }, { type: i2$1.NavController }, { type: LocalSettingsValidatorService }, { type: i2$1.AlertController }, { type: i1$1.TranslateService }, { type: i1$3.UntypedFormBuilder }, { type: AccountService }, { type: LocalSettingsService }, { type: i0.ChangeDetectorRef }, { type: NetworkService }, { type: undefined, decorators: [{
29228
29367
  type: Inject,
29229
29368
  args: [APP_LOCALES]
@@ -29562,7 +29701,7 @@ class EntitiesTableDataSource extends TableDataSource {
29562
29701
  .deleteAll([row.currentData], this.serviceOptions)
29563
29702
  .catch((err) => this.handleServiceError(err))
29564
29703
  .then(() => {
29565
- setTimeout$1(() => {
29704
+ setTimeout(() => {
29566
29705
  // make sure row has been deleted (because GrapQHl cache remove can failed)
29567
29706
  const present = this.getRow(id) === row;
29568
29707
  if (present)
@@ -30703,7 +30842,7 @@ class AppTable {
30703
30842
  this.emitRefresh(event);
30704
30843
  // When target wait for a complete (e.g. IonRefresher)
30705
30844
  if (event?.target && event.target.complete) {
30706
- setTimeout$1(async () => {
30845
+ setTimeout(async () => {
30707
30846
  await this.waitIdle();
30708
30847
  event.target.complete();
30709
30848
  });
@@ -31236,7 +31375,7 @@ class AppTable {
31236
31375
  if (!this.table) {
31237
31376
  // DEBUG only -- alert user that table not found in template
31238
31377
  if (this.debug) {
31239
- setTimeout$1(() => !this.table &&
31378
+ setTimeout(() => !this.table &&
31240
31379
  console.warn(`[table] Missing <mat-table> in the HTML template (after waiting 500ms)! Component: ${this.constructor.name}`), 500);
31241
31380
  }
31242
31381
  // Make sure to wait the table
@@ -33386,7 +33525,7 @@ class AppAsyncTable {
33386
33525
  this.emitRefresh(event);
33387
33526
  // When target wait for a complete (e.g. IonRefresher)
33388
33527
  if (event?.target && event.target.complete) {
33389
- setTimeout$1(async () => {
33528
+ setTimeout(async () => {
33390
33529
  await this.waitIdle();
33391
33530
  event.target.complete();
33392
33531
  });
@@ -33911,7 +34050,7 @@ class AppAsyncTable {
33911
34050
  if (!this.table) {
33912
34051
  // DEBUG only -- alert user that table not found in template
33913
34052
  if (this.debug) {
33914
- setTimeout$1(() => !this.table &&
34053
+ setTimeout(() => !this.table &&
33915
34054
  console.warn(`[table] Missing <mat-table> in the HTML template (after waiting 500ms)! Component: ${this.constructor.name}`), 500);
33916
34055
  }
33917
34056
  // Make sure to wait the table
@@ -35044,7 +35183,10 @@ class AppFormContainer {
35044
35183
  logFormErrors(prefix) {
35045
35184
  if (this.debug)
35046
35185
  console.debug('[editor] Editor not valid. Checking where (forms, tables)...');
35047
- this._children?.forEach((c) => this.logChildrenErrors(c, prefix));
35186
+ this._children?.forEach((c, index) => {
35187
+ const path = this._childrenPath[index];
35188
+ this.logChildrenErrors(c, prefix, path);
35189
+ });
35048
35190
  }
35049
35191
  /* -- protected methods -- */
35050
35192
  registerSubscription(sub) {
@@ -35091,7 +35233,7 @@ class AppFormContainer {
35091
35233
  // If form provider: get delegate
35092
35234
  else if (c instanceof AppFormProvider) {
35093
35235
  if (!c.empty && !c.valid) {
35094
- c.waitDelegate({ timeout: 1000 }).then((delegate) => this.logChildrenErrors(delegate, prefix, 'provider'));
35236
+ c.waitDelegate({ timeout: 1000 }).then((delegate) => this.logChildrenErrors(delegate, prefix, path));
35095
35237
  }
35096
35238
  }
35097
35239
  // If table
@@ -35454,7 +35596,7 @@ class AppTabEditor extends AppEditor {
35454
35596
  }
35455
35597
  }
35456
35598
  // Realign tab, after a delay because the tab can be disabled when component is created
35457
- setTimeout$1(() => this.tabGroup.realignInkBar(), 500);
35599
+ setTimeout(() => this.tabGroup.realignInkBar(), 500);
35458
35600
  }));
35459
35601
  }
35460
35602
  }
@@ -35477,7 +35619,7 @@ class AppTabEditor extends AppEditor {
35477
35619
  this.tabGroup.selectedIndex = value;
35478
35620
  this.markForCheck();
35479
35621
  // Wait tab change in UI, before realign ink tab
35480
- setTimeout$1(() => this.tabGroup.realignInkBar(), 200);
35622
+ setTimeout(() => this.tabGroup.realignInkBar(), 200);
35481
35623
  }
35482
35624
  else if (!opts || opts.emitEvent !== false) {
35483
35625
  this.markForCheck();
@@ -35538,7 +35680,7 @@ class AppTabEditor extends AppEditor {
35538
35680
  console.error('[tab-page] Unknown swipe action: ' + event.type);
35539
35681
  return false;
35540
35682
  }
35541
- setTimeout$1(() => {
35683
+ setTimeout(() => {
35542
35684
  this.selectedTabIndex = selectTabIndex;
35543
35685
  this.markForCheck();
35544
35686
  });
@@ -35674,7 +35816,7 @@ class AppEntityEditorModal extends AppTabEditor {
35674
35816
  }
35675
35817
  else {
35676
35818
  // Use a timeout to avoid error 'NG0100: ExpressionChangedAfterItHasBeenCheckedError'
35677
- setTimeout$1(() => this.load());
35819
+ setTimeout(() => this.load());
35678
35820
  }
35679
35821
  }
35680
35822
  ngOnDestroy() {
@@ -36287,7 +36429,7 @@ class AccountPage extends AppForm {
36287
36429
  }));
36288
36430
  this.registerSubscription(this.configService.config.subscribe((config) => this.onConfigLoaded(config)));
36289
36431
  // Realign tab, after a delay because the tab can be disabled when component is created
36290
- setTimeout$1(() => this.tabGroup.realignInkBar(), 500);
36432
+ setTimeout(() => this.tabGroup.realignInkBar(), 500);
36291
36433
  }
36292
36434
  ngOnDestroy() {
36293
36435
  super.ngOnDestroy();
@@ -36427,7 +36569,7 @@ class AccountPage extends AppForm {
36427
36569
  this.disable();
36428
36570
  await this.accountService.save(newAccount);
36429
36571
  // Reload
36430
- setTimeout$1(() => this.onLogin(this.accountService.account), 100);
36572
+ setTimeout(() => this.onLogin(this.accountService.account), 100);
36431
36573
  this.markAsPristine();
36432
36574
  return true;
36433
36575
  }
@@ -37256,7 +37398,7 @@ class AppEntityEditor extends AppTabEditor {
37256
37398
  super.ngAfterViewInit();
37257
37399
  // Load data
37258
37400
  if (this._autoLoad) {
37259
- setTimeout$1(() => this.loadFromRoute(), this._autoLoadDelay);
37401
+ setTimeout(() => this.loadFromRoute(), this._autoLoadDelay);
37260
37402
  }
37261
37403
  }
37262
37404
  ngOnDestroy() {
@@ -37591,7 +37733,7 @@ class AppEntityEditor extends AppTabEditor {
37591
37733
  return false;
37592
37734
  }
37593
37735
  // Wait, then go back (wait is need in order to update back href is need)
37594
- await setTimeout$1(() => this.goBack(), 500);
37736
+ await setTimeout(() => this.goBack(), 500);
37595
37737
  return true;
37596
37738
  }
37597
37739
  async reload() {
@@ -38670,7 +38812,6 @@ class UserEventNotificationIcon {
38670
38812
  if (this.visible !== value) {
38671
38813
  this.visible = value;
38672
38814
  this.cd.markForCheck();
38673
- // FIXME: if zoneless timers, should use detectChanges() ?
38674
38815
  }
38675
38816
  }
38676
38817
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: UserEventNotificationIcon, deps: [{ token: APP_USER_EVENT_SERVICE, optional: true }, { token: AccountService }, { token: i2$1.PopoverController }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -38986,7 +39127,7 @@ class MessageModal {
38986
39127
  this.canSelectType = toBoolean(this.canSelectType, this.accountService.isAdmin());
38987
39128
  }
38988
39129
  ngAfterViewInit() {
38989
- setTimeout$1(() => {
39130
+ setTimeout(() => {
38990
39131
  this.form.markAsReady({ emitEvent: false });
38991
39132
  if (this.data) {
38992
39133
  this.data.type = this.data.type || MessageTypes.INBOX_MESSAGE;
@@ -39359,7 +39500,7 @@ class JobProgressionIcon extends RxState {
39359
39500
  // emit event
39360
39501
  this.jobFinished.emit(progression.id);
39361
39502
  if (this.autoRemove) {
39362
- setTimeout$1(() => {
39503
+ setTimeout(() => {
39363
39504
  this.stopListenJob(progression.id);
39364
39505
  }, this.autoRemoveDelay);
39365
39506
  }
@@ -40713,13 +40854,13 @@ class LatLongTestPage {
40713
40854
  this.form.get('enable').valueChanges.subscribe((value) => disableFormGroup.setValue(value));
40714
40855
  }
40715
40856
  ngOnInit() {
40716
- setTimeout$1(() => this.loadData(), 250);
40857
+ setTimeout(() => this.loadData(), 250);
40717
40858
  }
40718
40859
  toggleMode(value) {
40719
40860
  if (this.mode !== value) {
40720
40861
  this.mode = value;
40721
40862
  }
40722
- setTimeout$1(() => this.loadData(), 250);
40863
+ setTimeout(() => this.loadData(), 250);
40723
40864
  }
40724
40865
  // Load the form with data
40725
40866
  async loadData() {
@@ -40767,7 +40908,7 @@ class LatLongTestPage {
40767
40908
  }
40768
40909
  this.geoPositionMessage = logMessage;
40769
40910
  // Clean the log message, if same
40770
- setTimeout$1(() => {
40911
+ setTimeout(() => {
40771
40912
  if (this.geoPositionMessage === logMessage) {
40772
40913
  this.geoPositionMessage = null;
40773
40914
  }
@@ -41583,7 +41724,7 @@ class UploadFileTestingPage {
41583
41724
  return { type: HttpEventType.UploadProgress, total: file.size, loaded };
41584
41725
  }
41585
41726
  // Stop the timer
41586
- setTimeout$1(() => $stop.next(), 1000);
41727
+ setTimeout(() => $stop.next(), 1000);
41587
41728
  // Return final response
41588
41729
  return new HttpResponse({ body: { finalName: file.name } });
41589
41730
  }));
@@ -43122,7 +43263,7 @@ class ArrayFormTestPage extends AppForm {
43122
43263
  this.cd = cd;
43123
43264
  }
43124
43265
  ngOnInit() {
43125
- setTimeout$1(() => this.loadData(), 250);
43266
+ setTimeout(() => this.loadData(), 250);
43126
43267
  }
43127
43268
  ngOnDestroy() {
43128
43269
  this.subscription.unsubscribe();
@@ -43863,5 +44004,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
43863
44004
  * Generated bundle index. Do not edit.
43864
44005
  */
43865
44006
 
43866
- export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControls, emitPromiseEvent, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isControlHasInput, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isResponseEvent, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
44007
+ export { APP_ABOUT_DEVELOPERS, APP_ABOUT_PARTNERS, APP_CONFIG_OPTIONS, APP_DEBUG_DATA_SERVICE, APP_FORM_ERROR_I18N_KEYS, APP_GRAPHQL_FRAGMENTS, APP_GRAPHQL_TYPE_POLICIES, APP_HOME_BUTTONS, APP_HOTKEYS_CONFIG, APP_JOB_PROGRESSION_SERVICE, APP_LOCALES, APP_LOCAL_SETTINGS, APP_LOCAL_SETTINGS_OPTIONS, APP_LOCAL_STORAGE_TYPE_POLICIES, APP_LOGGING_SERVICE, APP_MENU_ITEMS, APP_MENU_OPTIONS, APP_NAMED_FILTER_SERVICE, APP_PROGRESS_BAR_SERVICE, APP_SETTINGS_MENU_ITEMS, APP_STORAGE, APP_STORAGE_EXPLORER_PROTECTED_KEYS, APP_TESTING_PAGES, APP_USER_EVENT_LIST_INFINITE_SCROLL_THRESHOLD, APP_USER_EVENT_SERVICE, APP_USER_SETTINGS_OPTIONS, APP_USER_TOKEN_SCOPES, AboutModal, AbstractNamedFilterService, AbstractSelectionModelPipe, AbstractTableSelectionPipe, AbstractUserEventService, Account, AccountPage, AccountService, AccountToStringPipe, AccountUtils, ActionsColumnComponent, AdminModule, AdminRoutingModule, AdminUsersModule, Alerts, AndroidOsEnvironment, AppAboutModalModule, AppAccountModule, AppAsyncTable, AppAuthForm, AppAuthModal, AppAuthModule, AppChangePasswordModule, AppChangePasswordPage, AppEditor, AppEditorOptions, AppEntityEditor, AppEntityEditorModal, AppEntityEditorModalOptions, AppEntityFormModule, AppForm, AppFormArray, AppFormButtonsBarModule, AppFormContainer, AppFormField, AppFormModule, AppFormProvider, AppFormUtils, AppGestureConfig, AppGraphQLModule, AppHelpModal, AppHomePageModule, AppIconComponent, AppIconModule, AppImageGalleryComponent, AppInMemoryTable, AppInstallUpgradeCard, AppInstallUpgradeCardModule, AppListForm, AppListFormModule, AppLoadingSpinner, AppMenuModule, AppNullForm, AppPropertiesForm, AppPropertiesFormModule, AppPropertiesTable, AppPropertiesUtils, AppPropertyUtils, AppRegisterModule, AppResetPasswordModal, AppRowField, AppSelectPeerModule, AppSettingsPageModule, AppTabEditor, AppTabEditorOptions, AppTable, AppTableModule, AppTableUtils, AppTextPopoverModule, AppUpdateOfflineModeCard, AppUpdateOfflineModeCardModule, AppValidatorService, ArrayFilterPipe, ArrayFirstPipe, ArrayFormTestPage, ArrayIncludesPipe, ArrayJoinPipe, ArrayLastPipe, ArrayLengthPipe, ArrayPluckPipe, AsAnyPipe, AsArrayPipe, AsBooleanPipe, AsFloatLabelTypePipe, AsObservablePipe, AudioProvider, AudioTestingModule, AudioTestingPage, AuthGuardService, AutoTitleDirective, AutocompleteTestPage, AutofocusDirective, BadgeDirective, BadgeNumberPipe, Base58, BaseEntityService, BaseGraphqlService, BaseGraphqlServiceOptions, BaseReferential, Beans, BooleanFormatPipe, BooleanTestPage, CORE_CONFIG_OPTIONS, CORE_TESTING_PAGES, CapitalizePipe, CellValueChangeListener, ChangePasswordForm, ChipsTestPage, Color, ColorScale, ComponentDirtyGuard, ConfigFragments, ConfigService, Configuration, CoreModule, CorePipesModule, CoreTestingModule, CryptoService, CsvUtils, DATE_ISO_PATTERN, DATE_MATCH_REGEXP, DATE_PATTERN, DATE_UNIX_MS_TIMESTAMP, DATE_UNIX_TIMESTAMP, DEFAULT_JOIN_ARRAY_VALUES_SEPARATOR, DEFAULT_JOIN_PROPERTIES_SEPARATOR, DEFAULT_MENU_SHOW_WHEN, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS, DEFAULT_PLACEHOLDER_CHAR, DEFAULT_REQUIRED_COLUMNS, DateDiffDurationPipe, DateFormatPipe, DateFormatService, DateFromNowPipe, DateShortTestPage, DateTestPage, DateTimeTestPage, DateUtils, DebugComponent, Department, DepartmentToStringPipe, DragAndDropDirective, DurationPipe, DurationTestPage, ED25519_SEED_LENGTH, EMPTY_PLACEHOLDER_CHAR, EMPTY_PLACEHOLDER_CHAR_REGEXP_GLOBAL, ENTITIES_STORAGE_KEY_PREFIX, ENVIRONMENT, EmptyArrayPipe, EntitiesAsyncTableDataSource, EntitiesStorage, EntitiesTableDataSource, Entity, EntityClass, EntityClasses, EntityFilter, EntityFilterUtils, EntityMetadataComponent, EntityStore, EntityUtils, Environment, EnvironmentHttpLoader, EnvironmentLoader, ErrorCodes, EvenPipe, FileResponse, FileService, FileSizePipe, FilesUtils, FormArrayHelper, FormArrayTestModule, FormButtonsBarComponent, FormButtonsBarToken, FormErrorPipe, FormErrorTranslatePipe, FormErrorTranslator, FormFieldValuesHolder, FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, FormGetValuePipe, GalleryTestPage, GeolocationUtils, GraphqlService, HAMMER_PRESS_TIME, HAMMER_TAP_TIME, HighlightPipe, HomePage, Hotkeys, HotkeysDialogComponent, IMAGE_DEFAULTS, IPosition, ImageAttachment, ImageAttachmentFilter, ImageAttachmentService, ImageGalleryModule, ImageGalleryTestingModule, ImageModule, ImageService, ImagesUtils, InMemoryEntitiesService, IsAllSelectedPipe, IsEmptySelectionPipe, IsLoginAccountPipe, IsMultipleSelectionPipe, IsNilOrBlankPipe, IsNilOrNaNPipe, IsNilPipe, IsNotAllSelectedPipe, IsNotEmptySelectionPipe, IsNotNilOrBlankPipe, IsNotNilOrNaNPipe, IsNotNilPipe, IsOnDeskPipe, IsOnFieldPipe, IsSelectedPipe, IsSingleSelectionPipe, JobModule, JobProgression, JobProgressionComponent, JobProgressionIcon, JobProgressionList, JobProgressionService, JobProgressionTestService, JobProgressionTestingPage, JobTestingModule, JobUtils, JsonUtils, KEYBOARD_HIDE_DELAY_MS, LAT_LONG_DEFAULT_MAX_DECIMALS, LAT_LONG_PATTERNS, LatLongFormatPipe, LatLongTestPage, LatitudeFormatPipe, LocalSettingsService, LogLevel, LogUtils, Logger, LoggingService, LoggingServiceModule, LongitudeFormatPipe, MASKS, MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING, MINIFY_ENTITY_FOR_LOCAL_STORAGE, MINIFY_ENTITY_FOR_POD, MOMENT_NO_TIME_PROPERTY, MapGetPipe, MapKeysPipe, MapValuesPipe, MaskitoPlaceholderPipe, MaskitoTestPage, MatAutocompleteConfigHolder, MatAutocompleteField, MatAutocompleteFieldUtils, MatBadgeTestPage, MatBooleanField, MatChipsField, MatColorPipe, MatCommonTestPage, MatDate, MatDateShort, MatDateTime, MatDuration, MatLatLongField, MatPaginatorI18n, MatStepperI18n, MatSwipeField, MaterialTestingModule, MathAbsPipe, MenuComponent, MenuItem, MenuItems, MenuOptions, MenuService, MenuTestingModule, MenuTestingPage, Message, MessageFilter, MessageForm, MessageModal, MessageModule, MessageService, MessageTypeList, MessageTypes, MimeTypes, ModalToolbarComponent, NETWORK_DEFAULT_CONNECTION_TIMEOUT, NamedFilter, NamedFilterFilter, NamedFilterSelector, NamedFilterSelectorTestingModule, NamedFilterSelectorTestingPage, NavActionsColumnComponent, NetworkService, NewTokenModal, NgInitDirective, NgVarDirective, NoHtmlPipe, NotEmptyArrayPipe, NumberFormatPipe, ObservableTestPage, OddPipe, OtherMenuTestingPage, PEER_URL_REGEXP, PLUS_PLACEHOLDER_CHAR_REGEXP_GLOBAL, PRIORITIZED_AUTHORITIES, PUBKEY_REGEXP, Peer, Person, PersonFilter, PersonFragments, PersonService, PersonToStringPipe, PersonUtils, PersonValidatorService, PlatformService, ProgressBarService, ProgressInterceptor, PropertiesFormTestPage, PropertiesFormTestingModule, PropertyEntity, PropertyEntityFilter, PropertyEntityValidator, PropertyFormatPipe, PropertyGetPipe, RESERVED_END_COLUMNS, RESERVED_START_COLUMNS, Referential, ReferentialFilter, ReferentialRef, ReferentialToStringPipe, ReferentialUtils, ReferentialValidatorService, RegisterConfirmPage, RegisterForm, RegisterModal, ResizableComponent, ResizableDirective, ResizableModule, RxStateModule, SCRYPT_PARAMS, SETTINGS_DISPLAY_COLUMNS, SETTINGS_FILTER, SETTINGS_PAGE_SIZE, SETTINGS_SORTED_COLUMN, SETTINGS_STORAGE_KEY, SETTINGS_TRANSIENT_PROPERTIES, SHARED_MATERIAL_TESTING_PAGES, SHARED_STORAGE_TESTING_PAGES, SHARED_TESTING_PAGES, SOCIAL_TESTING_PAGES, SPACE_PLACEHOLDER_CHAR, SPACE_PLACEHOLDER_CHAR_REGEXP_GLOBAL, SafeHtmlPipe, SelectPeerModal, SelectionLengthPipe, ServerErrorCodes, SettingsPage, SharedAsyncValidators, SharedBadgeModule, SharedDebugModule, SharedDirectivesModule, SharedFormArrayValidators, SharedFormGroupValidators, SharedHotkeysModule, SharedMatAutocompleteModule, SharedMatBooleanModule, SharedMatChipsModule, SharedMatDateTimeModule, SharedMatDurationModule, SharedMatLatLongModule, SharedMatSwipeModule, SharedMaterialModule, SharedModule, SharedNamedFilterModule, SharedPipesModule, SharedRoutingModule, SharedTestingModule, SharedTestsPage, SharedTextFormModule, SharedToolbarModule, SharedValidators, SocialErrorCodes, SocialModule, SocialModuleOptionsToken, SocialTestingModule, Software, StartableService, StatusById, StatusIds, StatusList, StorageDrivers, StorageExplorerComponent, StorageExplorerModule, StorageExplorerTestingModule, StorageExplorerTestingRoutingModule, StorageService, StrIncludesPipe, StrLengthPipe, SubMenuTabDirective, SwipeTestPage, Table2TestPage, TableSelectColumnsComponent, TableTestPage, TableTestingModule, TableValidatorService, TextForm, TextFormTestingPage, TextPopover, TextPopoverTestingModule, TextPopoverTestingPage, ToStringPipe, ToastTestingModule, ToastTestingPage, Toasts, TokenScope, ToolbarComponent, ToolbarToken, TranslatablePipe, TranslateContextPipe, TranslateContextService, TreeItemEntityUtils, UploadFile, UploadFileComponent, UploadFilePopover, UploadFileTestingModule, UploadFileTestingPage, UriUtils, UserEventModule, UserEventNotificationIcon, UserEventNotificationList, UserEventTestService, UserEventTestingModule, UserEventTestingPage, UserSettings, UserToken, UserTokenTable, UsersPage, ValueFormatPipe, accountToString, adaptValueToControl, addValueInArray, arrayDistinct, arrayResize, arraySize, asInputElement, booleanToString, canHaveFocus, capitalizeFirstLetter, chainPromises, changeCaseToUnderscore, clearValueInArray, collectByProperty, copyEntity2Form, createPromiseEvent, createPromiseEventEmitter, departmentToString, departmentsToString, disableControl, disableControls, emitPromiseEvent, enableControl, enableControls, entityToString, equals, equalsOrNil, escapeRegExp, fadeInAnimation, fadeInOutAnimation, fadeInSlowAnimation, filterFalse, filterFormErrors, filterFormErrorsByPath, filterFormErrorsByPrefix, filterNotNil, filterNumberInput, filterTrue, findParentWithClass, firstArrayValue, firstFalse, firstFalsePromise, firstNotNil, firstNotNilPromise, firstTrue, firstTruePromise, focusInput, focusNextInput, focusPreviousInput, formatLatLong, formatLatitude, formatLongitude, fromDateISOString, fromScrollEndEvent, fromUnixMsTimestamp, fromUnixTimestamp, getCaretPosition, getColorContrast, getColorShade, getColorTint, getConnectionType, getControlFromPath, getFocusableInputElements, getFormErrors, getFormValueFromEntity, getInputRangeFromCaretIndex, getInputSelectionRangesFromMask, getProperty, getPropertyByPath, getPropertyByPathAsString, getRandomImage, getRandomImageWithCredit, hexToRgb, hexToRgbArray, initArrayControlsFromValues, intersectArrays, isAndroid, isBlankString, isCapacitor, isControlHasInput, isEmptyArray, isIOS, isInputElement, isInstanceOf, isInt, isMobile, isNil, isNilOrBlank, isNilOrNaN, isNotEmptyArray, isNotNil, isNotNilBoolean, isNotNilObject, isNotNilOrBlank, isNotNilOrNaN, isNotNilString, isNumber, isNumberRange, isOnFieldMode, isProgressEvent, isResponseEvent, isStartableService, isTouchUi, isWindows, joinProperties, joinPropertiesPath, lastArrayValue, logFormErrors, markAllAsTouched, markAsUntouched, markControlAsTouched, markFormGroupAsTouched, maskitoAutoSelectByMaskPattern, maskitoPrefixPlugin, matchMedia, matchUpperCase, mergeLoadResult, mixHex, moveInputCaretToSeparator, newArray, noHtml, noTrailingSlash, notNilOrDefault, nullIfNilOrBlank, nullIfUndefined, parseLatitudeOrLongitude, propertiesPathComparator, propertyComparator, propertyPathComparator, referentialToString, referentialsToString, remove, removeAll, removeDiacritics, removeDuplicatesFromArray, removeEnd, removeValueInArray, replaceAll, resetCalculatedValue, resizeArray, rgbArrayToHex, rgbToHex, round, scrollFactory, selectInputContent, selectInputRange, setCalculatedValue, setControlEnabled, setPropertyByPath, setTabIndex, sleep, slideInAnimation, slideInOutAnimation, slideUpDownAnimation, sort, splitById, splitByProperty, startsWithUpperCase, suggestFromArray, suggestFromStringArray, tabindexComparator, testUserAgent, toBoolean, toDateISOString, toDuration, toFloat, toInt, toNotNil, toNumber, trimEmptyToNull, uncapitalizeFirstLetter, undefinedIfNull, underscoreToChangeCase, updateValueAndValidity, waitFor, waitForFalse, waitForTrue, waitIdle, waitWhilePending };
43867
44008
  //# sourceMappingURL=sumaris-net.ngx-components.mjs.map