@everymatrix/cashier-method-details 1.28.2 → 1.28.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everymatrix/cashier-method-details",
3
- "version": "1.28.2",
3
+ "version": "1.28.4",
4
4
  "main": "index.js",
5
5
  "svelte": "src/index.ts",
6
6
  "scripts": {
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "d958fcf980942e498f37b94d506a1b27a5169aa4"
38
+ "gitHead": "1bfc13085b6829695a52b1569af671db1c024e41"
39
39
  }
@@ -21,7 +21,7 @@
21
21
  name: string;
22
22
  label: string;
23
23
  description: string;
24
- type: string;
24
+ type: FieldTypes;
25
25
  defaultValue: any;
26
26
  format: string;
27
27
  placeholder: string;
@@ -49,7 +49,7 @@
49
49
  this.name = element.Name || null;
50
50
  this.label = element.Label || null;
51
51
  this.description = element.Description || null;
52
- this.type = element.Type || null;
52
+ this.type = fieldTypeMap.get(element.Type) || null;
53
53
  this.defaultValue = this.calcDefaultValue(element);
54
54
  this.format = element.Format || null;
55
55
  this.placeholder = element.Placeholder || null;
@@ -88,7 +88,11 @@
88
88
  return this.description
89
89
  }
90
90
  }
91
-
91
+ const mapReducer = (arr, [keys, val]) => [
92
+ ...arr,
93
+ ...(Array.isArray(keys) ? [...keys.map(key => [key, val])] : [[keys, val]]
94
+ )
95
+ ];
92
96
  enum TxnType {
93
97
  Deposit='Deposit',
94
98
  Withdraw='Withdraw'
@@ -101,6 +105,11 @@
101
105
  RedirectWithRetry = 'Redirect'
102
106
  }
103
107
 
108
+ const redirectModeMap = new Map([
109
+ [['Default', 0], RedirectionModeStringEnum.Default],
110
+ [['Redirect', 1], RedirectionModeStringEnum.RedirectWithRetry]
111
+ ].reduce(mapReducer, []));
112
+
104
113
  enum FieldTypes {
105
114
  Unknown ='Unknown',
106
115
  Text ='Text',
@@ -121,6 +130,27 @@
121
130
  Html = 'Html',
122
131
  QRCode = 'QR'
123
132
  }
133
+
134
+ const fieldTypeMap = new Map([
135
+ [['Unknown', 0], FieldTypes.Unknown],
136
+ [['Text', 1], FieldTypes.Text],
137
+ [['Boolean', 2], FieldTypes.Boolean],
138
+ [['Number', 3], FieldTypes.Number],
139
+ [['Money', 4], FieldTypes.Money],
140
+ [['DateTime', 5], FieldTypes.DateTime],
141
+ [['Lookup', 6], FieldTypes.Lookup],
142
+ [['IpAddress', 7], FieldTypes.IpAddress],
143
+ [['Date', 8], FieldTypes.Date],
144
+ [['Time', 9], FieldTypes.Time],
145
+ [['LookupCollection', 10], FieldTypes.LookupCollection],
146
+ [['Hidden', 11], FieldTypes.Hidden],
147
+ [['Label', 12], FieldTypes.Label],
148
+ [['Password', 13], FieldTypes.Password],
149
+ [['Link', 14], FieldTypes.Link],
150
+ [['Image', 15], FieldTypes.Image],
151
+ [['Html', 19], FieldTypes.Html],
152
+ [['QR', 20], FieldTypes.QRCode]
153
+ ].reduce(mapReducer, []))
124
154
  export let endpoint: string;
125
155
  export let session: string;
126
156
  export let lang: string = 'en';
@@ -175,6 +205,7 @@
175
205
  let maxLookupHeight: number;
176
206
  let editedAmount: number;
177
207
  let errorResponseCode: string;
208
+ let isDisabled: boolean;
178
209
 
179
210
  $: endpoint && session && selectedpaymentmethodname && currency && reinitMethod();
180
211
  $: clientstyling && customStylingContainer && setClientStyling();
@@ -220,6 +251,7 @@
220
251
  }
221
252
  })
222
253
  }
