@angular/animations 13.2.4 → 13.3.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.2.4
2
+ * @license Angular v13.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.2.4
2
+ * @license Angular v13.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.2.4
2
+ * @license Angular v13.3.0-rc.0
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -15,130 +15,130 @@ import { ɵRuntimeError, Injectable } from '@angular/core';
15
15
  * Use of this source code is governed by an MIT-style license that can be
16
16
  * found in the LICENSE file at https://angular.io/license
17
17
  */
18
- const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
18
+ const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;
19
19
  const LINE_START = '\n - ';
20
20
  function invalidTimingValue(exp) {
21
- return new ɵRuntimeError(3000 /* INVALID_TIMING_VALUE */, NG_DEV_MODE && `The provided timing value "${exp}" is invalid.`);
21
+ return new ɵRuntimeError(3000 /* INVALID_TIMING_VALUE */, NG_DEV_MODE$1 && `The provided timing value "${exp}" is invalid.`);
22
22
  }
23
23
  function negativeStepValue() {
24
- return new ɵRuntimeError(3100 /* NEGATIVE_STEP_VALUE */, NG_DEV_MODE && 'Duration values below 0 are not allowed for this animation step.');
24
+ return new ɵRuntimeError(3100 /* NEGATIVE_STEP_VALUE */, NG_DEV_MODE$1 && 'Duration values below 0 are not allowed for this animation step.');
25
25
  }
26
26
  function negativeDelayValue() {
27
- return new ɵRuntimeError(3101 /* NEGATIVE_DELAY_VALUE */, NG_DEV_MODE && 'Delay values below 0 are not allowed for this animation step.');
27
+ return new ɵRuntimeError(3101 /* NEGATIVE_DELAY_VALUE */, NG_DEV_MODE$1 && 'Delay values below 0 are not allowed for this animation step.');
28
28
  }
