@oslokommune/punkt-elements 13.4.2 → 13.5.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,7 +1,13 @@
1
1
  import { classMap } from 'lit/directives/class-map.js'
2
2
  import { ifDefined } from 'lit/directives/if-defined.js'
3
3
  import { customElement, property, state } from 'lit/decorators.js'
4
- import { formatISODate, fromISOToDate, fromISOtoLocal, newDate } from '@/utils/dateutils'
4
+ import {
5
+ formatISODate,
6
+ fromISOToDate,
7
+ fromISOtoLocal,
8
+ newDate,
9
+ parseISODateString,
10
+ } from '@/utils/dateutils'
5
11
  import { html, nothing, PropertyValues } from 'lit'
6
12
  import { PktCalendar } from '@/components/calendar/calendar'
7
13
  import { PktInputElement } from '@/base-elements/input-element'
@@ -21,15 +27,22 @@ export class PktDatepicker extends PktInputElement {
21
27
  /**
22
28
  * Element attributes and properties
23
29
  */
30
+ private _valueProperty: string = ''
31
+
24
32
  @property({ type: String, reflect: true })
25
- value: string | string[] = ''
33
+ get value(): string {
34
+ return this._valueProperty
35
+ }
36
+
37
+ set value(newValue: string | string[]) {
38
+ const oldValue = this._valueProperty
39
+ this._valueProperty = Array.isArray(newValue) ? newValue.join(',') : newValue || ''
40
+ this.valueChanged(this._valueProperty, oldValue)
41
+ this.requestUpdate('value', oldValue)
42
+ }
26
43
 
27
44
  @property({ type: Array })
28
- _value: string[] = this.value
29
- ? !Array.isArray(this.value)
30
- ? this.value.split(',')
31
- : this.value
32
- : []
45
+ _value: string[] = []
33
46
 
34
47
  @property({ type: String, reflect: true })
35
48
  label: string = 'Datovelger'
@@ -112,8 +125,17 @@ export class PktDatepicker extends PktInputElement {
112
125
  }
113
126
  })
114
127
 
115
- if (this.value.length && this._value.length === 0) {
116
- this._value = !Array.isArray(this.value) ? this.value.split(',') : this.value
128
+ document &&
129
+ document.body.addEventListener('keydown', (e: KeyboardEvent) => {
130
+ if (e.key === 'Escape' && this.calendarOpen) {
131
+ this.hideCalendar()
132
+ }
133
+ })
134
+
135
+ if (this.value) {
136
+ this._value = Array.isArray(this.value)
137
+ ? this.value.filter(Boolean)
138
+ : this.value.split(',').filter(Boolean)
117
139
  }
118
140
  this.min = this.min || specs.props.min.default
119
141
  this.max = this.max || specs.props.max.default
@@ -151,10 +173,55 @@ export class PktDatepicker extends PktInputElement {
151
173
  })
152
174
  }
153
175
 
176
+ onInput(): void {
177
+ // Trigger input event for form validation
178
+ this.dispatchEvent(new Event('input', { bubbles: true }))
179
+ }
180
+
181
+ valueChanged(newValue: string | null, oldValue: string | null): void {
182
+ if (newValue !== oldValue) {
183
+ let validatedValue: string[] = []
184
+
185
+ if (newValue) {
186
+ // Handle case where newValue might be a string or need conversion
187
+ if (typeof newValue === 'string') {
188
+ validatedValue = newValue.split(',').filter(Boolean)
189
+ } else {
190
+ // If not a string, convert to string first
191
+ validatedValue = String(newValue).split(',').filter(Boolean)
192
+ }
193
+ }
194
+
195
+ // Validate dates against min/max boundaries
196
+ if (this.min || this.max) {
197
+ const minDate = this.min ? new Date(this.min) : null
198
+ const maxDate = this.max ? new Date(this.max) : null
199
+
200
+ validatedValue = validatedValue.filter((dateStr) => {
201
+ const date = new Date(dateStr)
202
+ if (isNaN(date.getTime())) return false
203
+ if (minDate && date < minDate) return false
204
+ if (maxDate && date > maxDate) return false
205
+ return true
206
+ })
207
+ }
208
+
209
+ this._value = validatedValue
210
+
211
+ // Update the public value property to reflect validated value
212
+ const validatedValueString = validatedValue.join(',')
213
+ if (this._valueProperty !== validatedValueString) {
214
+ this._valueProperty = validatedValueString
215
+ }
216
+
217
+ // Call base class valueChanged to handle events properly
218
+ super.valueChanged(validatedValueString, oldValue)
219
+ }
220
+ }
221
+
154
222
  attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