254
+
223
255
  const createDatePicker = () => {
224
256
  const dateOptions = {
225
257
  [FieldTypes.Time]: {
@@ -248,7 +280,7 @@
248
280
  }
249
281
  flatpickr(flatpickrEl, dateOptions[el.dataset.type])
250
282
  });
251
- }
283
+ }
252
284
  const setActiveLanguage = ():void => {
253
285
  setLocale(lang);
254
286
  }
@@ -360,7 +392,7 @@
360
392
  showError[openedLookup] = true;
361
393
  validateField(fields.find(field => field.name === openedLookup));
362
394
  }
363
- if(!e.composedPath().includes(clickedElem)){
395
+ if (!e.composedPath().includes(clickedElem)) {
364
396
  openedLookup = null;
365
397
  }
366
398
  }
@@ -374,20 +406,28 @@
374
406
  }
375
407
  event.stopPropagation();
376
408
  clickedElem = event.composedPath()[0]
377
- const clickY = clickedElem.getBoundingClientRect().y;
409
+ const innerContainer = clickedElem.getBoundingClientRect();
410
+ const outerContainer = customStylingContainer.getBoundingClientRect()
411
+ const clickY = innerContainer.y;
378
412
  const minLookupHeight = 200;
379
- const lookupMargin = 55;
380
413
  openLookupTop = (window.innerHeight - clickY) < minLookupHeight;
381
- maxLookupHeight = openLookupTop ? clickY - minLookupHeight : window.innerHeight - clickY - lookupMargin;
414
+ const topSpace = innerContainer.top - outerContainer.top - innerContainer.height;
415
+ const bottomSpace = outerContainer.bottom - innerContainer.bottom - innerContainer.height;
416
+ const dropdownSizeBottom = !openLookupTop && bottomSpace < 70 ? minLookupHeight - 50 : bottomSpace;
417
+ maxLookupHeight = openLookupTop ? topSpace : dropdownSizeBottom;
382
418
  openedLookup = name
383
419
  }
384
420
 
385
421
  const prepareTxn = () => {
422
+ if (isDisabled) {
423
+ return;
424
+ }
386
425
  isProcessingTxn = true;
387
426
  const url:URL = new URL(`${endpoint}/v1/player/${customerid}/payment/GetPaymentPrepare`);
388
427
  const headers = new Headers();
389
428
  headers.append("accept", "application/json");
390
429
  headers.append("Content-Type", "application/json");
430
+ toggleDisableActionOnPage();
391
431
  const requestParams:RequestInit = {
392
432
  method: "POST",
393
433
  mode: "cors",
@@ -417,6 +457,7 @@
417
457
  xPaymentSessionToken = data.XPaymentSessionToken;
418
458
  isProcessingTxn = false;
419
459
  showConfirmModal = true;
460
+ toggleDisableActionOnPage();
420
461
  })
421
462
  }
422
463
 
@@ -437,6 +478,10 @@
437
478
  hidePaymentDetails()
438
479
  }
439
480
 