29
29
  function invalidStyleParams(varName) {
30
- return new ɵRuntimeError(3001 /* INVALID_STYLE_PARAMS */, NG_DEV_MODE &&
30
+ return new ɵRuntimeError(3001 /* INVALID_STYLE_PARAMS */, NG_DEV_MODE$1 &&
31
31
  `Unable to resolve the local animation param ${varName} in the given list of values`);
32
32
  }
33
33
  function invalidParamValue(varName) {
34
- return new ɵRuntimeError(3003 /* INVALID_PARAM_VALUE */, NG_DEV_MODE && `Please provide a value for the animation param ${varName}`);
34
+ return new ɵRuntimeError(3003 /* INVALID_PARAM_VALUE */, NG_DEV_MODE$1 && `Please provide a value for the animation param ${varName}`);
35
35
  }
36
36
  function invalidNodeType(nodeType) {
37
- return new ɵRuntimeError(3004 /* INVALID_NODE_TYPE */, NG_DEV_MODE && `Unable to resolve animation metadata node #${nodeType}`);
37
+ return new ɵRuntimeError(3004 /* INVALID_NODE_TYPE */, NG_DEV_MODE$1 && `Unable to resolve animation metadata node #${nodeType}`);
38
38
  }
39
39
  function invalidCssUnitValue(userProvidedProperty, value) {
40
- return new ɵRuntimeError(3005 /* INVALID_CSS_UNIT_VALUE */, NG_DEV_MODE && `Please provide a CSS unit value for ${userProvidedProperty}:${value}`);
40
+ return new ɵRuntimeError(3005 /* INVALID_CSS_UNIT_VALUE */, NG_DEV_MODE$1 && `Please provide a CSS unit value for ${userProvidedProperty}:${value}`);
41
41
  }
42
42
  function invalidTrigger() {
43
- return new ɵRuntimeError(3006 /* INVALID_TRIGGER */, NG_DEV_MODE &&
43
+ return new ɵRuntimeError(3006 /* INVALID_TRIGGER */, NG_DEV_MODE$1 &&
44
44
  'animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\'@foo\', [...]))');
45
45
  }
46
46
  function invalidDefinition() {
47
- return new ɵRuntimeError(3007 /* INVALID_DEFINITION */, NG_DEV_MODE && 'only state() and transition() definitions can sit inside of a trigger()');
47
+ return new ɵRuntimeError(3007 /* INVALID_DEFINITION */, NG_DEV_MODE$1 && 'only state() and transition() definitions can sit inside of a trigger()');
48
48
  }
49
49
  function invalidState(metadataName, missingSubs) {
50
- return new ɵRuntimeError(3008 /* INVALID_STATE */, NG_DEV_MODE &&
50
+ return new ɵRuntimeError(3008 /* INVALID_STATE */, NG_DEV_MODE$1 &&
51
51
  `state("${metadataName}", ...) must define default values for all the following style substitutions: ${missingSubs.join(', ')}`);
52
52
  }
53
53
  function invalidStyleValue(value) {
54
- return new ɵRuntimeError(3002 /* INVALID_STYLE_VALUE */, NG_DEV_MODE && `The provided style string value ${value} is not allowed.`);
54
+ return new ɵRuntimeError(3002 /* INVALID_STYLE_VALUE */, NG_DEV_MODE$1 && `The provided style string value ${value} is not allowed.`);
55
55
  }
56
56
  function invalidProperty(prop) {
57
- return new ɵRuntimeError(3009 /* INVALID_PROPERTY */, NG_DEV_MODE &&
57
+ return new ɵRuntimeError(3009 /* INVALID_PROPERTY */, NG_DEV_MODE$1 &&
58
58
  `The provided animation property "${prop}" is not a supported CSS property for animations`);
59
59
  }
60
60
  function invalidParallelAnimation(prop, firstStart, firstEnd, secondStart, secondEnd) {
61
- return new ɵRuntimeError(3010 /* INVALID_PARALLEL_ANIMATION */, NG_DEV_MODE &&
61
+ return new ɵRuntimeError(3010 /* INVALID_PARALLEL_ANIMATION */, NG_DEV_MODE$1 &&
62
62
  `The CSS property "${prop}" that exists between the times of "${firstStart}ms" and "${firstEnd}ms" is also being animated in a parallel animation between the times of "${secondStart}ms" and "${secondEnd}ms"`);
63
63
  }
64
64
  function invalidKeyframes() {
65
- return new ɵRuntimeError(3011 /* INVALID_KEYFRAMES */, NG_DEV_MODE && `keyframes() must be placed inside of a call to animate()`);
65
+ return new ɵRuntimeError(3011 /* INVALID_KEYFRAMES */, NG_DEV_MODE$1 && `keyframes() must be placed inside of a call to animate()`);
66
66
  }
67
67
  function invalidOffset() {
68
- return new ɵRuntimeError(3012 /* INVALID_OFFSET */, NG_DEV_MODE && `Please ensure that all keyframe offsets are between 0 and 1`);
68
+ return new ɵRuntimeError(3012 /* INVALID_OFFSET */, NG_DEV_MODE$1 && `Please ensure that all keyframe offsets are between 0 and 1`);
69
69
  }
70
70
  function keyframeOffsetsOutOfOrder() {
71
- return new ɵRuntimeError(3200 /* KEYFRAME_OFFSETS_OUT_OF_ORDER */, NG_DEV_MODE && `Please ensure that all keyframe offsets are in order`);
71
+ return new ɵRuntimeError(3200 /* KEYFRAME_OFFSETS_OUT_OF_ORDER */, NG_DEV_MODE$1 && `Please ensure that all keyframe offsets are in order`);
72
72
  }
73
73
  function keyframesMissingOffsets() {
74
- return new ɵRuntimeError(3202 /* KEYFRAMES_MISSING_OFFSETS */, NG_DEV_MODE && `Not all style() steps within the declared keyframes() contain offsets`);
74
+ return new ɵRuntimeError(3202 /* KEYFRAMES_MISSING_OFFSETS */, NG_DEV_MODE$1 && `Not all style() steps within the declared keyframes() contain offsets`);
75
75
  }
76
76
  function invalidStagger() {
77
- return new ɵRuntimeError(3013 /* INVALID_STAGGER */, NG_DEV_MODE && `stagger() can only be used inside of query()`);
77
+ return new ɵRuntimeError(3013 /* INVALID_STAGGER */, NG_DEV_MODE$1 && `stagger() can only be used inside of query()`);
78
78
  }
79
79
  function invalidQuery(selector) {
80
- return new ɵRuntimeError(3014 /* INVALID_QUERY */, NG_DEV_MODE &&
80
+ return new ɵRuntimeError(3014 /* INVALID_QUERY */, NG_DEV_MODE$1 &&
81
81
  `\`query("${selector}")\` returned zero elements. (Use \`query("${selector}", { optional: true })\` if you wish to allow this.)`);
82
82
  }
83
83
  function invalidExpression(expr) {
84
- return new ɵRuntimeError(3015 /* INVALID_EXPRESSION */, NG_DEV_MODE && `The provided transition expression "${expr}" is not supported`);
84
+ return new ɵRuntimeError(3015 /* INVALID_EXPRESSION */, NG_DEV_MODE$1 && `The provided transition expression "${expr}" is not supported`);
85
85
  }
86
86
  function invalidTransitionAlias(alias) {
87
- return new ɵRuntimeError(3016 /* INVALID_TRANSITION_ALIAS */, NG_DEV_MODE && `The transition alias value "${alias}" is not supported`);
87
+ return new ɵRuntimeError(3016 /* INVALID_TRANSITION_ALIAS */, NG_DEV_MODE$1 && `The transition alias value "${alias}" is not supported`);
88
88
  }
89
89
  function validationFailed(errors) {
90
- return new ɵRuntimeError(3500 /* VALIDATION_FAILED */, NG_DEV_MODE && `animation validation failed:\n${errors.map(err => err.message).join('\n')}`);
90
+ return new ɵRuntimeError(3500 /* VALIDATION_FAILED */, NG_DEV_MODE$1 && `animation validation failed:\n${errors.map(err => err.message).join('\n')}`);
91
91
  }
92
92
  function buildingFailed(errors) {
93
- return new ɵRuntimeError(3501 /* BUILDING_FAILED */, NG_DEV_MODE && `animation building failed:\n${errors.map(err => err.message).join('\n')}`);
93
+ return new ɵRuntimeError(3501 /* BUILDING_FAILED */, NG_DEV_MODE$1 && `animation building failed:\n${errors.map(err => err.message).join('\n')}`);
94
94
  }
95
95
  function triggerBuildFailed(name, errors) {
96
- return new ɵRuntimeError(3404 /* TRIGGER_BUILD_FAILED */, NG_DEV_MODE &&
96
+ return new ɵRuntimeError(3404 /* TRIGGER_BUILD_FAILED */, NG_DEV_MODE$1 &&
97
97
  `The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.map(err => err.message).join('\n - ')}`);
98
98
  }
99
99
  function animationFailed(errors) {
100
- return new ɵRuntimeError(3502 /* ANIMATION_FAILED */, NG_DEV_MODE &&
100
+ return new ɵRuntimeError(3502 /* ANIMATION_FAILED */, NG_DEV_MODE$1 &&
101
101
  `Unable to animate due to the following errors:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
102
102
  }
103
103
  function registerFailed(errors) {
104
- return new ɵRuntimeError(3503 /* REGISTRATION_FAILED */, NG_DEV_MODE &&
104
+ return new ɵRuntimeError(3503 /* REGISTRATION_FAILED */, NG_DEV_MODE$1 &&
105
105
  `Unable to build the animation due to the following errors: ${errors.map(err => err.message).join('\n')}`);
106
106
  }
107
107
  function missingOrDestroyedAnimation() {
108
- return new ɵRuntimeError(3300 /* MISSING_OR_DESTROYED_ANIMATION */, NG_DEV_MODE && 'The requested animation doesn\'t exist or has already been destroyed');
108
+ return new ɵRuntimeError(3300 /* MISSING_OR_DESTROYED_ANIMATION */, NG_DEV_MODE$1 && 'The requested animation doesn\'t exist or has already been destroyed');
109
109
  }
110
110
  function createAnimationFailed(errors) {
111
- return new ɵRuntimeError(3504 /* CREATE_ANIMATION_FAILED */, NG_DEV_MODE &&
111
+ return new ɵRuntimeError(3504 /* CREATE_ANIMATION_FAILED */, NG_DEV_MODE$1 &&
112
112
  `Unable to create the animation due to the following errors:${errors.map(err => err.message).join('\n')}`);
113
113
  }
114
114
  function missingPlayer(id) {
115
- return new ɵRuntimeError(3301 /* MISSING_PLAYER */, NG_DEV_MODE && `Unable to find the timeline player referenced by ${id}`);
115
+ return new ɵRuntimeError(3301 /* MISSING_PLAYER */, NG_DEV_MODE$1 && `Unable to find the timeline player referenced by ${id}`);
116
116
  }
117
117
  function missingTrigger(phase, name) {
118
- return new ɵRuntimeError(3302 /* MISSING_TRIGGER */, NG_DEV_MODE &&
118
+ return new ɵRuntimeError(3302 /* MISSING_TRIGGER */, NG_DEV_MODE$1 &&
119
119
  `Unable to listen on the animation trigger event "${phase}" because the animation trigger "${name}" doesn\'t exist!`);
120
120
  }
121
121
  function missingEvent(name) {
122
- return new ɵRuntimeError(3303 /* MISSING_EVENT */, NG_DEV_MODE &&
122
+ return new ɵRuntimeError(3303 /* MISSING_EVENT */, NG_DEV_MODE$1 &&
123
123
  `Unable to listen on the animation trigger "${name}" because the provided event is undefined!`);
124
124
  }
125
125
  function unsupportedTriggerEvent(phase, name) {
126
- return new ɵRuntimeError(3400 /* UNSUPPORTED_TRIGGER_EVENT */, NG_DEV_MODE &&
126
+ return new ɵRuntimeError(3400 /* UNSUPPORTED_TRIGGER_EVENT */, NG_DEV_MODE$1 &&
127
127
  `The provided animation trigger event "${phase}" for the animation trigger "${name}" is not supported!`);
128
128
  }
129
129
  function unregisteredTrigger(name) {
130
- return new ɵRuntimeError(3401 /* UNREGISTERED_TRIGGER */, NG_DEV_MODE && `The provided animation trigger "${name}" has not been registered!`);
130
+ return new ɵRuntimeError(3401 /* UNREGISTERED_TRIGGER */, NG_DEV_MODE$1 && `The provided animation trigger "${name}" has not been registered!`);
131
131
  }
132
132
  function triggerTransitionsFailed(errors) {
133
- return new ɵRuntimeError(3402 /* TRIGGER_TRANSITIONS_FAILED */, NG_DEV_MODE &&
133
+ return new ɵRuntimeError(3402 /* TRIGGER_TRANSITIONS_FAILED */, NG_DEV_MODE$1 &&
134
134
  `Unable to process animations due to the following failed trigger transitions\n ${errors.map(err => err.message).join('\n')}`);
135
135
  }
136
136
  function triggerParsingFailed(name, errors) {
137
- return new ɵRuntimeError(3403 /* TRIGGER_PARSING_FAILED */, NG_DEV_MODE &&
137
+ return new ɵRuntimeError(3403 /* TRIGGER_PARSING_FAILED */, NG_DEV_MODE$1 &&
138
138
  `Animation parsing for the ${name} trigger have failed:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
139
139
  }
140
140
  function transitionFailed(name, errors) {
141
- return new ɵRuntimeError(3505 /* TRANSITION_FAILED */, NG_DEV_MODE &&
141
+ return new ɵRuntimeError(3505 /* TRANSITION_FAILED */, NG_DEV_MODE$1 &&
142
142
  `@${name} has failed due to:\n ${errors.map(err => err.message).join('\n- ')}`);
143
143
  }
144
144
 
@@ -372,9 +372,9 @@ class NoopAnimationDriver {
372
372
  return new NoopAnimationPlayer(duration, delay);
373
373
  }
374
374
  }
375
- NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
376
- NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NoopAnimationDriver });
377
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.4", ngImport: i0, type: NoopAnimationDriver, decorators: [{
375
+ NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0-rc.0", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
376
+ NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0-rc.0", ngImport: i0, type: NoopAnimationDriver });
377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0-rc.0", ngImport: i0, type: NoopAnimationDriver, decorators: [{
378
378
  type: Injectable
379
379
  }] });
380
380
  /**
@@ -672,6 +672,39 @@ function computeStyle(element, prop) {
672
672
  return window.getComputedStyle(element)[prop];
673
673
  }
674
674
 
675
+ /**
676
+ * @license
677
+ * Copyright Google LLC All Rights Reserved.
678
+ *
679
+ * Use of this source code is governed by an MIT-style license that can be
680
+ * found in the LICENSE file at https://angular.io/license
681
+ */
682
+ const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
683
+ function createListOfWarnings(warnings) {
684
+ const LINE_START = '\n - ';
685
+ return `${LINE_START}${warnings.filter(Boolean).map(warning => warning).join(LINE_START)}`;
686
+ }
687
+ function warnValidation(warnings) {
688
+ NG_DEV_MODE && console.warn(`animation validation warnings:${createListOfWarnings(warnings)}`);
689
+ }
690
+ function warnTriggerBuild(name, warnings) {
691
+ NG_DEV_MODE &&
692
+ console.warn(`The animation trigger "${name}" has built with the following warnings:${createListOfWarnings(warnings)}`);
693
+ }
694
+ function warnRegister(warnings) {
695
+ NG_DEV_MODE &&
696
+ console.warn(`Animation built with the following warnings:${createListOfWarnings(warnings)}`);
697
+ }
698
+ function triggerParsingWarnings(name, warnings) {
699
+ NG_DEV_MODE &&
700
+ console.warn(`Animation parsing for the ${name} trigger presents the following warnings:${createListOfWarnings(warnings)}`);
701
+ }
702
+ function pushUnrecognizedPropertiesWarning(warnings, props) {
703
+ if (ngDevMode && props.length) {
704
+ warnings.push(`The provided CSS properties are not recognized properties supported for animations: ${props.join(', ')}`);
705
+ }
706
+ }
707
+
675
708
  /**
676
709
  * @license
677
710
  * Copyright Google LLC All Rights Reserved.
@@ -795,18 +828,22 @@ const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
795
828
  *
796
829
  * Otherwise an error will be thrown.
797
830
  */
798
- function buildAnimationAst(driver, metadata, errors) {
799
- return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
831
+ function buildAnimationAst(driver, metadata, errors, warnings) {
832
+ return new AnimationAstBuilderVisitor(driver).build(metadata, errors, warnings);
800
833
  }
801
834
  const ROOT_SELECTOR = '';
802
835
  class AnimationAstBuilderVisitor {
803
836
  constructor(_driver) {
804
837
  this._driver = _driver;
805
838
  }
806
- build(metadata, errors) {
839
+ build(metadata, errors, warnings) {
807
840
  const context = new AnimationAstBuilderContext(errors);
808
841
  this._resetContextStyleTimingState(context);
809
- return visitDslNode(this, normalizeAnimationEntry(metadata), context);
842
+ const ast = visitDslNode(this, normalizeAnimationEntry(metadata), context);
843
+ if (context.unsupportedCSSPropertiesFound.size) {
844
+ pushUnrecognizedPropertiesWarning(warnings, [...context.unsupportedCSSPropertiesFound.keys()]);
845
+ }
846
+ return ast;
810
847
  }
811
848
  _resetContextStyleTimingState(context) {
812
849
  context.currentQuerySelector = ROOT_SELECTOR;
@@ -1019,7 +1056,8 @@ class AnimationAstBuilderVisitor {
1019
1056
  return;
1020
1057
  Object.keys(tuple).forEach(prop => {
1021
1058
  if (!this._driver.validateStyleProperty(prop)) {
1022
- context.errors.push(invalidProperty(prop));
1059
+ delete tuple[prop];
1060
+ context.unsupportedCSSPropertiesFound.add(prop);
1023
1061
  return;
1024
1062
  }
1025
1063
  const collectedStyles = context.collectedStyles[context.currentQuerySelector];
@@ -1186,6 +1224,7 @@ class AnimationAstBuilderContext {
1186
1224
  this.currentTime = 0;
1187
1225
  this.collectedStyles = {};
1188
1226
  this.options = null;
1227
+ this.unsupportedCSSPropertiesFound = new Set();
1189
1228
  }
1190
1229
  }
1191
1230
  function consumeOffset(styles) {
@@ -2055,10 +2094,14 @@ class Animation {
2055
2094
  constructor(_driver, input) {
2056
2095
  this._driver = _driver;
2057
2096
  const errors = [];
2058
- const ast = buildAnimationAst(_driver, input, errors);
2097
+ const warnings = [];
2098
+ const ast = buildAnimationAst(_driver, input, errors, warnings);
2059
2099
  if (errors.length) {
2060
2100
  throw validationFailed(errors);
2061
2101
  }
2102
+ if (warnings.length) {
2103
+ warnValidation(warnings);
2104
+ }
2062
2105
  this._animationAst = ast;
2063
2106
  }
2064
2107
  buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {
@@ -2318,11 +2361,15 @@ class TimelineAnimationEngine {
2318
2361
  }
2319
2362
  register(id, metadata) {
2320
2363
  const errors = [];
2321
- const ast = buildAnimationAst(this._driver, metadata, errors);
2364
+ const warnings = [];
2365
+ const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
2322
2366
  if (errors.length) {
2323
2367
  throw registerFailed(errors);
2324
2368
  }
2325
2369
  else {
2370
+ if (warnings.length) {
2371
+ warnRegister(warnings);
2372
+ }
2326
2373
  this._animations[id] = ast;
2327
2374
  }
2328
2375
  }
@@ -3992,10 +4039,14 @@ class AnimationEngine {
3992
4039
  let trigger = this._triggerCache[cacheKey];
3993
4040
  if (!trigger) {
3994
4041
  const errors = [];
3995
- const ast = buildAnimationAst(this._driver, metadata, errors);
4042
+ const warnings = [];
4043
+ const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
3996
4044
  if (errors.length) {
3997
4045
  throw triggerBuildFailed(name, errors);
3998
4046
  }
4047
+ if (warnings.length) {
4048
+ warnTriggerBuild(name, warnings);
4049
+ }
3999
4050
  trigger = buildTrigger(name, ast, this._normalizer);
4000
4051
  this._triggerCache[cacheKey] = trigger;
4001
4052
  }