@syncfusion/ej2-calendars 24.2.3 → 24.2.8
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/CHANGELOG.md +18 -0
- package/dist/ej2-calendars.min.js +2 -2
- package/dist/ej2-calendars.umd.min.js +2 -2
- package/dist/ej2-calendars.umd.min.js.map +1 -1
- package/dist/es6/ej2-calendars.es2015.js +103 -40
- package/dist/es6/ej2-calendars.es2015.js.map +1 -1
- package/dist/es6/ej2-calendars.es5.js +103 -40
- package/dist/es6/ej2-calendars.es5.js.map +1 -1
- package/dist/global/ej2-calendars.min.js +2 -2
- package/dist/global/ej2-calendars.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/package.json +10 -10
- package/src/calendar/calendar.d.ts +2 -0
- package/src/calendar/calendar.js +86 -21
- package/src/datepicker/datepicker.js +7 -3
- package/src/daterangepicker/daterangepicker.d.ts +0 -2
- package/src/daterangepicker/daterangepicker.js +8 -12
- package/src/maskbase/masked-date-time.js +2 -4
- package/styles/bootstrap-dark.css +2 -2
- package/styles/bootstrap.css +1 -1
- package/styles/bootstrap4.css +2 -2
- package/styles/bootstrap5-dark.css +1 -1
- package/styles/bootstrap5.css +1 -1
- package/styles/calendar/_bootstrap-dark-definition.scss +2 -2
- package/styles/calendar/_bootstrap4-definition.scss +2 -2
- package/styles/calendar/_material-dark-definition.scss +1 -1
- package/styles/calendar/_material-definition.scss +1 -1
- package/styles/calendar/_material3-definition.scss +1 -1
- package/styles/calendar/_theme.scss +1 -1
- package/styles/calendar/bootstrap-dark.css +2 -2
- package/styles/calendar/bootstrap.css +1 -1
- package/styles/calendar/bootstrap4.css +2 -2
- package/styles/calendar/bootstrap5-dark.css +1 -1
- package/styles/calendar/bootstrap5.css +1 -1
- package/styles/calendar/fabric-dark.css +1 -1
- package/styles/calendar/fabric.css +1 -1
- package/styles/calendar/fluent-dark.css +1 -1
- package/styles/calendar/fluent.css +1 -1
- package/styles/calendar/highcontrast-light.css +1 -1
- package/styles/calendar/highcontrast.css +1 -1
- package/styles/calendar/material-dark.css +10 -10
- package/styles/calendar/material.css +10 -10
- package/styles/calendar/material3-dark.css +10 -10
- package/styles/calendar/material3.css +10 -10
- package/styles/calendar/tailwind-dark.css +1 -1
- package/styles/calendar/tailwind.css +1 -1
- package/styles/fabric-dark.css +1 -1
- package/styles/fabric.css +1 -1
- package/styles/fluent-dark.css +1 -1
- package/styles/fluent.css +1 -1
- package/styles/highcontrast-light.css +1 -1
- package/styles/highcontrast.css +1 -1
- package/styles/material-dark.css +10 -10
- package/styles/material.css +10 -10
- package/styles/material3-dark.css +10 -10
- package/styles/material3.css +10 -10
- package/styles/tailwind-dark.css +1 -1
- package/styles/tailwind.css +1 -1
|
@@ -19,6 +19,7 @@ const DEVICE = 'e-device';
|
|
|
19
19
|
const HEADER = 'e-header';
|
|
20
20
|
const RTL = 'e-rtl';
|
|
21
21
|
const CONTENT = 'e-content';
|
|
22
|
+
const CONTENTTABLE = 'e-calandar-content-table';
|
|
22
23
|
const YEAR = 'e-year';
|
|
23
24
|
const MONTH = 'e-month';
|
|
24
25
|
const DECADE = 'e-decade';
|
|
@@ -34,6 +35,7 @@ const WEEKEND = 'e-weekend';
|
|
|
34
35
|
const WEEKNUMBER = 'e-week-number';
|
|
35
36
|
const SELECTED = 'e-selected';
|
|
36
37
|
const FOCUSEDDATE = 'e-focused-date';
|
|
38
|
+
const FOCUSEDCELL = 'e-focused-cell';
|
|
37
39
|
const OTHERMONTHROW = 'e-month-hide';
|
|
38
40
|
const TODAY = 'e-today';
|
|
39
41
|
const TITLE = 'e-title';
|
|
@@ -212,6 +214,7 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
212
214
|
const ariaTitleAttrs = {
|
|
213
215
|
'aria-atomic': 'true', 'aria-live': 'assertive', 'aria-label': 'title'
|
|
214
216
|
};
|
|
217
|
+
const tabIndexAttr = { 'tabindex': '0' };
|
|
215
218
|
this.headerElement = this.createElement('div', { className: HEADER });
|
|
216
219
|
const iconContainer = this.createElement('div', { className: ICONCONTAINER });
|
|
217
220
|
this.previousIcon = this.createElement('button', { className: '' + PREVICON, attrs: { type: 'button' } });
|
|
@@ -221,6 +224,7 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
221
224
|
isCenterRipple: true
|
|
222
225
|
});
|
|
223
226
|
attributes(this.previousIcon, ariaPrevAttrs);
|
|
227
|
+
attributes(this.previousIcon, tabIndexAttr);
|
|
224
228
|
this.nextIcon = this.createElement('button', { className: '' + NEXTICON, attrs: { type: 'button' } });
|
|
225
229
|
rippleEffect(this.nextIcon, {
|
|
226
230
|
selector: '.e-next',
|
|
@@ -232,8 +236,10 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
232
236
|
attributes(this.nextIcon, { tabIndex: '-1' });
|
|
233
237
|
}
|
|
234
238
|
attributes(this.nextIcon, ariaNextAttrs);
|
|
239
|
+
attributes(this.nextIcon, tabIndexAttr);
|
|
235
240
|
this.headerTitleElement = this.createElement('div', { className: '' + LINK + ' ' + TITLE });
|
|
236
241
|
attributes(this.headerTitleElement, ariaTitleAttrs);
|
|
242
|
+
attributes(this.headerTitleElement, tabIndexAttr);
|
|
237
243
|
this.headerElement.appendChild(this.headerTitleElement);
|
|
238
244
|
this.previousIcon.appendChild(this.createElement('span', { className: '' + PREVSPAN + ' ' + ICON }));
|
|
239
245
|
this.nextIcon.appendChild(this.createElement('span', { className: '' + NEXTSPAN + ' ' + ICON }));
|
|
@@ -250,7 +256,7 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
250
256
|
}
|
|
251
257
|
createContent() {
|
|
252
258
|
this.contentElement = this.createElement('div', { className: CONTENT });
|
|
253
|
-
this.table = this.createElement('table', { attrs: { tabIndex: '0', 'role': 'grid', 'aria-activedescendant': '', 'aria-labelledby': this.element.id } });
|
|
259
|
+
this.table = this.createElement('table', { attrs: { 'class': CONTENTTABLE, 'tabIndex': '0', 'role': 'grid', 'aria-activedescendant': '', 'aria-labelledby': this.element.id } });
|
|
254
260
|
if (this.getModuleName() === 'calendar') {
|
|
255
261
|
this.element.appendChild(this.contentElement);
|
|
256
262
|
}
|
|
@@ -263,6 +269,30 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
263
269
|
if (this.showTodayButton) {
|
|
264
270
|
this.createContentFooter();
|
|
265
271
|
}
|
|
272
|
+
if (this.getModuleName() != 'daterangepicker') {
|
|
273
|
+
EventHandler.add(this.table, 'focus', this.addContentFocus, this);
|
|
274
|
+
EventHandler.add(this.table, 'blur', this.removeContentFocus, this);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
addContentFocus(args) {
|
|
278
|
+
const focusedDate = this.tableBodyElement.querySelector('tr td.e-focused-date');
|
|
279
|
+
const selectedDate = this.tableBodyElement.querySelector('tr td.e-selected');
|
|
280
|
+
if (!isNullOrUndefined(selectedDate)) {
|
|
281
|
+
selectedDate.classList.add(FOCUSEDCELL);
|
|
282
|
+
}
|
|
283
|
+
else if (!isNullOrUndefined(focusedDate)) {
|
|
284
|
+
focusedDate.classList.add(FOCUSEDCELL);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
removeContentFocus(args) {
|
|
288
|
+
const focusedDate = this.tableBodyElement.querySelector('tr td.e-focused-date');
|
|
289
|
+
const selectedDate = this.tableBodyElement.querySelector('tr td.e-selected');
|
|
290
|
+
if (!isNullOrUndefined(selectedDate)) {
|
|
291
|
+
selectedDate.classList.remove(FOCUSEDCELL);
|
|
292
|
+
}
|
|
293
|
+
else if (!isNullOrUndefined(focusedDate)) {
|
|
294
|
+
focusedDate.classList.remove(FOCUSEDCELL);
|
|
295
|
+
}
|
|
266
296
|
}
|
|
267
297
|
getCultureValues() {
|
|
268
298
|
const culShortNames = [];
|
|
@@ -346,6 +376,7 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
346
376
|
updateFooter() {
|
|
347
377
|
this.todayElement.textContent = this.l10.getConstant('today');
|
|
348
378
|
this.todayElement.setAttribute('aria-label', this.l10.getConstant('today'));
|
|
379
|
+
this.todayElement.setAttribute('tabindex', '0');
|
|
349
380
|
}
|
|
350
381
|
createContentFooter() {
|
|
351
382
|
if (this.showTodayButton) {
|
|
@@ -450,34 +481,54 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
450
481
|
this.effect = '';
|
|
451
482
|
switch (e.action) {
|
|
452
483
|
case 'moveLeft':
|
|
453
|
-
this.
|
|
454
|
-
|
|
484
|
+
if (this.getModuleName() != 'daterangepicker' && !isNullOrUndefined(e.target) && e.target.classList.length > 0 && e.target.classList.contains(CONTENTTABLE)) {
|
|
485
|
+
this.keyboardNavigate(-1, view, e, this.max, this.min);
|
|
486
|
+
e.preventDefault();
|
|
487
|
+
}
|
|
455
488
|
break;
|
|
456
489
|
case 'moveRight':
|
|
457
|
-
this.
|
|
458
|
-
|
|
490
|
+
if (this.getModuleName() != 'daterangepicker' && !isNullOrUndefined(e.target) && e.target.classList.length > 0 && e.target.classList.contains(CONTENTTABLE)) {
|
|
491
|
+
this.keyboardNavigate(1, view, e, this.max, this.min);
|
|
492
|
+
e.preventDefault();
|
|
493
|
+
}
|
|
459
494
|
break;
|
|
460
495
|
case 'moveUp':
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
496
|
+
if (this.getModuleName() != 'daterangepicker' && !isNullOrUndefined(e.target) && e.target.classList.length > 0 && e.target.classList.contains(CONTENTTABLE)) {
|
|
497
|
+
if (view === 0) {
|
|
498
|
+
this.keyboardNavigate(-7, view, e, this.max, this.min); // move the current date to the previous seven days.
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
this.keyboardNavigate(-4, view, e, this.max, this.min); // move the current year to the previous four days.
|
|
502
|
+
}
|
|
503
|
+
e.preventDefault();
|
|
466
504
|
}
|
|
467
|
-
e.preventDefault();
|
|
468
505
|
break;
|
|
469
506
|
case 'moveDown':
|
|
470
|
-
if (
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
507
|
+
if (this.getModuleName() != 'daterangepicker' && !isNullOrUndefined(e.target) && e.target.classList.length > 0 && e.target.classList.contains(CONTENTTABLE)) {
|
|
508
|
+
if (view === 0) {
|
|
509
|
+
this.keyboardNavigate(7, view, e, this.max, this.min);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
this.keyboardNavigate(4, view, e, this.max, this.min);
|
|
513
|
+
}
|
|
514
|
+
e.preventDefault();
|
|
475
515
|
}
|
|
476
|
-
e.preventDefault();
|
|
477
516
|
break;
|
|
478
517
|
case 'select':
|
|
479
|
-
if (e.target === this.
|
|
518
|
+
if (e.target === this.headerTitleElement) {
|
|
519
|
+
this.navigateTitle(e);
|
|
520
|
+
}
|
|
521
|
+
else if (e.target === this.previousIcon) {
|
|
522
|
+
this.navigatePrevious(e);
|
|
523
|
+
}
|
|
524
|
+
else if (e.target === this.nextIcon) {
|
|
525
|
+
this.navigateNext(e);
|
|
526
|
+
}
|
|
527
|
+
else if (e.target === this.todayElement) {
|
|
480
528
|
this.todayButtonClick(e, value);
|
|
529
|
+
if (this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') {
|
|
530
|
+
this.element.focus();
|
|
531
|
+
}
|
|
481
532
|
}
|
|
482
533
|
else {
|
|
483
534
|
const element = !isNullOrUndefined(focusedDate) ? focusedDate : selectedDate;
|
|
@@ -490,6 +541,9 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
490
541
|
else {
|
|
491
542
|
this.contentClick(null, --view, (element), value);
|
|
492
543
|
}
|
|
544
|
+
if (this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') {
|
|
545
|
+
this.element.focus();
|
|
546
|
+
}
|
|
493
547
|
}
|
|
494
548
|
}
|
|
495
549
|
break;
|
|
@@ -559,9 +613,20 @@ let CalendarBase = class CalendarBase extends Component {
|
|
|
559
613
|
this.navigateTo('Month', new Date(this.currentDate.getFullYear(), 11, 31));
|
|
560
614
|
e.preventDefault();
|
|
561
615
|
break;
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
616
|
+
case 'tab':
|
|
617
|
+
if ((this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') && e.target === this.todayElement) {
|
|
618
|
+
e.preventDefault();
|
|
619
|
+
this.element.focus();
|
|
620
|
+
this.hide();
|
|
621
|
+
}
|
|
622
|
+
break;
|
|
623
|
+
case 'shiftTab':
|
|
624
|
+
if ((this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') && e.target === this.headerTitleElement) {
|
|
625
|
+
e.preventDefault();
|
|
626
|
+
this.element.focus();
|
|
627
|
+
this.hide();
|
|
628
|
+
}
|
|
629
|
+
break;
|
|
565
630
|
}
|
|
566
631
|
}
|
|
567
632
|
keyboardNavigate(number, currentView, e, max, min) {
|
|
@@ -3801,8 +3866,6 @@ let DatePicker = class DatePicker extends Calendar {
|
|
|
3801
3866
|
this.inputElement.focus();
|
|
3802
3867
|
}
|
|
3803
3868
|
break;
|
|
3804
|
-
case 'tab':
|
|
3805
|
-
this.hide(e);
|
|
3806
3869
|
}
|
|
3807
3870
|
}
|
|
3808
3871
|
inputFocusHandler() {
|
|
@@ -3964,7 +4027,13 @@ let DatePicker = class DatePicker extends Calendar {
|
|
|
3964
4027
|
this.inputElement.selectionStart = start;
|
|
3965
4028
|
this.inputElement.selectionEnd = end;
|
|
3966
4029
|
}
|
|
3967
|
-
this.
|
|
4030
|
+
if (e.action === 'tab' && e.target === this.inputElement && this.isCalendar() && document.activeElement === this.inputElement) {
|
|
4031
|
+
e.preventDefault();
|
|
4032
|
+
this.headerTitleElement.focus();
|
|
4033
|
+
}
|
|
4034
|
+
if (e.action === 'shiftTab' && e.target === this.inputElement && this.isCalendar() && document.activeElement === this.inputElement) {
|
|
4035
|
+
this.hide(e);
|
|
4036
|
+
}
|
|
3968
4037
|
break;
|
|
3969
4038
|
}
|
|
3970
4039
|
default:
|
|
@@ -5338,7 +5407,6 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
5338
5407
|
this.invalidValueString = null;
|
|
5339
5408
|
this.isAngular = false;
|
|
5340
5409
|
this.preventChange = false;
|
|
5341
|
-
this.isKeyPressed = false;
|
|
5342
5410
|
this.dateRangeOptions = options;
|
|
5343
5411
|
}
|
|
5344
5412
|
/**
|
|
@@ -5689,7 +5757,6 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
5689
5757
|
EventHandler.add(this.inputElement, 'focus', this.inputFocusHandler, this);
|
|
5690
5758
|
EventHandler.add(this.inputElement, 'blur', this.inputBlurHandler, this);
|
|
5691
5759
|
EventHandler.add(this.inputElement, 'change', this.inputChangeHandler, this);
|
|
5692
|
-
EventHandler.add(this.inputElement, 'keyup', this.keyupHandler, this);
|
|
5693
5760
|
if (this.showClearButton && this.inputWrapper.clearButton) {
|
|
5694
5761
|
EventHandler.add(this.inputWrapper.clearButton, 'mousedown', this.resetHandler, this);
|
|
5695
5762
|
}
|
|
@@ -5716,7 +5783,6 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
5716
5783
|
EventHandler.remove(this.inputElement, 'blur', this.inputBlurHandler);
|
|
5717
5784
|
EventHandler.remove(this.inputElement, 'focus', this.inputFocusHandler);
|
|
5718
5785
|
EventHandler.remove(this.inputElement, 'change', this.inputChangeHandler);
|
|
5719
|
-
EventHandler.remove(this.inputElement, 'keyup', this.keyupHandler);
|
|
5720
5786
|
if (this.showClearButton && this.inputWrapper.clearButton) {
|
|
5721
5787
|
EventHandler.remove(this.inputWrapper.clearButton, 'mousedown touchstart', this.resetHandler);
|
|
5722
5788
|
}
|
|
@@ -5970,8 +6036,8 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
5970
6036
|
const startDate = this.presetsItem[i].start;
|
|
5971
6037
|
const endDate = this.presetsItem[i].end;
|
|
5972
6038
|
if (this.startValue && this.endValue) {
|
|
5973
|
-
if ((
|
|
5974
|
-
|
|
6039
|
+
if (startDate.getDate() == this.startValue.getDate() && startDate.getMonth() == this.startValue.getMonth() && startDate.getFullYear() == this.startValue.getFullYear()
|
|
6040
|
+
&& endDate.getDate() == this.endValue.getDate() && endDate.getMonth() == this.endValue.getMonth() && endDate.getFullYear() == this.endValue.getFullYear()) {
|
|
5975
6041
|
this.activeIndex = i;
|
|
5976
6042
|
this.isCustomRange = false;
|
|
5977
6043
|
}
|
|
@@ -7935,9 +8001,6 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
7935
8001
|
this.startButton.element.classList.add(ACTIVE$1);
|
|
7936
8002
|
}
|
|
7937
8003
|
}
|
|
7938
|
-
keyupHandler(e) {
|
|
7939
|
-
this.isKeyPressed = (this.inputElement.value !== this.previousEleValue) ? true : false;
|
|
7940
|
-
}
|
|
7941
8004
|
applyFunction(eve) {
|
|
7942
8005
|
let isValueChanged = false;
|
|
7943
8006
|
if (eve.type !== 'touchstart') {
|
|
@@ -7960,13 +8023,15 @@ let DateRangePicker = class DateRangePicker extends CalendarBase {
|
|
|
7960
8023
|
eve.preventDefault();
|
|
7961
8024
|
}
|
|
7962
8025
|
if (!isNullOrUndefined(this.startValue) && !isNullOrUndefined(this.endValue)) {
|
|
8026
|
+
if (!(this.previousStartValue && this.previousEndValue && this.startValue.getDate() == this.previousStartValue.getDate() && this.startValue.getMonth() == this.previousStartValue.getMonth() &&
|
|
8027
|
+
this.startValue.getFullYear() == this.previousStartValue.getFullYear()
|
|
8028
|
+
&& this.endValue.getDate() == this.previousEndValue.getDate() && this.endValue.getMonth() == this.previousEndValue.getMonth()
|
|
8029
|
+
&& this.endValue.getFullYear() == this.previousEndValue.getFullYear())) {
|
|
8030
|
+
Input.setValue(this.rangeArgs(eve).text, this.inputElement, this.floatLabelType, this.showClearButton);
|
|
8031
|
+
}
|
|
7963
8032
|
this.previousStartValue = new Date(+this.startValue);
|
|
7964
8033
|
this.previousEndValue = new Date(+this.endValue);
|
|
7965
8034
|
this.previousEleValue = this.inputElement.value;
|
|
7966
|
-
if (!this.isKeyPressed) {
|
|
7967
|
-
Input.setValue(this.rangeArgs(eve).text, this.inputElement, this.floatLabelType, this.showClearButton);
|
|
7968
|
-
}
|
|
7969
|
-
this.isKeyPressed = false;
|
|
7970
8035
|
if (+this.initStartDate !== +this.startValue || +this.initEndDate !== +this.endValue) {
|
|
7971
8036
|
isValueChanged = true;
|
|
7972
8037
|
}
|
|
@@ -14386,6 +14451,7 @@ class MaskedDateTime {
|
|
|
14386
14451
|
{
|
|
14387
14452
|
let year = (this.isYearPart && (newDateValue.getFullYear().toString().length < 4
|
|
14388
14453
|
&& !this.isShortYear) ? newDateValue.getFullYear() * 10 : 0) + parseInt(newVal[start - 1], 10);
|
|
14454
|
+
let yearValue = (this.dateformat.match(/y/g) || []).length;
|
|
14389
14455
|
this.isShortYear = false;
|
|
14390
14456
|
this.isYearZero = (newVal[start - 1] === '0');
|
|
14391
14457
|
if (isNaN(year)) {
|
|
@@ -14399,7 +14465,7 @@ class MaskedDateTime {
|
|
|
14399
14465
|
}
|
|
14400
14466
|
else {
|
|
14401
14467
|
newDateValue.setFullYear(year);
|
|
14402
|
-
if (year.toString().length ===
|
|
14468
|
+
if (year.toString().length === yearValue) {
|
|
14403
14469
|
this.isNavigate = true;
|
|
14404
14470
|
}
|
|
14405
14471
|
this.previousDate = new Date(newDateValue.getFullYear(), newDateValue.getMonth(), newDateValue.getDate());
|
|
@@ -14574,9 +14640,6 @@ class MaskedDateTime {
|
|
|
14574
14640
|
case 'yy':
|
|
14575
14641
|
result = proxy.isYearPart ? proxy.roundOff(proxy.maskDateValue.getFullYear() % 100, 2) : proxy.defaultConstant['year'].toString();
|
|
14576
14642
|
result = proxy.zeroCheck(proxy.isYearZero, proxy.isYearPart, result);
|
|
14577
|
-
if (proxy.isYearPart) {
|
|
14578
|
-
proxy.isNavigate = proxy.isShortYear = (proxy.maskDateValue.getFullYear() % 100).toString().length === 2;
|
|
14579
|
-
}
|
|
14580
14643
|
break;
|
|
14581
14644
|
case 'y':
|
|
14582
14645
|
case 'yyyy':
|