481
+ const toggleDisableActionOnPage = () => {
482
+ window.postMessage({type: 'ToggleDisableActionOnPage', disable: isProcessingTxn})
483
+ }
484
+
440
485
  const hidePaymentDetails = () => {
441
486
  dispatchEvent(new CustomEvent('hidePaymentDetails', {
442
487
  detail: { hideMethodDetails: mobileView },
@@ -467,6 +512,7 @@
467
512
  const headers = new Headers();
468
513
  headers.append("accept", "application/json");
469
514
  headers.append("Content-Type", "application/json");
515
+ toggleDisableActionOnPage();
470
516
  const requestParams:RequestInit = {
471
517
  method: "POST",
472
518
  mode: "cors",
@@ -484,12 +530,13 @@
484
530
  }
485
531
  xPaymentSessionToken = data.XPaymentSessionToken;
486
532
  redirectUrl = data.RedirectUrl;
487
- redirectMode = data.RedirectionMode;
533
+ redirectMode = redirectModeMap.get(data.RedirectionMode);
488
534
  isProcessingTxn = false;
535
+ toggleDisableActionOnPage();
489
536
  if (!redirectUrl) {
490
537
  showReceiptPage = true;
491
538
  }
492
- if (data.RedirectionMode === RedirectionModeStringEnum.RedirectWithRetry) {
539
+ if (redirectMode === RedirectionModeStringEnum.RedirectWithRetry) {
493
540
  windowRedirect = window.open(data.RedirectUrl, '_blank');
494
541
  showRedirectNotification = !!windowRedirect;
495
542
  if (!windowRedirect) {
@@ -516,7 +563,12 @@
516
563
 
517
564
  const onLookUpChanged = (field, value) => {
518
565
  prepareFields[field.name] = value;
519
- validateField(field);
566
+ fields.filter(el => el.correlationFieldName).forEach(el => validateField(el));
567
+ }
568
+
569
+ const getValueByFieldName = (values:any[], name:string):string => {
570
+ const fieldValue = name ? values.find(el => el.Name === name).Value : '';
571
+ return fieldValue;
520
572
  }
521
573
 
522
574
  const showField = (field) => {
@@ -608,11 +660,12 @@
608
660
 
609
661
  const validateField = (field) => {
610
662
  const value = prepareFields[field.name]
611
- fieldValidation[field.name] = emptyFieldError(field, value) || patternMatchesError(field, value);
663
+ fieldValidation[field.name] = showField(field) ? (emptyFieldError(field, value) || patternMatchesError(field, value)) : '';
612
664
  }
613
665
 
614
666
  const isSubmitDisabled = (amountError, fieldValidation) => {
615
- return !!amountError || Object.values(fieldValidation).some(error => !!error)
667
+ isDisabled = !!amountError || Object.values(fieldValidation).some(error => !!error);
668
+ return isDisabled;
616
669
  }
617
670
 
618
671
  </script>
@@ -711,14 +764,14 @@
711
764
 
712
765
  {:else if field.type === FieldTypes.Lookup}
713
766
  <div class="CustomSelect">
714
- <div class="Selected" id="{index}" on:click="{(e) => showLookup(e, field.name)}">{prepareFields[field.name] || ''}</div>
767
+ <div class="Selected" id="{index}" on:click="{(e) => showLookup(e, field.name)}"> {getValueByFieldName(field.values, prepareFields[field.name])}</div>
715
768
  <div class="OptionList"
716
769
  class:Opened={openedLookup === field.name}
717
770
  class:Top={openLookupTop}
718
771
  style="max-height: {`${maxLookupHeight}px`};"
719
772
  >
720
773
  {#each field.values as value}
721
- <div on:click="{() => {prepareFields[field.name] = value.Name; fields = fields}}">
774
+ <div on:click="{() => {onLookUpChanged(field, value.Name); fields = fields}}">
722
775
  <span>{value.Value}</span>
723
776
  </div>
724
777
  {/each}
@@ -859,10 +912,10 @@
859
912
  background: transparent;
860
913
  }
861
914
  ::-webkit-scrollbar-thumb {
862
- background: var(--emw--color-gray-100, #E8E9EB);
915
+ background: var(--mmw--color-grey-105, #E8E9EB);
863
916
  }
864
917
  ::-webkit-scrollbar-thumb:hover {
865
- background: var(--emw--color-gray-300, #666);
918
+ background: var(--mmw--color-grey-290, #666);
866
919
  }
867
920
 
868
921
  input::-webkit-outer-spin-button,
@@ -876,6 +929,7 @@
876
929
  }
877
930
  .CashierMethodDetails {
878
931
  width: 100%;
932
+ height: 100%;
879
933
  }
880
934
  .ReceiptPage {
881
935
  background-color: var(--emw--color-gray-transparency-100, rgb(255, 255, 255));
@@ -888,7 +942,7 @@
888
942
  position: relative;
889
943
  display: flex;
890
944
  flex-direction: column;
891
- gap: 5px;
945
+ gap: var(--mmw--spacing-2x-small-plus, 5px);
892
946
  &:has(.RedirectionNotification) form {
893
947
  visibility: hidden;
894
948
  }
@@ -897,12 +951,12 @@
897
951
  align-items: center;
898
952
  display: flex;
899
953
  height: 50px;
900
- border-bottom: 1px solid var(--emw--color-gray-100, #E8E9EB);
954
+ border-bottom: 1px solid var(--mmw--color-grey-105, #E8E9EB);
901
955
 
902
956
  .SelectedLogoDescription {
903
- color: var(--emw--color-black, #111);
957
+ color: var(--mmw--color-grey-10, #111);
904
958
  font-size: var(--emw--font-size-small, 14px);
905
- margin: 7px 5px 7px 7px;
959
+ margin: var(--mmw--spacing-x-small-minus, 7px) var(--mmw--spacing-2x-small-plus, 5px) var(--mmw--spacing-x-small-minus, 7px) var(--mmw--spacing-x-small-minus, 7px);
906
960
  word-break: break-word;
907
961
  }
908
962
 
@@ -910,9 +964,9 @@
910
964
  width: 56px;
911
965
  height: 32px;
912
966
  flex-shrink: 0;
913
- background: var(--emw--color-background, #FFF);
914
- border: 1px solid var(--emw--color-gray-100, #E8E9EB);
915
- border-radius: var(--emw--border-radius-large, 6px);
967
+ background: var(--emw--color-background, #fff);
968
+ border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
969
+ border-radius: var(--mmw--border-radius-medium-plus, 6px);
916
970
 
917
971
  img {
918
972
  max-height: 32px;
@@ -922,15 +976,15 @@
922
976
  .ChangePaymeth {
923
977
  margin-left: auto;
924
978
  cursor: pointer;
925
- color: var(--emw--color-black, #111);
979
+ color: var(--mmw--color-grey-10, #111);
926
980
  font-size: var(--emw--font-size-small, 14px);
927
981
  text-decoration-line: underline;
928
982
  }
929
983
  }
930
984
  .SelectedMethodDescription {
931
- color: var(--emw--color-gray-300, #666);
985
+ color: var(--mmw--color-grey-290, #666);
932
986
  font-size: var(--emw--font-size-x-small, 12px);
933
- margin: 10px 0 5px;
987
+ margin: var(--emw--spacing-small-minus, 10px) 0 var(--mmw--spacing-2x-small-plus, 5px);
934
988
  line-height: var(--emw--font-size-x-small, 12px);
935
989
  white-space: pre-line;
936
990
  }
@@ -942,7 +996,7 @@
942
996
  flex-direction: column;
943
997
  align-items: center;
944
998
  justify-content: center;
945
- gap: 20px;
999
+ gap: var(--emw--spacing-large, 20px);
946
1000
  .RedirectionClose {
947
1001
  display: flex;
948
1002
  width: 234px;
@@ -955,21 +1009,21 @@
955
1009
  text-align: center;
956
1010
  font-size: var(--emw--font-size-x-small, 12px);
957
1011
  font-style: normal;
958
- font-weight: 500;
1012
+ font-weight: var(--emw--font-weight-semibold, 500);
959
1013
  line-height: normal;
960
1014
  text-transform: uppercase;
961
- border-radius: 4px;
1015
+ border-radius: var(--emw--border-radius-medium, 4px);
962
1016
  background: var(--emw--color-primary, #7EC51E);
963
1017
  }
964
1018
  .RedirectionTitle {
965
- color: var(--emw--color-black, #111);
1019
+ color: var(--mmw--color-grey-10, #111);
966
1020
  font-size: var(--emw--font-size-x-small, 12px);
967
1021
  font-style: normal;
968
1022
  text-transform: none;
969
- font-weight: var(--emw--font-weight-bold, 600);
1023
+ font-weight: var(--mmw--font-weight-semibold-plus, 600);
970
1024
  }
971
1025
  .RedirectionMessage {
972
- color: var(--emw--color-gray-300, #666);
1026
+ color: var(--mmw--color-grey-290, #666);
973
1027
  font-size: var(--emw--font-size-x-small, 12px);
974
1028
  font-style: normal;
975
1029
  text-transform: none;
@@ -997,10 +1051,10 @@
997
1051
  }
998
1052
  .FieldWrapper {
999
1053
  background-color: var(--emw--color-gray-transparency-100, rgba(255, 255, 255, 1));
1000
- border-radius: 6px;
1054
+ border-radius: var(--mmw--border-radius-medium-plus, 6px);
1001
1055
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
1002
- padding: 0 15px 15px;
1003
- margin-bottom: 10px;
1056
+ padding: 0 var(--emw--spacing-medium, 15px) var(--emw--spacing-medium, 15px);
1057
+ margin-bottom: var(--emw--spacing-small-minus, 10px);
1004
1058
  &:has(.QRCode, .Label) {
1005
1059
  box-shadow: none;
1006
1060
  background: transparent;
@@ -1032,22 +1086,22 @@
1032
1086
  .Alert {
1033
1087
  color: var(--emw--color-error, #FE0101);
1034
1088
  font-size: var(--emw--font-size-x-small, 12px);
1035
- margin: 5px 0 0 2px;
1089
+ margin: var(--mmw--spacing-2x-small-plus, 5px) 0 0 var(--emw--spacing-3x-small, 2px);
1036
1090
  line-height: var(--emw--font-size-x-small, 12px);
1037
1091
  }
1038
1092
  .AmountLimits {
1039
- color: var(--emw--color-gray-300, #666);
1093
+ color: var(--mmw--color-grey-290, #666);
1040
1094
  font-size: var(--emw--font-size-x-small, 12px);
1041
- margin: 5px 0 0 2px;
1095
+ margin: var(--mmw--spacing-2x-small-plus, 5px) 0 0 var(--emw--spacing-3x-small, 2px);
1042
1096
  line-height: var(--emw--font-size-x-small, 12px);
1043
1097
  }
1044
1098
  input, .Selected {
1045
- border: 1px solid var(--emw--color-gray-100, #E8E9EB);
1099
+ border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1046
1100
  border-radius: var(--emw--border-radius-medium, 4px);
1047
1101
  height: $input-height;
1048
1102
  line-height: var(--emw--size-small, 14px);
1049
- color: var(--emw--color-black, #111);
1050
- padding: 0 15px;
1103
+ color: var(--mmw--color-grey-10, #111);
1104
+ padding: 0 var(--emw--spacing-medium, 15px);
1051
1105
  font-style: inherit;
1052
1106
  font-family: inherit;
1053
1107
  &:focus {
@@ -1056,20 +1110,20 @@
1056
1110
  }
1057
1111
 
1058
1112
  label {
1059
- color: var(--emw--color-black, #111);
1113
+ color: var(--mmw--color-grey-10, #111);
1060
1114
  font-size: var(--emw--size-small, 14px);
1061
- margin-top: 7px;
1115
+ margin-top: var(--mmw--spacing-x-small-minus, 7px);
1062
1116
  line-height: 27px;
1063
1117
  span.Required:before {
1064
1118
  content: '*';
1065
1119
  display: inline-block;
1066
- margin-right: 2px;
1120
+ margin-right: var(--emw--spacing-3x-small, 2px);
1067
1121
  }
1068
1122
  }
1069
1123
  .Description {
1070
- color: var(--emw--color-gray-300, #666);
1124
+ color: var(--mmw--color-grey-290, #666);
1071
1125
  font-size: var(--emw--font-size-x-small, 12px);
1072
- margin: 0 0 5px 2px;
1126
+ margin: 0 0 var(--mmw--spacing-2x-small-plus, 5px) var(--emw--spacing-3x-small, 2px);
1073
1127
  line-height: var(--emw--font-size-x-small, 12px);
1074
1128
  }
1075
1129
  .PrimaryButton {
@@ -1077,37 +1131,37 @@
1077
1131
  text-align: center;
1078
1132
  font-size: var(--emw--font-size-x-small, 12px);
1079
1133
  font-style: normal;
1080
- font-weight: 400;
1134
+ font-weight: var(--emw--font-weight-normal, 400);
1081
1135
  height: 46px;
1082
1136
  border-radius: 50px;
1083
1137
  line-height: normal;
1084
1138
  border: none;
1085
1139
  background: var(--emw--color-primary, #7EC51E);
1086
1140
  width: 100%;
1087
- margin: 12px 0;
1141
+ margin: var(--emw--spacing-small, 12px) 0;
1088
1142
  cursor: pointer;
1089
1143
  display: flex;
1090
1144
  align-items: center;
1091
1145
  justify-content: center;
1092
- gap: 5px;
1146
+ gap: var(--mmw--spacing-2x-small-plus, 5px);
1093
1147
  &:has(.ButtonSpinner),
1094
1148
  &:has(.ButtonSpinner):hover,
1095
1149
  &:active {
1096
- background: var(--emw--color-active, #5C950F);
1150
+ background: var(--mmw--color-main-button-active, #5C950F);
1097
1151
  }
1098
1152
  .ButtonAmount {
1099
- font-weight: 600;
1153
+ font-weight: var(--mmw--font-weight-semibold-plus, 600);
1100
1154
  }
1101
1155
  .ButtonSpinner {
1102
1156
  animation: loading-spinner 1s linear infinite;
1103
1157
  }
1104
1158
  &[disabled] {
1105
- background: var(--emw--color-disabled, #99999980);
1159
+ background: var(--mmw--color-disabled, #99999980);
1106
1160
  cursor: auto;
1107
1161
  pointer-events: none;
1108
1162
  }
1109
1163
  &:hover {
1110
- background: var(--emw--color-hover, #71B11B);
1164
+ background: var(--mmw--color-main-button-hover, #71B11B);
1111
1165
  }
1112
1166
  }
1113
1167
  .QRCode {
@@ -1117,10 +1171,10 @@
1117
1171
  .Checkbox {
1118
1172
  display: flex;
1119
1173
  position: relative;
1120
- margin-top: 12px;
1174
+ margin-top: var(--emw--spacing-small, 12px);
1121
1175
 
1122
1176
  .Description {
1123
- margin: 0 0 0 20px;
1177
+ margin: 0 0 0 var(--emw--spacing-large, 20px);
1124
1178
  cursor: pointer;
1125
1179
  line-height: var( --emw--font-size-medium, 16px);
1126
1180
  }
@@ -1131,7 +1185,7 @@
1131
1185
  left: 0;
1132
1186
  height: 12px;
1133
1187
  width: 12px;
1134
- border: 1px solid var(--emw--color-gray-100, #E8E9EB);
1188
+ border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1135
1189
  border-radius: var(--emw--border-radius-medium, 4px);
1136
1190
  background-color: var(--emw--color-white, #FFF);
1137
1191
  cursor: pointer;
@@ -1187,7 +1241,7 @@
1187
1241
  width: 0;
1188
1242
  height: 0;
1189
1243
  border: 6px solid transparent;
1190
- border-color: rgb(168 169 170) transparent transparent transparent;
1244
+ border-color: var(--mmw--color-border, rgb(168 169 170)) transparent transparent transparent;
1191
1245
  }
1192
1246
  }
1193
1247
  .OptionList {
@@ -1196,23 +1250,23 @@
1196
1250
  left: 0;
1197
1251
  right: 0;
1198
1252
  z-index: 99;
1199
- background-color: white;
1200
- border: 1px solid var(--emw--color-gray-100, #E8E9EB);
1253
+ background-color: var(--emw--color-white, #fff);
1254
+ border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1201
1255
  border-radius: var(--emw--border-radius-medium, 4px);
1202
- margin-top: 5px;
1256
+ margin-top: var(--mmw--spacing-2x-small-plus, 5px);
1203
1257
  overflow: auto;
1204
1258
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
1205
1259
  &.Top {
1206
1260
  transform: translate(0, calc(-1 * (100% + $input-height + 10px)));
1207
1261
  }
1208
1262
  div {
1209
- padding: 8px 16px;
1263
+ padding: var(--emw--spacing-x-small, 8px) var(--emw--spacing-medium, 16px);
1210
1264
  cursor: pointer;
1211
1265
  user-select: none;
1212
1266
  line-height: calc(var(--emw--size-small, 14px) + 3px);
1213
1267
  font-size: var(--emw--size-small, 14px);
1214
1268
  &:hover {
1215
- background-color: var(--emw--color-background-secondary, #F9F9F9)
1269
+ background-color: var(--emw--color-gray-50, #F9F9F9);
1216
1270
  }
1217
1271
  }
1218
1272
  &.Opened {