155
- if (name === 'value') {
156
- if (this.range && value?.split(',').length === 1) return
157
- if (this.value !== _old) this.valueChanged(value, _old)
223
+ if (name === 'value' && this.value !== _old) {
224
+ this.valueChanged(value, _old)
158
225
  }
159
226
 
160
227
  if (name === 'excludedates' && typeof this.excludedates === 'string') {
@@ -168,6 +235,12 @@ export class PktDatepicker extends PktInputElement {
168
235
  }
169
236
 
170
237
  updated(changedProperties: PropertyValues): void {
238
+ if (changedProperties.has('value')) {
239
+ const newValue = Array.isArray(this.value) ? this.value.join(',') : this.value
240
+ const oldValue = changedProperties.get('value')
241
+ const oldValueStr = Array.isArray(oldValue) ? oldValue.join(',') : oldValue
242
+ this.valueChanged(newValue, oldValueStr)
243
+ }
171
244
  if (changedProperties.has('multiple')) {
172
245
  // If multiple is now true, ensure _value is an array of non-empty strings
173
246
  if (this.multiple && !Array.isArray(this._value)) {
@@ -180,8 +253,8 @@ export class PktDatepicker extends PktInputElement {
180
253
  } else if (!this.multiple && Array.isArray(this._value)) {
181
254
  this._value = this._value.filter(Boolean)
182
255
  }
183
- // If multiple is now false, ensure _value is a single value
184
- if (!this.multiple && Array.isArray(this._value)) {
256
+ // If multiple is now false, ensure _value is a single value (but not for range datepickers)
257
+ if (!this.multiple && !this.range && Array.isArray(this._value)) {
185
258
  this._value = [this._value[0] ?? '']
186
259
  }
187
260
  }
@@ -212,6 +285,9 @@ export class PktDatepicker extends PktInputElement {
212
285
  .value=${this._value[0] ?? ''}
213
286
  min=${ifDefined(this.min)}
214
287
  max=${ifDefined(this.max)}
288
+ placeholder=${ifDefined(this.placeholder)}
289
+ ?readonly=${this.readonly}
290
+ aria-describedby="${this.id}-helptext"
215
291
  @click=${(e: MouseEvent) => {
216
292
  e.preventDefault()
217
293
  this.showCalendar()
@@ -276,6 +352,8 @@ export class PktDatepicker extends PktInputElement {
276
352
  .value=${this._value[0] ?? ''}
277
353
  min=${ifDefined(this.min)}
278
354
  max=${ifDefined(this.max)}
355
+ placeholder=${ifDefined(this.placeholder)}
356
+ ?readonly=${this.readonly}
279
357
  ?disabled=${this.disabled}
280
358
  @click=${(e: MouseEvent) => {
281
359
  e.preventDefault()
@@ -339,6 +417,8 @@ export class PktDatepicker extends PktInputElement {
339
417
  .value=${this._value[1] ?? ''}
340
418
  min=${ifDefined(this.min)}
341
419
  max=${ifDefined(this.max)}
420
+ placeholder=${ifDefined(this.placeholder)}
421
+ ?readonly=${this.readonly}
342
422
  ?disabled=${this.disabled}
343
423
  @click=${(e: MouseEvent) => {
344
424
  e.preventDefault()
@@ -409,7 +489,6 @@ export class PktDatepicker extends PktInputElement {
409
489
  }
410
490
 
411
491
  renderMultipleInput() {
412
- console.log('range', this.range, 'multiple', this.multiple)
413
492
  return html`
414
493
  <input
415
494
  class=${classMap(this.inputClasses)}
@@ -417,6 +496,8 @@ export class PktDatepicker extends PktInputElement {
417
496
  id="${this.id}-input"
418
497
  min=${ifDefined(this.min)}
419
498
  max=${ifDefined(this.max)}
499
+ placeholder=${ifDefined(this.placeholder)}
500
+ ?readonly=${this.readonly}
420
501
  ?disabled=${this.disabled || (this.maxlength && this._value.length >= this.maxlength)}
421
502
  @click=${(e: MouseEvent) => {
422
503
  e.preventDefault()
@@ -470,7 +551,7 @@ export class PktDatepicker extends PktInputElement {
470
551
  <div class="pkt-datepicker__tags" aria-live="polite">
471
552
  ${!!this._value[0]
472
553
  ? repeat(
473
- (this._value ?? []).filter(Boolean),
554
+ (this._value ?? []).filter(Boolean).sort(),
474
555
  (date) => date,
475
556
  (date) => html`
476
557
  <pkt-tag
@@ -513,16 +594,26 @@ export class PktDatepicker extends PktInputElement {
513
594
  ? this.excludedates
514
595
  : (this.excludedates as string).split(',')}
515
596
  .excludeweekdays=${this.excludeweekdays}
516
- .currentmonth=${this.currentmonth ? newDate(this.currentmonth) : null}
597
+ .currentmonth=${this.currentmonth ? parseISODateString(this.currentmonth) : null}
517
598
  @date-selected=${(e: CustomEvent) => {
518
- this.value = !this.multiple && !this.range ? e.detail[0] : e.detail
599
+ this.value =
600
+ !this.multiple && !this.range
601
+ ? e.detail[0]
602
+ : Array.isArray(e.detail)
603
+ ? e.detail.join(',')
604
+ : e.detail
519
605
  this._value = e.detail
520
606
  if (this.inputRef.value) {
521
607
  if (this.range && this.inputRefTo.value) {
522
608
  this.inputRef.value.value = this._value[0] ?? ''
523
609
  this.inputRefTo.value.value = this._value[1] ?? ''
610
+ // Update validity state after programmatic value change
611
+ this.manageValidity(this.inputRef.value)
612
+ this.manageValidity(this.inputRefTo.value)
524
613
  } else if (!this.multiple) {
525
614
  this.inputRef.value.value = this._value.length ? this._value[0] : ''
615
+ // Update validity state after programmatic value change
616
+ this.manageValidity(this.inputRef.value)
526
617
  }
527
618
  }
528
619
  }}
@@ -536,7 +627,6 @@ export class PktDatepicker extends PktInputElement {
536
627
  }
537
628
 
538
629
  render() {
539
- console.log('multiple', this.multiple, 'value', this.value, '_value', this._value)
540
630
  this.inputClasses = {
541
631
  'pkt-input': true,
542
632
  'pkt-datepicker__input': true,
@@ -551,6 +641,7 @@ export class PktDatepicker extends PktInputElement {
551
641
  'pkt-btn': true,
552
642
  'pkt-btn--icon-only': true,
553
643
  'pkt-btn--tertiary': true,
644
+ 'pkt-datepicker__calendar-button': true,
554
645
  }
555
646
 
556
647
  return html`
@@ -595,6 +686,12 @@ export class PktDatepicker extends PktInputElement {
595
686
  class="${classMap(this.buttonClasses)}"
596
687
  type="button"
597
688
  @click=${this.toggleCalendar}
689
+ @keydown=${(e: KeyboardEvent) => {
690
+ if (e.key === 'Enter' || e.key === ' ' || e.key === 'Space') {
691
+ e.preventDefault()
692
+ this.toggleCalendar(e)
693
+ }
694
+ }}
598
695
  ?disabled=${this.disabled}
599
696
  ${ref(this.btnRef)}
600
697
  >
@@ -677,4 +774,9 @@ export class PktDatepicker extends PktInputElement {
677
774
  e.preventDefault()
678
775
  this.calendarOpen ? this.hideCalendar() : this.showCalendar()
679
776
  }
777
+
778
+ public clearInputValue() {
779
+ this._value = []
780
+ this.value = ''
781
+ }
680
782
  }
@@ -0,0 +1,176 @@
1
+ import '@testing-library/jest-dom'
2
+
3
+ import './datepicker'
4
+ import '../calendar/calendar'
5
+ import { PktDatepicker } from './datepicker'
6
+
7
+ const waitForCustomElements = async () => {
8
+ await customElements.whenDefined('pkt-datepicker')
9
+ await customElements.whenDefined('pkt-calendar')
10
+ }
11
+
12
+ // Helper function to create datepicker markup
13
+ const createDatepicker = async (datepickerProps = '') => {
14
+ const container = document.createElement('div')
15
+ container.innerHTML = `
16
+ <pkt-datepicker ${datepickerProps}></pkt-datepicker>
17
+ `
18
+ document.body.appendChild(container)
19
+ await waitForCustomElements()
20
+ return container
21
+ }
22
+
23
+ // Cleanup after each test
24
+ afterEach(() => {
25
+ document.body.innerHTML = ''
26
+ })
27
+
28
+ describe('PktDatepicker', () => {
29
+ describe('Date boundary testing', () => {
30
+ test('handles minimum possible dates', async () => {
31
+ const minDate = '1900-01-01'
32
+ const container = await createDatepicker(`value="${minDate}" earliest="${minDate}"`)
33
+
34
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
35
+ await datepicker.updateComplete
36
+
37
+ expect(datepicker.value).toBe(minDate)
38
+ })
39
+
40
+ test('handles maximum possible dates', async () => {
41
+ const maxDate = '2100-12-31'
42
+ const container = await createDatepicker(`value="${maxDate}" latest="${maxDate}"`)
43
+
44
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
45
+ await datepicker.updateComplete
46
+
47
+ expect(datepicker.value).toBe(maxDate)
48
+ })
49
+
50
+ test('handles year boundaries correctly', async () => {
51
+ const yearBoundaryDates = ['1999-12-31', '2000-01-01', '2000-12-31', '2001-01-01']
52
+
53
+ for (const date of yearBoundaryDates) {
54
+ const container = await createDatepicker(`value="${date}"`)
55
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
56
+ await datepicker.updateComplete
57
+
58
+ expect(datepicker.value).toBe(date)
59
+ container.remove()
60
+ }
61
+ })
62
+
63
+ test('handles month boundaries correctly', async () => {
64
+ const monthBoundaryDates = [
65
+ '2024-01-31',
66
+ '2024-02-01',
67
+ '2024-02-28',
68
+ '2024-02-29', // Leap year
69
+ '2024-03-01',
70
+ ]
71
+
72
+ for (const date of monthBoundaryDates) {
73
+ const container = await createDatepicker(`value="${date}"`)
74
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
75
+ await datepicker.updateComplete
76
+
77
+ expect(datepicker.value).toBe(date)
78
+ container.remove()
79
+ }
80
+ })
81
+
82
+ test('validates dates against earliest/latest boundaries', async () => {
83
+ const container = await createDatepicker('min="2024-06-10" max="2024-06-20"')
84
+
85
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
86
+ await datepicker.updateComplete
87
+
88
+ const input = datepicker.querySelector('input') as HTMLInputElement
89
+
90
+ // Test date before min - component should filter it out
91
+ datepicker.value = '2024-06-05'
92
+ await datepicker.updateComplete
93
+
94
+ // Component should reject invalid date (filter it out)
95
+ expect(datepicker.value).toBe('')
96
+ expect(input.value).toBe('')
97
+
98
+ // Test date after max - component should filter it out
99
+ datepicker.value = '2024-06-25'
100
+ await datepicker.updateComplete
101
+
102
+ // Component should reject invalid date (filter it out)
103
+ expect(datepicker.value).toBe('')
104
+ expect(input.value).toBe('')
105
+
106
+ // Test valid date - should be accepted
107
+ datepicker.value = '2024-06-15'
108
+ await datepicker.updateComplete
109
+
110
+ // Valid date should be accepted
111
+ expect(datepicker.value).toBe('2024-06-15')
112
+ expect(input.value).toBe('2024-06-15')
113
+ expect(input.validity.valid).toBe(true)
114
+ })
115
+ })
116
+
117
+ describe('Error handling and edge cases', () => {
118
+ test('handles invalid date formats gracefully', async () => {
119
+ const container = await createDatepicker('value="not-a-date"')
120
+
121
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
122
+ await datepicker.updateComplete
123
+
124
+ // Should not crash
125
+ expect(datepicker).toBeInTheDocument()
126
+ })
127
+
128
+ test('handles empty values correctly', async () => {
129
+ const container = await createDatepicker('value=""')
130
+
131
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
132
+ await datepicker.updateComplete
133
+
134
+ expect(datepicker.value).toBe('')
135
+ expect(datepicker.hasError).toBe(false)
136
+ })
137
+
138
+ test('handles malformed multiple values', async () => {
139
+ const malformedDates = '2024-06-15,,2024-06-20,,,'
140
+ const container = await createDatepicker(`value="${malformedDates}" multiple`)
141
+
142
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
143
+ await datepicker.updateComplete
144
+
145
+ // Should filter out empty values
146
+ const tags = datepicker.querySelectorAll('pkt-tag')
147
+ expect(tags.length).toBe(2) // Only valid dates
148
+ })
149
+
150
+ test('handles very long value strings', async () => {
151
+ // Create a string with many dates
152
+ const longValueArray = Array.from({ length: 100 }, (_, i) => `2024-06-${(i % 30) + 1}`)
153
+ const longValue = longValueArray.join(',')
154
+ const container = await createDatepicker(`value="${longValue}" multiple maxlength="50"`)
155
+
156
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
157
+ await datepicker.updateComplete
158
+
159
+ // Should handle gracefully - maxlength may or may not be enforced at render time
160
+ const tags = datepicker.querySelectorAll('pkt-tag')
161
+ expect(tags.length).toBeGreaterThan(0) // Should show some tags
162
+ expect(datepicker).toBeInTheDocument() // Should not crash
163
+ })
164
+
165
+ test('handles conflicting properties gracefully', async () => {
166
+ // Both multiple and range shouldn't typically be used together
167
+ const container = await createDatepicker('multiple range value="2024-06-15,2024-06-20"')
168
+
169
+ const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
170
+ await datepicker.updateComplete
171
+
172
+ // Should still render without errors
173
+ expect(datepicker).toBeInTheDocument()
174
+ })
175
+ })
176
+ })
@@ -1,108 +0,0 @@
1
- "use strict";const lt=require("./class-map-BBG2gMX4.cjs"),o=require("./element-6DBpyGQm.cjs"),F=require("./state-DPobt-Yz.cjs");require("./icon-B_ryAy4Q.cjs");const et=6048e5,ut=864e5,j=Symbol.for("constructDateFrom");function S(n,t){return typeof n=="function"?n(t):n&&typeof n=="object"&&j in n?n[j](t):n instanceof Date?new n.constructor(t):new Date(t)}function k(n,t){return S(t||n,n)}function L(n,t,e){const r=k(n,e==null?void 0:e.in);return isNaN(t)?S(n,NaN):(t&&r.setDate(r.getDate()+t),r)}let ht={};function I(){return ht}function A(n,t){var c,l,u,f;const e=I(),r=(t==null?void 0:t.weekStartsOn)??((l=(c=t==null?void 0:t.locale)==null?void 0:c.options)==null?void 0:l.weekStartsOn)??e.weekStartsOn??((f=(u=e.locale)==null?void 0:u.options)==null?void 0:f.weekStartsOn)??0,a=k(n,t==null?void 0:t.in),s=a.getDay(),i=(s<r?7:0)+s-r;return a.setDate(a.getDate()-i),a.setHours(0,0,0,0),a}function H(n,t){return A(n,{...t,weekStartsOn:1})}function nt(n,t){const e=k(n,t==null?void 0:t.in),r=e.getFullYear(),a=S(e,0);a.setFullYear(r+1,0,4),a.setHours(0,0,0,0);const s=H(a),i=S(e,0);i.setFullYear(r,0,4),i.setHours(0,0,0,0);const c=H(i);return e.getTime()>=s.getTime()?r+1:e.getTime()>=c.getTime()?r:r-1}function G(n){const t=k(n),e=new Date(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()));return e.setUTCFullYear(t.getFullYear()),+n-+e}function rt(n,...t){const e=S.bind(null,t.find(r=>typeof r=="object"));return t.map(e)}function z(n,t){const e=k(n,t==null?void 0:t.in);return e.setHours(0,0,0,0),e}function dt(n,t,e){const[r,a]=rt(e==null?void 0:e.in,n,t),s=z(r),i=z(a),c=+s-G(s),l=+i-G(i);return Math.round((c-l)/ut)}function ft(n,t){const e=nt(n,t),r=S(n,0);return r.setFullYear(e,0,4),r.setHours(0,0,0,0),H(r)}function mt(n){return n instanceof Date||typeof n=="object"&&Object.prototype.toString.call(n)==="[object Date]"}function gt(n){return!(!mt(n)&&typeof n!="number"||isNaN(+k(n)))}function yt(n,t){const e=k(n,t==null?void 0:t.in);return e.setHours(23,59,59,999),e}function pt(n,t){const[e,r]=rt(n,t.start,t.end);return{start:e,end:r}}function R(n,t){const{start:e,end:r}=pt(t==null?void 0:t.in,n);let a=+e>+r;const s=a?+e:+r,i=a?r:e;i.setHours(0,0,0,0);let c=1;const l=[];for(;+i<=s;)l.push(S(e,i)),i.setDate(i.getDate()+c),i.setHours(0,0,0,0);return a?l.reverse():l}function wt(n,t){const e=k(n,t==null?void 0:t.in);return e.setFullYear(e.getFullYear(),0,1),e.setHours(0,0,0,0),e}const bt={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}},kt=(n,t,e)=>{let r;const a=bt[n];return typeof a=="string"?r=a:t===1?r=a.one:r=a.other.replace("{{count}}",t.toString()),e!=null&&e.addSuffix?e.comparison&&e.comparison>0?"in "+r:r+" ago":r};function U(n){return(t={})=>{const e=t.width?String(t.width):n.defaultWidth;return n.formats[e]||n.formats[n.defaultWidth]}}const Dt={full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},vt={full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},St={full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},Mt={date:U({formats:Dt,defaultWidth:"full"}),time:U({formats:vt,defaultWidth:"full"}),dateTime:U({formats:St,defaultWidth:"full"})},xt={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"},Tt=(n,t,e,r)=>xt[n];function $(n){return(t,e)=>{const r=e!=null&&e.context?String(e.context):"standalone";let a;if(r==="formatting"&&n.formattingValues){const i=n.defaultFormattingWidth||n.defaultWidth,c=e!=null&&e.width?String(e.width):i;a=n.formattingValues[c]||n.formattingValues[i]}else{const i=n.defaultWidth,c=e!=null&&e.width?String(e.width):n.defaultWidth;a=n.values[c]||n.values[i]}const s=n.argumentCallback?n.argumentCallback(t):t;return a[s]}}const Pt={narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},Ot={narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},Ct={narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},Nt={narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},$t={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},Et={narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},Wt=(n,t)=>{const e=Number(n),r=e%100;if(r>20||r<10)switch(r%10){case 1:return e+"st";case 2:return e+"nd";case 3:return e+"rd"}return e+"th"},Yt={ordinalNumber:Wt,era:$({values:Pt,defaultWidth:"wide"}),quarter:$({values:Ot,defaultWidth:"wide",argumentCallback:n=>n-1}),month:$({values:Ct,defaultWidth:"wide"}),day:$({values:Nt,defaultWidth:"wide"}),dayPeriod:$({values:$t,defaultWidth:"wide",formattingValues:Et,defaultFormattingWidth:"wide"})};function E(n){return(t,e={})=>{const r=e.width,a=r&&n.matchPatterns[r]||n.matchPatterns[n.defaultMatchWidth],s=t.match(a);if(!s)return null;const i=s[0],c=r&&n.parsePatterns[r]||n.parsePatterns[n.defaultParseWidth],l=Array.isArray(c)?Ft(c,p=>p.test(i)):At(c,p=>p.test(i));let u;u=n.valueCallback?n.valueCallback(l):l,u=e.valueCallback?e.valueCallback(u):u;const f=t.slice(i.length);return{value:u,rest:f}}}function At(n,t){for(const e in n)if(Object.prototype.hasOwnProperty.call(n,e)&&t(n[e]))return e}function Ft(n,t){for(let e=0;e<n.length;e++)if(t(n[e]))return e}function _t(n){return(t,e={})=>{const r=t.match(n.matchPattern);if(!r)return null;const a=r[0],s=t.match(n.parsePattern);if(!s)return null;let i=n.valueCallback?n.valueCallback(s[0]):s[0];i=e.valueCallback?e.valueCallback(i):i;const c=t.slice(a.length);return{value:i,rest:c}}}const Ht=/^(\d+)(th|st|nd|rd)?/i,It=/\d+/i,qt={narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},Lt={any:[/^b/i,/^(a|c)/i]},Rt={narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},Ut={any:[/1/i,/2/i,/3/i,/4/i]},Bt={narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},zt={narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},Qt={narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},jt={narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},Gt={narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},Xt={any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},Vt={ordinalNumber:_t({matchPattern:Ht,parsePattern:It,valueCallback:n=>parseInt(n,10)}),era:E({matchPatterns:qt,defaultMatchWidth:"wide",parsePatterns:Lt,defaultParseWidth:"any"}),quarter:E({matchPatterns:Rt,defaultMatchWidth:"wide",parsePatterns:Ut,defaultParseWidth:"any",valueCallback:n=>n+1}),month:E({matchPatterns:Bt,defaultMatchWidth:"wide",parsePatterns:zt,defaultParseWidth:"any"}),day:E({matchPatterns:Qt,defaultMatchWidth:"wide",parsePatterns:jt,defaultParseWidth:"any"}),dayPeriod:E({matchPatterns:Gt,defaultMatchWidth:"any",parsePatterns:Xt,defaultParseWidth:"any"})},Jt={code:"en-US",formatDistance:kt,formatLong:Mt,formatRelative:Tt,localize:Yt,match:Vt,options:{weekStartsOn:0,firstWeekContainsDate:1}};function Kt(n,t){const e=k(n,t==null?void 0:t.in);return dt(e,wt(e))+1}function Zt(n,t){const e=k(n,t==null?void 0:t.in),r=+H(e)-+ft(e);return Math.round(r/et)+1}function at(n,t){var f,p,w,m;const e=k(n,t==null?void 0:t.in),r=e.getFullYear(),a=I(),s=(t==null?void 0:t.firstWeekContainsDate)??((p=(f=t==null?void 0:t.locale)==null?void 0:f.options)==null?void 0:p.firstWeekContainsDate)??a.firstWeekContainsDate??((m=(w=a.locale)==null?void 0:w.options)==null?void 0:m.firstWeekContainsDate)??1,i=S((t==null?void 0:t.in)||n,0);i.setFullYear(r+1,0,s),i.setHours(0,0,0,0);const c=A(i,t),l=S((t==null?void 0:t.in)||n,0);l.setFullYear(r,0,s),l.setHours(0,0,0,0);const u=A(l,t);return+e>=+c?r+1:+e>=+u?r:r-1}function te(n,t){var c,l,u,f;const e=I(),r=(t==null?void 0:t.firstWeekContainsDate)??((l=(c=t==null?void 0:t.locale)==null?void 0:c.options)==null?void 0:l.firstWeekContainsDate)??e.firstWeekContainsDate??((f=(u=e.locale)==null?void 0:u.options)==null?void 0:f.firstWeekContainsDate)??1,a=at(n,t),s=S((t==null?void 0:t.in)||n,0);return s.setFullYear(a,0,r),s.setHours(0,0,0,0),A(s,t)}function st(n,t){const e=k(n,t==null?void 0:t.in),r=+A(e,t)-+te(e,t);return Math.round(r/et)+1}function h(n,t){const e=n<0?"-":"",r=Math.abs(n).toString().padStart(t,"0");return e+r}const M={y(n,t){const e=n.getFullYear(),r=e>0?e:1-e;return h(t==="yy"?r%100:r,t.length)},M(n,t){const e=n.getMonth();return t==="M"?String(e+1):h(e+1,2)},d(n,t){return h(n.getDate(),t.length)},a(n,t){const e=n.getHours()/12>=1?"pm":"am";switch(t){case"a":case"aa":return e.toUpperCase();case"aaa":return e;case"aaaaa":return e[0];case"aaaa":default:return e==="am"?"a.m.":"p.m."}},h(n,t){return h(n.getHours()%12||12,t.length)},H(n,t){return h(n.getHours(),t.length)},m(n,t){return h(n.getMinutes(),t.length)},s(n,t){return h(n.getSeconds(),t.length)},S(n,t){const e=t.length,r=n.getMilliseconds(),a=Math.trunc(r*Math.pow(10,e-3));return h(a,t.length)}},C={midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},X={G:function(n,t,e){const r=n.getFullYear()>0?1:0;switch(t){case"G":case"GG":case"GGG":return e.era(r,{width:"abbreviated"});case"GGGGG":return e.era(r,{width:"narrow"});case"GGGG":default:return e.era(r,{width:"wide"})}},y:function(n,t,e){if(t==="yo"){const r=n.getFullYear(),a=r>0?r:1-r;return e.ordinalNumber(a,{unit:"year"})}return M.y(n,t)},Y:function(n,t,e,r){const a=at(n,r),s=a>0?a:1-a;if(t==="YY"){const i=s%100;return h(i,2)}return t==="Yo"?e.ordinalNumber(s,{unit:"year"}):h(s,t.length)},R:function(n,t){const e=nt(n);return h(e,t.length)},u:function(n,t){const e=n.getFullYear();return h(e,t.length)},Q:function(n,t,e){const r=Math.ceil((n.getMonth()+1)/3);switch(t){case"Q":return String(r);case"QQ":return h(r,2);case"Qo":return e.ordinalNumber(r,{unit:"quarter"});case"QQQ":return e.quarter(r,{width:"abbreviated",context:"formatting"});case"QQQQQ":return e.quarter(r,{width:"narrow",context:"formatting"});case"QQQQ":default:return e.quarter(r,{width:"wide",context:"formatting"})}},q:function(n,t,e){const r=Math.ceil((n.getMonth()+1)/3);switch(t){case"q":return String(r);case"qq":return h(r,2);case"qo":return e.ordinalNumber(r,{unit:"quarter"});case"qqq":return e.quarter(r,{width:"abbreviated",context:"standalone"});case"qqqqq":return e.quarter(r,{width:"narrow",context:"standalone"});case"qqqq":default:return e.quarter(r,{width:"wide",context:"standalone"})}},M:function(n,t,e){const r=n.getMonth();switch(t){case"M":case"MM":return M.M(n,t);case"Mo":return e.ordinalNumber(r+1,{unit:"month"});case"MMM":return e.month(r,{width:"abbreviated",context:"formatting"});case"MMMMM":return e.month(r,{width:"narrow",context:"formatting"});case"MMMM":default:return e.month(r,{width:"wide",context:"formatting"})}},L:function(n,t,e){const r=n.getMonth();switch(t){case"L":return String(r+1);case"LL":return h(r+1,2);case"Lo":return e.ordinalNumber(r+1,{unit:"month"});case"LLL":return e.month(r,{width:"abbreviated",context:"standalone"});case"LLLLL":return e.month(r,{width:"narrow",context:"standalone"});case"LLLL":default:return e.month(r,{width:"wide",context:"standalone"})}},w:function(n,t,e,r){const a=st(n,r);return t==="wo"?e.ordinalNumber(a,{unit:"week"}):h(a,t.length)},I:function(n,t,e){const r=Zt(n);return t==="Io"?e.ordinalNumber(r,{unit:"week"}):h(r,t.length)},d:function(n,t,e){return t==="do"?e.ordinalNumber(n.getDate(),{unit:"date"}):M.d(n,t)},D:function(n,t,e){const r=Kt(n);return t==="Do"?e.ordinalNumber(r,{unit:"dayOfYear"}):h(r,t.length)},E:function(n,t,e){const r=n.getDay();switch(t){case"E":case"EE":case"EEE":return e.day(r,{width:"abbreviated",context:"formatting"});case"EEEEE":return e.day(r,{width:"narrow",context:"formatting"});case"EEEEEE":return e.day(r,{width:"short",context:"formatting"});case"EEEE":default:return e.day(r,{width:"wide",context:"formatting"})}},e:function(n,t,e,r){const a=n.getDay(),s=(a-r.weekStartsOn+8)%7||7;switch(t){case"e":return String(s);case"ee":return h(s,2);case"eo":return e.ordinalNumber(s,{unit:"day"});case"eee":return e.day(a,{width:"abbreviated",context:"formatting"});case"eeeee":return e.day(a,{width:"narrow",context:"formatting"});case"eeeeee":return e.day(a,{width:"short",context:"formatting"});case"eeee":default:return e.day(a,{width:"wide",context:"formatting"})}},c:function(n,t,e,r){const a=n.getDay(),s=(a-r.weekStartsOn+8)%7||7;switch(t){case"c":return String(s);case"cc":return h(s,t.length);case"co":return e.ordinalNumber(s,{unit:"day"});case"ccc":return e.day(a,{width:"abbreviated",context:"standalone"});case"ccccc":return e.day(a,{width:"narrow",context:"standalone"});case"cccccc":return e.day(a,{width:"short",context:"standalone"});case"cccc":default:return e.day(a,{width:"wide",context:"standalone"})}},i:function(n,t,e){const r=n.getDay(),a=r===0?7:r;switch(t){case"i":return String(a);case"ii":return h(a,t.length);case"io":return e.ordinalNumber(a,{unit:"day"});case"iii":return e.day(r,{width:"abbreviated",context:"formatting"});case"iiiii":return e.day(r,{width:"narrow",context:"formatting"});case"iiiiii":return e.day(r,{width:"short",context:"formatting"});case"iiii":default:return e.day(r,{width:"wide",context:"formatting"})}},a:function(n,t,e){const a=n.getHours()/12>=1?"pm":"am";switch(t){case"a":case"aa":return e.dayPeriod(a,{width:"abbreviated",context:"formatting"});case"aaa":return e.dayPeriod(a,{width:"abbreviated",context:"formatting"}).toLowerCase();case"aaaaa":return e.dayPeriod(a,{width:"narrow",context:"formatting"});case"aaaa":default:return e.dayPeriod(a,{width:"wide",context:"formatting"})}},b:function(n,t,e){const r=n.getHours();let a;switch(r===12?a=C.noon:r===0?a=C.midnight:a=r/12>=1?"pm":"am",t){case"b":case"bb":return e.dayPeriod(a,{width:"abbreviated",context:"formatting"});case"bbb":return e.dayPeriod(a,{width:"abbreviated",context:"formatting"}).toLowerCase();case"bbbbb":return e.dayPeriod(a,{width:"narrow",context:"formatting"});case"bbbb":default:return e.dayPeriod(a,{width:"wide",context:"formatting"})}},B:function(n,t,e){const r=n.getHours();let a;switch(r>=17?a=C.evening:r>=12?a=C.afternoon:r>=4?a=C.morning:a=C.night,t){case"B":case"BB":case"BBB":return e.dayPeriod(a,{width:"abbreviated",context:"formatting"});case"BBBBB":return e.dayPeriod(a,{width:"narrow",context:"formatting"});case"BBBB":default:return e.dayPeriod(a,{width:"wide",context:"formatting"})}},h:function(n,t,e){if(t==="ho"){let r=n.getHours()%12;return r===0&&(r=12),e.ordinalNumber(r,{unit:"hour"})}return M.h(n,t)},H:function(n,t,e){return t==="Ho"?e.ordinalNumber(n.getHours(),{unit:"hour"}):M.H(n,t)},K:function(n,t,e){const r=n.getHours()%12;return t==="Ko"?e.ordinalNumber(r,{unit:"hour"}):h(r,t.length)},k:function(n,t,e){let r=n.getHours();return r===0&&(r=24),t==="ko"?e.ordinalNumber(r,{unit:"hour"}):h(r,t.length)},m:function(n,t,e){return t==="mo"?e.ordinalNumber(n.getMinutes(),{unit:"minute"}):M.m(n,t)},s:function(n,t,e){return t==="so"?e.ordinalNumber(n.getSeconds(),{unit:"second"}):M.s(n,t)},S:function(n,t){return M.S(n,t)},X:function(n,t,e){const r=n.getTimezoneOffset();if(r===0)return"Z";switch(t){case"X":return J(r);case"XXXX":case"XX":return P(r);case"XXXXX":case"XXX":default:return P(r,":")}},x:function(n,t,e){const r=n.getTimezoneOffset();switch(t){case"x":return J(r);case"xxxx":case"xx":return P(r);case"xxxxx":case"xxx":default:return P(r,":")}},O:function(n,t,e){const r=n.getTimezoneOffset();switch(t){case"O":case"OO":case"OOO":return"GMT"+V(r,":");case"OOOO":default:return"GMT"+P(r,":")}},z:function(n,t,e){const r=n.getTimezoneOffset();switch(t){case"z":case"zz":case"zzz":return"GMT"+V(r,":");case"zzzz":default:return"GMT"+P(r,":")}},t:function(n,t,e){const r=Math.trunc(+n/1e3);return h(r,t.length)},T:function(n,t,e){return h(+n,t.length)}};function V(n,t=""){const e=n>0?"-":"+",r=Math.abs(n),a=Math.trunc(r/60),s=r%60;return s===0?e+String(a):e+String(a)+t+h(s,2)}function J(n,t){return n%60===0?(n>0?"-":"+")+h(Math.abs(n)/60,2):P(n,t)}function P(n,t=""){const e=n>0?"-":"+",r=Math.abs(n),a=h(Math.trunc(r/60),2),s=h(r%60,2);return e+a+t+s}const K=(n,t)=>{switch(n){case"P":return t.date({width:"short"});case"PP":return t.date({width:"medium"});case"PPP":return t.date({width:"long"});case"PPPP":default:return t.date({width:"full"})}},it=(n,t)=>{switch(n){case"p":return t.time({width:"short"});case"pp":return t.time({width:"medium"});case"ppp":return t.time({width:"long"});case"pppp":default:return t.time({width:"full"})}},ee=(n,t)=>{const e=n.match(/(P+)(p+)?/)||[],r=e[1],a=e[2];if(!a)return K(n,t);let s;switch(r){case"P":s=t.dateTime({width:"short"});break;case"PP":s=t.dateTime({width:"medium"});break;case"PPP":s=t.dateTime({width:"long"});break;case"PPPP":default:s=t.dateTime({width:"full"});break}return s.replace("{{date}}",K(r,t)).replace("{{time}}",it(a,t))},ne={p:it,P:ee},re=/^D+$/,ae=/^Y+$/,se=["D","DD","YY","YYYY"];function ie(n){return re.test(n)}function oe(n){return ae.test(n)}function ce(n,t,e){const r=le(n,t,e);if(console.warn(r),se.includes(n))throw new RangeError(r)}function le(n,t,e){const r=n[0]==="Y"?"years":"days of the month";return`Use \`${n.toLowerCase()}\` instead of \`${n}\` (in \`${t}\`) for formatting ${r} to the input \`${e}\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`}const ue=/[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g,he=/P+p+|P+|p+|''|'(''|[^'])+('|$)|./g,de=/^'([^]*?)'?$/,fe=/''/g,me=/[a-zA-Z]/;function ge(n,t,e){var f,p,w,m;const r=I(),a=r.locale??Jt,s=r.firstWeekContainsDate??((p=(f=r.locale)==null?void 0:f.options)==null?void 0:p.firstWeekContainsDate)??1,i=r.weekStartsOn??((m=(w=r.locale)==null?void 0:w.options)==null?void 0:m.weekStartsOn)??0,c=k(n,e==null?void 0:e.in);if(!gt(c))throw new RangeError("Invalid time value");let l=t.match(he).map(g=>{const b=g[0];if(b==="p"||b==="P"){const q=ne[b];return q(g,a.formatLong)}return g}).join("").match(ue).map(g=>{if(g==="''")return{isToken:!1,value:"'"};const b=g[0];if(b==="'")return{isToken:!1,value:ye(g)};if(X[b])return{isToken:!0,value:g};if(b.match(me))throw new RangeError("Format string contains an unescaped latin alphabet character `"+b+"`");return{isToken:!1,value:g}});a.localize.preprocessor&&(l=a.localize.preprocessor(c,l));const u={firstWeekContainsDate:s,weekStartsOn:i,locale:a};return l.map(g=>{if(!g.isToken)return g.value;const b=g.value;(oe(b)||ie(b))&&ce(b,t,String(n));const q=X[b[0]];return q(c,b,a.localize,u)}).join("")}function ye(n){const t=n.match(de);return t?t[1].replace(fe,"'"):n}function pe(n,t){const e=k(n,t==null?void 0:t.in).getDay();return e===0?7:e}const B={},W={};function Y(n,t){try{const r=(B[n]||(B[n]=new Intl.DateTimeFormat("en-GB",{timeZone:n,hour:"numeric",timeZoneName:"longOffset"}).format))(t).split("GMT")[1]||"";return r in W?W[r]:Z(r,r.split(":"))}catch{if(n in W)return W[n];const e=n==null?void 0:n.match(we);return e?Z(n,e.slice(1)):NaN}}const we=/([+-]\d\d):?(\d\d)?/;function Z(n,t){const e=+t[0],r=+(t[1]||0);return W[n]=e>0?e*60+r:e*60-r}class v extends Date{constructor(...t){super(),t.length>1&&typeof t[t.length-1]=="string"&&(this.timeZone=t.pop()),this.internal=new Date,isNaN(Y(this.timeZone,this))?this.setTime(NaN):t.length?typeof t[0]=="number"&&(t.length===1||t.length===2&&typeof t[1]!="number")?this.setTime(t[0]):typeof t[0]=="string"?this.setTime(+new Date(t[0])):t[0]instanceof Date?this.setTime(+t[0]):(this.setTime(+new Date(...t)),ot(this),Q(this)):this.setTime(Date.now())}static tz(t,...e){return e.length?new v(...e,t):new v(Date.now(),t)}withTimeZone(t){return new v(+this,t)}getTimezoneOffset(){return-Y(this.timeZone,this)}setTime(t){return Date.prototype.setTime.apply(this,arguments),Q(this),+this}[Symbol.for("constructDateFrom")](t){return new v(+new Date(t),this.timeZone)}}const tt=/^(get|set)(?!UTC)/;Object.getOwnPropertyNames(Date.prototype).forEach(n=>{if(!tt.test(n))return;const t=n.replace(tt,"$1UTC");v.prototype[t]&&(n.startsWith("get")?v.prototype[n]=function(){return this.internal[t]()}:(v.prototype[n]=function(){return Date.prototype[t].apply(this.internal,arguments),be(this),+this},v.prototype[t]=function(){return Date.prototype[t].apply(this,arguments),Q(this),+this}))});function Q(n){n.internal.setTime(+n),n.internal.setUTCMinutes(n.internal.getUTCMinutes()-n.getTimezoneOffset())}function be(n){Date.prototype.setFullYear.call(n,n.internal.getUTCFullYear(),n.internal.getUTCMonth(),n.internal.getUTCDate()),Date.prototype.setHours.call(n,n.internal.getUTCHours(),n.internal.getUTCMinutes(),n.internal.getUTCSeconds(),n.internal.getUTCMilliseconds()),ot(n)}function ot(n){const t=Y(n.timeZone,n),e=new Date(+n);e.setUTCHours(e.getUTCHours()-1);const r=-new Date(+n).getTimezoneOffset(),a=-new Date(+e).getTimezoneOffset(),s=r-a,i=Date.prototype.getHours.apply(n)!==n.internal.getUTCHours();s&&i&&n.internal.setUTCMinutes(n.internal.getUTCMinutes()+s);const c=r-t;c&&Date.prototype.setUTCMinutes.call(n,Date.prototype.getUTCMinutes.call(n)+c);const l=Y(n.timeZone,n),f=-new Date(+n).getTimezoneOffset()-l,p=l!==t,w=f-c;if(p&&w){Date.prototype.setUTCMinutes.call(n,Date.prototype.getUTCMinutes.call(n)+w);const m=Y(n.timeZone,n),g=l-m;g&&(n.internal.setUTCMinutes(n.internal.getUTCMinutes()+g),Date.prototype.setUTCMinutes.call(n,Date.prototype.getUTCMinutes.call(n)+g))}}class N extends v{static tz(t,...e){return e.length?new N(...e,t):new N(Date.now(),t)}toISOString(){const[t,e,r]=this.tzComponents(),a=`${t}${e}:${r}`;return this.internal.toISOString().slice(0,-1)+a}toString(){return`${this.toDateString()} ${this.toTimeString()}`}toDateString(){const[t,e,r,a]=this.internal.toUTCString().split(" ");return`${t==null?void 0:t.slice(0,-1)} ${r} ${e} ${a}`}toTimeString(){const t=this.internal.toUTCString().split(" ")[4],[e,r,a]=this.tzComponents();return`${t} GMT${e}${r}${a} (${ke(this.timeZone,this)})`}toLocaleString(t,e){return Date.prototype.toLocaleString.call(this,t,{...e,timeZone:(e==null?void 0:e.timeZone)||this.timeZone})}toLocaleDateString(t,e){return Date.prototype.toLocaleDateString.call(this,t,{...e,timeZone:(e==null?void 0:e.timeZone)||this.timeZone})}toLocaleTimeString(t,e){return Date.prototype.toLocaleTimeString.call(this,t,{...e,timeZone:(e==null?void 0:e.timeZone)||this.timeZone})}tzComponents(){const t=this.getTimezoneOffset(),e=t>0?"-":"+",r=String(Math.floor(Math.abs(t)/60)).padStart(2,"0"),a=String(Math.abs(t)%60).padStart(2,"0");return[e,r,a]}withTimeZone(t){return new N(+this,t)}[Symbol.for("constructDateFrom")](t){return new N(+new Date(t),this.timeZone)}}function ke(n,t){return new Intl.DateTimeFormat("en-GB",{timeZone:n,timeZoneName:"long"}).format(t).slice(12)}window.pktTz=window.pktTz===void 0?"Europe/Oslo":window.pktTz;const De=(n=window.pktTz)=>{const t=new N(new Date().toISOString(),n);return t.setHours(0,0,0,0),isNaN(t.getTime())?new Date:new Date(t.getFullYear(),t.getMonth(),t.getDate())};function O(n){if(!n||n==="")return new Date;if(/^\d{4}-\d{2}-\d{2}$/.test(n)){const[t,e,r]=n.split("-").map(Number);return new Date(t,e-1,r)}if(/^\d{4}-\d{2}$/.test(n)){const[t,e]=n.split("-").map(Number);return new Date(t,e-1,1)}return/^\d{4}$/.test(n)?new Date(Number(n),0,1):new Date(n)}const y=n=>{if(!n||isNaN(n.getTime()))return"";const t=n.getFullYear(),e=String(n.getMonth()+1).padStart(2,"0"),r=String(n.getDate()).padStart(2,"0");return`${t}-${e}-${r}`},ve=n=>{if(!n)return null;const t=O(n);return isNaN(t.getTime())?null:t},Se=(n,t)=>{const e=D(n);return isNaN(e.getTime())?"":ge(e,t)},D=(n="",t)=>{const e=typeof n=="string"?O(n):n;return!e||isNaN(e.getTime())?new Date:t?t==="end"?yt(e):z(e):e},x=(n,t,e=1)=>{if(typeof n!="number"||typeof t!="number"||typeof e!="number"||isNaN(n)||isNaN(t)||isNaN(e))return new Date;const r=new Date(n,t,e);return isNaN(r.getTime())?new Date:r},Me=n=>!n||isNaN(n.getTime())?"":new Intl.DateTimeFormat("no",{dateStyle:"full",timeZone:window.pktTz}).format(n),ct=n=>{if(Array.isArray(n))return n;if(typeof n=="string")return n.split(",")},xe=n=>n?O(n):null,Te=n=>{if(typeof n=="string")return n.split(",").map(t=>O(t));if(Array.isArray(n))return n.map(t=>O(t))},_={csvToArray:ct,stringToDate:xe,stringsToDate:Te},Pe={earliest:{default:null},latest:{default:null},weeknumbers:{default:!1},withcontrols:{default:!1},multiple:{default:!1},maxMultiple:{default:4},range:{default:!1}},T={props:Pe};var Oe=Object.defineProperty,Ce=Object.getOwnPropertyDescriptor,d=(n,t,e,r)=>{for(var a=r>1?void 0:r?Ce(t,e):t,s=n.length-1,i;s>=0;s--)(i=n[s])&&(a=(r?i(t,e,a):i(a))||a);return r&&a&&Oe(t,e,a),a};exports.PktCalendar=class extends o.PktElement{constructor(){super(...arguments),this.multiple=T.props.multiple.default,this.maxMultiple=T.props.maxMultiple.default,this.range=T.props.range.default,this.weeknumbers=T.props.weeknumbers.default,this.withcontrols=T.props.withcontrols.default,this.selected=[],this.earliest=T.props.earliest.default,this.latest=T.props.latest.default,this.excludedates=[],this.excludeweekdays=[],this.currentmonth=null,this.dayStrings=this.strings.dates.daysShort,this.dayStringsLong=this.strings.dates.days,this.monthStrings=this.strings.dates.months,this.weekString=this.strings.dates.week,this.prevMonthString=this.strings.dates.prevMonth,this.nextMonthString=this.strings.dates.nextMonth,this._selected=[],this.year=0,this.month=0,this.week=0,this.rangeHovered=null,this.inRange={},this.focusedDate=null,this.selectableDates=[],this.currentmonthtouched=!1,this.tabIndexSet=0}connectedCallback(){super.connectedCallback()}disconnectedCallback(){this.removeEventListener("keydown",this.handleKeydown),super.disconnectedCallback()}attributeChangedCallback(t,e,r){t==="selected"&&r&&this.convertSelected(),super.attributeChangedCallback(t,e,r)}updated(t){super.updated(t),t.has("selected")&&this.convertSelected()}firstUpdated(t){this.addEventListener("keydown",this.handleKeydown)}convertSelected(){if(typeof this.selected=="string"&&(this.selected=this.selected.split(",")),this.selected.length===1&&this.selected[0]===""&&(this.selected=[]),this._selected=this.selected.map(t=>O(t)),this.range&&this.selected.length===2){const t=R({start:this._selected[0],end:this._selected[1]});if(this.inRange={},Array.isArray(t)&&t.length){const e={};for(let r=0;r<t.length;r++)e[y(t[r])]=this.isInRange(t[r]);this.inRange=e}}this.setCurrentMonth()}setCurrentMonth(){if(this.currentmonth===null&&!this.currentmonthtouched){this.currentmonthtouched=!0;return}if(this.selected.length&&this.selected[0]!==""){const t=O(this.selected[this.selected.length-1]);this.currentmonth=isNaN(t.getTime())?new Date:t}else this.currentmonth===null&&(this.currentmonth=new Date);(!this.currentmonth||isNaN(this.currentmonth.getTime()))&&(this.currentmonth=new Date),this.year=this.currentmonth.getFullYear(),this.month=this.currentmonth.getMonth()}handleKeydown(t){switch(t.key){case"ArrowLeft":this.handleArrowKey(t,-1);break;case"ArrowRight":this.handleArrowKey(t,1);break;case"ArrowUp":this.handleArrowKey(t,-7);break;case"ArrowDown":this.handleArrowKey(t,7);break}}handleArrowKey(t,e){var s,i,c;if(((s=t.target)==null?void 0:s.nodeName)==="INPUT"||((i=t.target)==null?void 0:i.nodeName)==="SELECT"||((c=t.target)==null?void 0:c.nodeName)==="BUTTON")return;t.preventDefault(),this.focusedDate||this.focusOnCurrentDate();const r=this.focusedDate?D(this.focusedDate):x(this.year,this.month,1);let a=L(r,e);if(a){let l=this.querySelector(`div[data-date="${y(a)}"]`);if(l instanceof HTMLDivElement){if(l.dataset.disabled){a=L(a,e);let u=this.querySelector(`div[data-date="${y(a)}"]`);for(;u&&u instanceof HTMLDivElement&&u.dataset.disabled;)a=L(a,e),u=this.querySelector(`div[data-date="${y(a)}"]`);l=u}l instanceof HTMLDivElement&&!l.dataset.disabled&&(this.focusedDate=y(a),l.focus())}}}render(){return o.x`
2
- <div
3
- class="pkt-calendar ${this.weeknumbers?"pkt-cal-weeknumbers":o.E}"
4
- @focusout=${this.closeEvent}
5
- @keydown=${t=>{t.key==="Escape"&&(t.preventDefault(),this.close())}}
6
- >
7
- <nav class="pkt-cal-month-nav">
8
- <div>
9
- <button
10
- type="button"
11
- @click=${this.isPrevMonthAllowed()&&this.prevMonth}
12
- @keydown=${t=>{(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.isNextMonthAllowed()&&this.prevMonth())}}
13
- class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--icon-only ${this.isPrevMonthAllowed()?"":"pkt-hide"}"
14
- .data-disabled=${this.isPrevMonthAllowed()?o.E:"disabled"}
15
- ?aria-disabled=${!this.isPrevMonthAllowed()}
16
- tabindex=${this.isPrevMonthAllowed()?"0":"-1"}
17
- >
18
- <pkt-icon class="pkt-btn__icon" name="chevron-thin-left"></pkt-icon>
19
- <span class="pkt-btn__text">${this.prevMonthString}</span>
20
- </button>
21
- </div>
22
- ${this.renderMonthNav()}
23
- <div>
24
- <button
25
- type="button"
26
- @click=${this.isNextMonthAllowed()&&this.nextMonth}
27
- @keydown=${t=>{(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.isNextMonthAllowed()&&this.nextMonth())}}
28
- class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--icon-only ${this.isNextMonthAllowed()?"":"pkt-hide"}"
29
- .data-disabled=${this.isNextMonthAllowed()?o.E:"disabled"}
30
- ?aria-disabled=${!this.isNextMonthAllowed()}
31
- tabindex=${this.isNextMonthAllowed()?"0":"-1"}
32
- >
33
- <pkt-icon class="pkt-btn__icon" name="chevron-thin-right"></pkt-icon>
34
- <span class="pkt-btn__text">${this.nextMonthString}</span>
35
- </button>
36
- </div>
37
- </nav>
38
- <table
39
- class="pkt-cal-days pkt-txt-12-medium"
40
- role="grid"
41
- ?aria-multiselectable=${this.range||this.multiple}
42
- >
43
- <thead>
44
- ${this.renderDayNames()}
45
- </thead>
46
- <tbody>
47
- ${this.renderCalendarBody()}
48
- </tbody>
49
- </table>
50
- </div>
51
- `}renderDayNames(){const t=[];this.weeknumbers&&t.push(o.x`<th><div>${this.weekString}</div></th>`);for(let e=0;e<this.dayStrings.length;e++)t.push(o.x`<th><div aria-label="${this.dayStringsLong[e]}">${this.dayStrings[e]}</div></th>`);return o.x`<tr class="pkt-cal-week-row">
52
- ${t}
53
- </tr>`}renderMonthNav(){let t=[];return this.withcontrols?t.push(o.x`<div class="pkt-cal-month-picker">
54
- <label for="${this.id}-monthnav" class="pkt-hide">${this.strings.dates.month}</label>
55
- <select
56
- aria-label="${this.strings.dates.month}"
57
- class="pkt-input pkt-input-compact"
58
- id="${this.id}-monthnav"
59
- @change=${e=>{e.stopImmediatePropagation(),this.changeMonth(this.year,e.target.value)}}
60
- >
61
- ${this.monthStrings.map((e,r)=>o.x`<option value=${r} ?selected=${this.month===r}>${e}</option>`)}
62
- </select>
63
- <label for="${this.id}-yearnav" class="pkt-hide">${this.strings.dates.year}</label>
64
- <input
65
- aria-label="${this.strings.dates.year}"
66
- class="pkt-input pkt-cal-input-year pkt-input-compact"
67
- id="${this.id}-yearnav"
68
- type="number"
69
- size="4"
70
- placeholder="0000"
71
- @change=${e=>{e.stopImmediatePropagation(),this.changeMonth(e.target.value,this.month)}}
72
- .value=${this.year}
73
- />
74
- </div> `):t.push(o.x`<div class="pkt-txt-16-medium" aria-live="polite">
75
- ${this.monthStrings[this.month]} ${this.year}
76
- </div>`),t}renderDayView(t,e,r){var w;const a=x(this.year,this.month,t),s=y(a),i=s===y(e),c=this.selected.includes(s),l=Me(a),u=this.isExcluded(r,a)||!c&&this.multiple&&this.maxMultiple>0&&this.selected.length>=this.maxMultiple,f=this.focusedDate?this.focusedDate===s&&!u?"0":"-1":!u&&this.tabIndexSet===0||this.tabIndexSet===t?"0":"-1";f==="0"&&(this.tabIndexSet=t),this.selectableDates.push({currentDateISO:s,isDisabled:u,tabindex:f});const p={"pkt-cal-today":i,"pkt-cal-selected":c,"pkt-cal-in-range":this.inRange[s],"pkt-cal-excluded":this.isExcluded(r,a),"pkt-cal-in-range-first":this.range&&(this.selected.length===2||this.rangeHovered!==null)&&s===this.selected[0],"pkt-cal-in-range-last":this.range&&this.selected.length===2&&s===this.selected[1],"pkt-cal-range-hover":this.rangeHovered!==null&&s===y(this.rangeHovered)};return o.x`<td class=${lt.e(p)}>
77
- <div
78
- ?aria-selected=${c}
79
- role="gridcell"
80
- class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--label-only"
81
- @mouseover=${()=>this.range&&!this.isExcluded(r,a)&&this.handleRangeHover(a)}
82
- @focus=${()=>{this.range&&!this.isExcluded(r,a)&&this.handleRangeHover(a),this.focusedDate=s}}
83
- aria-label="${l}"
84
- tabindex=${(w=this.selectableDates.find(m=>m.currentDateISO===s))==null?void 0:w.tabindex}
85
- data-disabled=${u?"disabled":o.E}
86
- data-date=${s}
87
- @keydown=${m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),this.handleDateSelect(a))}}
88
- @click=${m=>{u||(m.preventDefault(),this.handleDateSelect(a))}}
89
- >
90
- <span class="pkt-btn__text pkt-txt-14-light">${t}</span>
91
- </div>
92
- </td>`}renderCalendarBody(){const t=De(),e=x(this.year,this.month,1),r=x(this.year,this.month+1,0),a=(e.getDay()+6)%7,s=r.getDate(),i=Math.ceil((s+a)/7),l=x(this.year,this.month,0).getDate();let u=1;this.week=st(x(this.year,this.month,1));const f=[];for(let p=0;p<i;p++){const w=[];this.weeknumbers&&w.push(o.x`<td class="pkt-cal-week">${this.week}</td>`),this.week++;for(let m=1;m<8;m++)if(p===0&&m<a+1){const g=l-(a-m);w.push(o.x`<td class="pkt-cal-other">
93
- <div
94
- class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--label-only"
95
- data-disabled="disabled"
96
- >
97
- <span class="pkt-btn__text pkt-txt-14-light">${g}</span>
98
- </div>
99
- </td>`)}else u>s?(w.push(o.x`<td class="pkt-cal-other">
100
- <div
101
- class="pkt-btn pkt-btn--tertiary pkt-btn--small pkt-btn--label-only"
102
- data-disabled="disabled"
103
- >
104
- <span class="pkt-btn__text pkt-txt-14-light">${u-s}</span>
105
- </div>
106
- </td>`),u++):(w.push(this.renderDayView(u,t,m)),u++);f.push(o.x`<tr class="pkt-cal-week-row" role="row">
107
- ${w}
108
- </tr>`)}return f}isExcluded(t,e){return this.excludeweekdays.includes(t.toString())||this.earliest&&D(e,"end")<D(this.earliest,"start")||this.latest&&D(e,"start")>D(this.latest,"end")?!0:this.excludedates.some(r=>typeof r=="string"?r===y(e):r.toDateString()===e.toDateString())}isPrevMonthAllowed(){const t=x(this.year,this.month,0);return!(this.earliest&&D(this.earliest)>t)}prevMonth(){const t=this.month===0?11:this.month-1,e=this.month===0?this.year-1:this.year;this.changeMonth(e,t)}isNextMonthAllowed(){const t=x(this.month===11?this.year+1:this.year,this.month===11?0:this.month+1,1);return!(this.latest&&D(this.latest)<t)}nextMonth(){const t=this.month===11?0:this.month+1,e=this.month===11?this.year+1:this.year;this.changeMonth(e,t)}changeMonth(t,e){this.year=typeof t=="string"?parseInt(t):t,this.month=typeof e=="string"?parseInt(e):e,this.tabIndexSet=0,this.focusedDate=null,this.selectableDates=[]}isInRange(t){if(this.range&&this.selected.length===2){if(t>D(this.selected[0])&&t<D(this.selected[1]))return!0}else if(this.range&&this.selected.length===1&&this.rangeHovered&&t>D(this.selected[0])&&t<this.rangeHovered)return!0;return!1}isRangeAllowed(t){let e=!0;if(this._selected.length===1){const r=R({start:this._selected[0],end:t});if(Array.isArray(r)&&r.length)for(let a=0;a<r.length;a++)this.excludedates.forEach(s=>{s>this._selected[0]&&s<t&&(e=!1)}),this.excludeweekdays.includes(pe(r[a]).toString())&&(e=!1)}return e}emptySelected(){this.selected=[],this._selected=[],this.inRange={}}addToSelected(t){this.selected.includes(y(t))||(this.selected=[...this.selected,y(t)],this._selected=[...this._selected,t],this.range&&this.selected.length===2&&this.close())}removeFromSelected(t){if(this.selected.length===1)this.emptySelected();else{const e=this.selected.indexOf(y(t)),r=[...this.selected],a=[...this._selected];r.splice(e,1),a.splice(e,1),this.selected=r,this._selected=a}}toggleSelected(t){const e=y(t);this.selected.includes(e)?this.removeFromSelected(t):this.maxMultiple&&this.selected.length>=this.maxMultiple||this.addToSelected(t)}handleRangeSelect(t){const e=y(t);return this.selected.includes(e)?this.selected.indexOf(e)===0?this.emptySelected():this.removeFromSelected(t):this.selected.length>1?(this.emptySelected(),this.addToSelected(t)):(this.selected.length===1&&!this.isRangeAllowed(t)&&this.emptySelected(),this.selected.length===1&&this._selected[0]>t&&this.emptySelected(),this.addToSelected(t)),Promise.resolve()}handleRangeHover(t){if(this.range&&this._selected.length===1&&this.isRangeAllowed(t)&&this._selected[0]<t){this.rangeHovered=t,this.inRange={};const e=R({start:this._selected[0],end:t});if(Array.isArray(e)&&e.length)for(let r=0;r<e.length;r++)this.inRange[y(e[r])]=this.isInRange(e[r])}else this.rangeHovered=null}handleDateSelect(t){if(t)return this.range?this.handleRangeSelect(t):this.multiple?this.toggleSelected(t):(this.selected.includes(y(t))?this.emptySelected():(this.emptySelected(),this.addToSelected(t)),this.close()),this.dispatchEvent(new CustomEvent("date-selected",{detail:this.selected,bubbles:!0,composed:!0})),Promise.resolve()}focusOnCurrentDate(){const t=y(D()),e=this.querySelector(`div[data-date="${t}"]`);if(e instanceof HTMLDivElement)this.focusedDate=t,e.focus();else{const r=this.selectableDates.find(a=>!a.isDisabled);if(r){const a=this.querySelector(`div[data-date="${r.currentDateISO}"]`);a instanceof HTMLDivElement&&(this.focusedDate=r.currentDateISO,a.focus())}}}closeEvent(t){!this.contains(t.relatedTarget)&&!t.target.classList.contains("pkt-hide")&&this.close()}close(){this.dispatchEvent(new CustomEvent("close",{detail:!0,bubbles:!0,composed:!0}))}};d([o.n({type:Boolean})],exports.PktCalendar.prototype,"multiple",2);d([o.n({type:Number})],exports.PktCalendar.prototype,"maxMultiple",2);d([o.n({type:Boolean})],exports.PktCalendar.prototype,"range",2);d([o.n({type:Boolean})],exports.PktCalendar.prototype,"weeknumbers",2);d([o.n({type:Boolean})],exports.PktCalendar.prototype,"withcontrols",2);d([o.n({converter:_.csvToArray})],exports.PktCalendar.prototype,"selected",2);d([o.n({type:String})],exports.PktCalendar.prototype,"earliest",2);d([o.n({type:String})],exports.PktCalendar.prototype,"latest",2);d([o.n({converter:_.stringsToDate})],exports.PktCalendar.prototype,"excludedates",2);d([o.n({converter:_.csvToArray})],exports.PktCalendar.prototype,"excludeweekdays",2);d([o.n({converter:_.stringToDate})],exports.PktCalendar.prototype,"currentmonth",2);d([o.n({type:Array})],exports.PktCalendar.prototype,"dayStrings",2);d([o.n({type:Array})],exports.PktCalendar.prototype,"dayStringsLong",2);d([o.n({type:Array})],exports.PktCalendar.prototype,"monthStrings",2);d([o.n({type:String})],exports.PktCalendar.prototype,"weekString",2);d([o.n({type:String})],exports.PktCalendar.prototype,"prevMonthString",2);d([o.n({type:String})],exports.PktCalendar.prototype,"nextMonthString",2);d([o.n({type:Array})],exports.PktCalendar.prototype,"_selected",2);d([o.n({type:Number})],exports.PktCalendar.prototype,"year",2);d([o.n({type:Number})],exports.PktCalendar.prototype,"month",2);d([o.n({type:Number})],exports.PktCalendar.prototype,"week",2);d([o.n({type:Date})],exports.PktCalendar.prototype,"rangeHovered",2);d([F.r()],exports.PktCalendar.prototype,"inRange",2);d([F.r()],exports.PktCalendar.prototype,"focusedDate",2);d([F.r()],exports.PktCalendar.prototype,"selectableDates",2);d([F.r()],exports.PktCalendar.prototype,"currentmonthtouched",2);d([F.r()],exports.PktCalendar.prototype,"tabIndexSet",2);exports.PktCalendar=d([o.t("pkt-calendar")],exports.PktCalendar);exports.converters=_;exports.csvToArray=ct;exports.formatISODate=y;exports.fromISOToDate=ve;exports.fromISOtoLocal=Se;exports.newDate=D;