This commit is contained in:
darenhsu
2022-07-17 13:16:16 +08:00
parent 84759556ff
commit befd344ab0
28070 changed files with 4008428 additions and 1 deletions
+103
View File
@@ -0,0 +1,103 @@
// Mixins
import mixins from '../../../util/mixins';
import Colorable from '../../../mixins/colorable';
import Localable from '../../../mixins/localable';
import Mouse from './mouse';
import Themeable from '../../../mixins/themeable';
import Times from './times'; // Directives
import Resize from '../../../directives/resize'; // Util
import props from '../util/props';
import { parseTimestamp, getWeekdaySkips, createDayList, createNativeLocaleFormatter, getStartOfWeek, getEndOfWeek, getTimestampIdentifier } from '../util/timestamp';
export default mixins(Colorable, Localable, Mouse, Themeable, Times
/* @vue/component */
).extend({
name: 'calendar-base',
directives: {
Resize
},
props: props.base,
computed: {
parsedWeekdays() {
return Array.isArray(this.weekdays) ? this.weekdays : (this.weekdays || '').split(',').map(x => parseInt(x, 10));
},
weekdaySkips() {
return getWeekdaySkips(this.parsedWeekdays);
},
weekdaySkipsReverse() {
const reversed = this.weekdaySkips.slice();
reversed.reverse();
return reversed;
},
parsedStart() {
return parseTimestamp(this.start, true);
},
parsedEnd() {
const start = this.parsedStart;
const end = this.end ? parseTimestamp(this.end) || start : start;
return getTimestampIdentifier(end) < getTimestampIdentifier(start) ? start : end;
},
days() {
return createDayList(this.parsedStart, this.parsedEnd, this.times.today, this.weekdaySkips);
},
dayFormatter() {
if (this.dayFormat) {
return this.dayFormat;
}
const options = {
timeZone: 'UTC',
day: 'numeric'
};
return createNativeLocaleFormatter(this.currentLocale, (_tms, _short) => options);
},
weekdayFormatter() {
if (this.weekdayFormat) {
return this.weekdayFormat;
}
const longOptions = {
timeZone: 'UTC',
weekday: 'long'
};
const shortOptions = {
timeZone: 'UTC',
weekday: 'short'
};
return createNativeLocaleFormatter(this.currentLocale, (_tms, short) => short ? shortOptions : longOptions);
}
},
methods: {
getRelativeClasses(timestamp, outside = false) {
return {
'v-present': timestamp.present,
'v-past': timestamp.past,
'v-future': timestamp.future,
'v-outside': outside
};
},
getStartOfWeek(timestamp) {
return getStartOfWeek(timestamp, this.parsedWeekdays, this.times.today);
},
getEndOfWeek(timestamp) {
return getEndOfWeek(timestamp, this.parsedWeekdays, this.times.today);
},
getFormatter(options) {
return createNativeLocaleFormatter(this.locale, (_tms, _short) => options);
}
}
});
//# sourceMappingURL=calendar-base.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,462 @@
// Styles
import "../../../../src/components/VCalendar/mixins/calendar-with-events.sass"; // Directives
import ripple from '../../../directives/ripple'; // Mixins
import CalendarBase from './calendar-base'; // Helpers
import { escapeHTML } from '../../../util/helpers'; // Util
import props from '../util/props';
import { CalendarEventOverlapModes } from '../modes';
import { getDayIdentifier, diffMinutes } from '../util/timestamp';
import { parseEvent, isEventStart, isEventOn, isEventOverlapping } from '../util/events';
const WIDTH_FULL = 100;
const WIDTH_START = 95;
const MINUTES_IN_DAY = 1440;
/* @vue/component */
export default CalendarBase.extend({
name: 'calendar-with-events',
directives: {
ripple
},
props: props.events,
computed: {
noEvents() {
return this.events.length === 0;
},
parsedEvents() {
return this.events.map(this.parseEvent);
},
parsedEventOverlapThreshold() {
return parseInt(this.eventOverlapThreshold);
},
eventColorFunction() {
return typeof this.eventColor === 'function' ? this.eventColor : () => this.eventColor;
},
eventTimedFunction() {
return typeof this.eventTimed === 'function' ? this.eventTimed : event => !!event[this.eventTimed];
},
eventCategoryFunction() {
return typeof this.eventCategory === 'function' ? this.eventCategory : event => event[this.eventCategory];
},
eventTextColorFunction() {
return typeof this.eventTextColor === 'function' ? this.eventTextColor : () => this.eventTextColor;
},
eventNameFunction() {
return typeof this.eventName === 'function' ? this.eventName : (event, timedEvent) => escapeHTML(event.input[this.eventName]);
},
eventModeFunction() {
return typeof this.eventOverlapMode === 'function' ? this.eventOverlapMode : CalendarEventOverlapModes[this.eventOverlapMode];
},
eventWeekdays() {
return this.parsedWeekdays;
},
categoryMode() {
return false;
}
},
methods: {
parseEvent(input, index = 0) {
return parseEvent(input, index, this.eventStart, this.eventEnd, this.eventTimedFunction(input), this.categoryMode ? this.eventCategoryFunction(input) : false);
},
formatTime(withTime, ampm) {
const formatter = this.getFormatter({
timeZone: 'UTC',
hour: 'numeric',
minute: withTime.minute > 0 ? 'numeric' : undefined
});
return formatter(withTime, true);
},
updateEventVisibility() {
if (this.noEvents || !this.eventMore) {
return;
}
const eventHeight = this.eventHeight;
const eventsMap = this.getEventsMap();
for (const date in eventsMap) {
const {
parent,
events,
more
} = eventsMap[date];
if (!more) {
break;
}
const parentBounds = parent.getBoundingClientRect();
const last = events.length - 1;
let hide = false;
let hidden = 0;
for (let i = 0; i <= last; i++) {
if (!hide) {
const eventBounds = events[i].getBoundingClientRect();
hide = i === last ? eventBounds.bottom > parentBounds.bottom : eventBounds.bottom + eventHeight > parentBounds.bottom;
}
if (hide) {
events[i].style.display = 'none';
hidden++;
}
}
if (hide) {
more.style.display = '';
more.innerHTML = this.$vuetify.lang.t(this.eventMoreText, hidden);
} else {
more.style.display = 'none';
}
}
},
getEventsMap() {
const eventsMap = {};
const elements = this.$refs.events;
if (!elements || !elements.forEach) {
return eventsMap;
}
elements.forEach(el => {
const date = el.getAttribute('data-date');
if (el.parentElement && date) {
if (!(date in eventsMap)) {
eventsMap[date] = {
parent: el.parentElement,
more: null,
events: []
};
}
if (el.getAttribute('data-more')) {
eventsMap[date].more = el;
} else {
eventsMap[date].events.push(el);
el.style.display = '';
}
}
});
return eventsMap;
},
genDayEvent({
event
}, day) {
const eventHeight = this.eventHeight;
const eventMarginBottom = this.eventMarginBottom;
const dayIdentifier = getDayIdentifier(day);
const week = day.week;
const start = dayIdentifier === event.startIdentifier;
let end = dayIdentifier === event.endIdentifier;
let width = WIDTH_START;
if (!this.categoryMode) {
for (let i = day.index + 1; i < week.length; i++) {
const weekdayIdentifier = getDayIdentifier(week[i]);
if (event.endIdentifier >= weekdayIdentifier) {
width += WIDTH_FULL;
end = end || weekdayIdentifier === event.endIdentifier;
} else {
end = true;
break;
}
}
}
const scope = {
eventParsed: event,
day,
start,
end,
timed: false
};
return this.genEvent(event, scope, false, {
staticClass: 'v-event',
class: {
'v-event-start': start,
'v-event-end': end
},
style: {
height: `${eventHeight}px`,
width: `${width}%`,
'margin-bottom': `${eventMarginBottom}px`
},
attrs: {
'data-date': day.date
},
key: event.index,
ref: 'events',
refInFor: true
});
},
genTimedEvent({
event,
left,
width
}, day) {
if (day.timeDelta(event.end) <= 0 || day.timeDelta(event.start) >= 1) {
return false;
}
const dayIdentifier = getDayIdentifier(day);
const start = event.startIdentifier >= dayIdentifier;
const end = event.endIdentifier > dayIdentifier;
const top = start ? day.timeToY(event.start) : 0;
const bottom = end ? day.timeToY(MINUTES_IN_DAY) : day.timeToY(event.end);
const height = Math.max(this.eventHeight, bottom - top);
const scope = {
eventParsed: event,
day,
start,
end,
timed: true
};
return this.genEvent(event, scope, true, {
staticClass: 'v-event-timed',
style: {
top: `${top}px`,
height: `${height}px`,
left: `${left}%`,
width: `${width}%`
}
});
},
genEvent(event, scopeInput, timedEvent, data) {
const slot = this.$scopedSlots.event;
const text = this.eventTextColorFunction(event.input);
const background = this.eventColorFunction(event.input);
const overlapsNoon = event.start.hour < 12 && event.end.hour >= 12;
const singline = diffMinutes(event.start, event.end) <= this.parsedEventOverlapThreshold;
const formatTime = this.formatTime;
const timeSummary = () => formatTime(event.start, overlapsNoon) + ' - ' + formatTime(event.end, true);
const eventSummary = () => {
const name = this.eventNameFunction(event, timedEvent);
if (event.start.hasTime) {
if (timedEvent) {
const time = timeSummary();
const delimiter = singline ? ', ' : '<br>';
return `<strong>${name}</strong>${delimiter}${time}`;
} else {
const time = formatTime(event.start, true);
return `<strong>${time}</strong> ${name}`;
}
}
return name;
};
const scope = { ...scopeInput,
event: event.input,
outside: scopeInput.day.outside,
singline,
overlapsNoon,
formatTime,
timeSummary,
eventSummary
};
return this.$createElement('div', this.setTextColor(text, this.setBackgroundColor(background, {
on: this.getDefaultMouseEventHandlers(':event', nativeEvent => ({ ...scope,
nativeEvent
})),
directives: [{
name: 'ripple',
value: this.eventRipple != null ? this.eventRipple : true
}],
...data
})), slot ? slot(scope) : [this.genName(eventSummary)]);
},
genName(eventSummary) {
return this.$createElement('div', {
staticClass: 'pl-1',
domProps: {
innerHTML: eventSummary()
}
});
},
genPlaceholder(day) {
const height = this.eventHeight + this.eventMarginBottom;
return this.$createElement('div', {
style: {
height: `${height}px`
},
attrs: {
'data-date': day.date
},
ref: 'events',
refInFor: true
});
},
genMore(day) {
const eventHeight = this.eventHeight;
const eventMarginBottom = this.eventMarginBottom;
return this.$createElement('div', {
staticClass: 'v-event-more pl-1',
class: {
'v-outside': day.outside
},
attrs: {
'data-date': day.date,
'data-more': 1
},
directives: [{
name: 'ripple',
value: this.eventRipple != null ? this.eventRipple : true
}],
on: {
click: () => this.$emit('click:more', day)
},
style: {
display: 'none',
height: `${eventHeight}px`,
'margin-bottom': `${eventMarginBottom}px`
},
ref: 'events',
refInFor: true
});
},
getVisibleEvents() {
const start = getDayIdentifier(this.days[0]);
const end = getDayIdentifier(this.days[this.days.length - 1]);
return this.parsedEvents.filter(event => isEventOverlapping(event, start, end));
},
isEventForCategory(event, category) {
return !this.categoryMode || category === event.category || typeof event.category !== 'string' && category === null;
},
getEventsForDay(day) {
const identifier = getDayIdentifier(day);
const firstWeekday = this.eventWeekdays[0];
return this.parsedEvents.filter(event => isEventStart(event, day, identifier, firstWeekday));
},
getEventsForDayAll(day) {
const identifier = getDayIdentifier(day);
const firstWeekday = this.eventWeekdays[0];
return this.parsedEvents.filter(event => event.allDay && (this.categoryMode ? isEventOn(event, identifier) : isEventStart(event, day, identifier, firstWeekday)) && this.isEventForCategory(event, day.category));
},
getEventsForDayTimed(day) {
const identifier = getDayIdentifier(day);
return this.parsedEvents.filter(event => !event.allDay && isEventOn(event, identifier) && this.isEventForCategory(event, day.category));
},
getScopedSlots() {
if (this.noEvents) {
return { ...this.$scopedSlots
};
}
const mode = this.eventModeFunction(this.parsedEvents, this.eventWeekdays[0], this.parsedEventOverlapThreshold);
const isNode = input => !!input;
const getSlotChildren = (day, getter, mapper, timed) => {
const events = getter(day);
const visuals = mode(day, events, timed, this.categoryMode);
if (timed) {
return visuals.map(visual => mapper(visual, day)).filter(isNode);
}
const children = [];
visuals.forEach((visual, index) => {
while (children.length < visual.column) {
children.push(this.genPlaceholder(day));
}
const mapped = mapper(visual, day);
if (mapped) {
children.push(mapped);
}
});
return children;
};
const slots = this.$scopedSlots;
const slotDay = slots.day;
const slotDayHeader = slots['day-header'];
const slotDayBody = slots['day-body'];
return { ...slots,
day: day => {
let children = getSlotChildren(day, this.getEventsForDay, this.genDayEvent, false);
if (children && children.length > 0 && this.eventMore) {
children.push(this.genMore(day));
}
if (slotDay) {
const slot = slotDay(day);
if (slot) {
children = children ? children.concat(slot) : slot;
}
}
return children;
},
'day-header': day => {
let children = getSlotChildren(day, this.getEventsForDayAll, this.genDayEvent, false);
if (slotDayHeader) {
const slot = slotDayHeader(day);
if (slot) {
children = children ? children.concat(slot) : slot;
}
}
return children;
},
'day-body': day => {
const events = getSlotChildren(day, this.getEventsForDayTimed, this.genTimedEvent, true);
let children = [this.$createElement('div', {
staticClass: 'v-event-timed-container'
}, events)];
if (slotDayBody) {
const slot = slotDayBody(day);
if (slot) {
children = children.concat(slot);
}
}
return children;
}
};
}
}
});
//# sourceMappingURL=calendar-with-events.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,161 @@
// Mixins
import CalendarBase from './calendar-base'; // Util
import props from '../util/props';
import { parseTime, copyTimestamp, updateMinutes, createDayList, createIntervalList, createNativeLocaleFormatter, MINUTES_IN_DAY } from '../util/timestamp';
/* @vue/component */
export default CalendarBase.extend({
name: 'calendar-with-intervals',
props: props.intervals,
computed: {
parsedFirstInterval() {
return parseInt(this.firstInterval);
},
parsedIntervalMinutes() {
return parseInt(this.intervalMinutes);
},
parsedIntervalCount() {
return parseInt(this.intervalCount);
},
parsedIntervalHeight() {
return parseFloat(this.intervalHeight);
},
parsedFirstTime() {
return parseTime(this.firstTime);
},
firstMinute() {
const time = this.parsedFirstTime;
return time !== false && time >= 0 && time <= MINUTES_IN_DAY ? time : this.parsedFirstInterval * this.parsedIntervalMinutes;
},
bodyHeight() {
return this.parsedIntervalCount * this.parsedIntervalHeight;
},
days() {
return createDayList(this.parsedStart, this.parsedEnd, this.times.today, this.weekdaySkips, this.maxDays);
},
intervals() {
const days = this.days;
const first = this.firstMinute;
const minutes = this.parsedIntervalMinutes;
const count = this.parsedIntervalCount;
const now = this.times.now;
return days.map(d => createIntervalList(d, first, minutes, count, now));
},
intervalFormatter() {
if (this.intervalFormat) {
return this.intervalFormat;
}
const longOptions = {
timeZone: 'UTC',
hour: '2-digit',
minute: '2-digit'
};
const shortOptions = {
timeZone: 'UTC',
hour: 'numeric',
minute: '2-digit'
};
const shortHourOptions = {
timeZone: 'UTC',
hour: 'numeric'
};
return createNativeLocaleFormatter(this.currentLocale, (tms, short) => short ? tms.minute === 0 ? shortHourOptions : shortOptions : longOptions);
}
},
methods: {
showIntervalLabelDefault(interval) {
const first = this.intervals[0][0];
const isFirst = first.hour === interval.hour && first.minute === interval.minute;
return !isFirst;
},
intervalStyleDefault(_interval) {
return undefined;
},
getTimestampAtEvent(e, day) {
const timestamp = copyTimestamp(day);
const bounds = e.currentTarget.getBoundingClientRect();
const baseMinutes = this.firstMinute;
const touchEvent = e;
const mouseEvent = e;
const touches = touchEvent.changedTouches || touchEvent.touches;
const clientY = touches && touches[0] ? touches[0].clientY : mouseEvent.clientY;
const addIntervals = (clientY - bounds.top) / this.parsedIntervalHeight;
const addMinutes = Math.floor(addIntervals * this.parsedIntervalMinutes);
const minutes = baseMinutes + addMinutes;
return updateMinutes(timestamp, minutes, this.times.now);
},
getSlotScope(timestamp) {
const scope = copyTimestamp(timestamp);
scope.timeToY = this.timeToY;
scope.timeDelta = this.timeDelta;
scope.minutesToPixels = this.minutesToPixels;
scope.week = this.days;
return scope;
},
scrollToTime(time) {
const y = this.timeToY(time);
const pane = this.$refs.scrollArea;
if (y === false || !pane) {
return false;
}
pane.scrollTop = y;
return true;
},
minutesToPixels(minutes) {
return minutes / this.parsedIntervalMinutes * this.parsedIntervalHeight;
},
timeToY(time, clamp = true) {
let y = this.timeDelta(time);
if (y !== false) {
y *= this.bodyHeight;
if (clamp) {
if (y < 0) {
y = 0;
}
if (y > this.bodyHeight) {
y = this.bodyHeight;
}
}
}
return y;
},
timeDelta(time) {
const minutes = parseTime(time);
if (minutes === false) {
return false;
}
const min = this.firstMinute;
const gap = this.parsedIntervalCount * this.parsedIntervalMinutes;
return (minutes - min) / gap;
}
}
});
//# sourceMappingURL=calendar-with-intervals.js.map
File diff suppressed because one or more lines are too long
+87
View File
@@ -0,0 +1,87 @@
import Vue from 'vue';
export default Vue.extend({
name: 'mouse',
methods: {
getDefaultMouseEventHandlers(suffix, getEvent) {
return this.getMouseEventHandlers({
['click' + suffix]: {
event: 'click'
},
['contextmenu' + suffix]: {
event: 'contextmenu',
prevent: true,
result: false
},
['mousedown' + suffix]: {
event: 'mousedown'
},
['mousemove' + suffix]: {
event: 'mousemove'
},
['mouseup' + suffix]: {
event: 'mouseup'
},
['mouseenter' + suffix]: {
event: 'mouseenter'
},
['mouseleave' + suffix]: {
event: 'mouseleave'
},
['touchstart' + suffix]: {
event: 'touchstart'
},
['touchmove' + suffix]: {
event: 'touchmove'
},
['touchend' + suffix]: {
event: 'touchend'
}
}, getEvent);
},
getMouseEventHandlers(events, getEvent) {
const on = {};
for (const event in events) {
const eventOptions = events[event];
if (!this.$listeners[event]) continue; // TODO somehow pull in modifiers
const prefix = eventOptions.passive ? '&' : (eventOptions.once ? '~' : '') + (eventOptions.capture ? '!' : '');
const key = prefix + eventOptions.event;
const handler = e => {
const mouseEvent = e;
if (eventOptions.button === undefined || mouseEvent.buttons > 0 && mouseEvent.button === eventOptions.button) {
if (eventOptions.prevent) {
e.preventDefault();
}
if (eventOptions.stop) {
e.stopPropagation();
}
this.$emit(event, getEvent(e));
}
return eventOptions.result;
};
if (key in on) {
/* istanbul ignore next */
if (Array.isArray(on[key])) {
on[key].push(handler);
} else {
on[key] = [on[key], handler];
}
} else {
on[key] = handler;
}
}
return on;
}
}
});
//# sourceMappingURL=mouse.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/components/VCalendar/mixins/mouse.ts"],"names":[],"mappings":"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","sourcesContent":["import Vue from 'vue'\n\nexport type MouseHandler = (e: MouseEvent | TouchEvent) => any\n\nexport type MouseEvents = {\n [event: string]: {\n event: string\n passive?: boolean\n capture?: boolean\n once?: boolean\n stop?: boolean\n prevent?: boolean\n button?: number\n result?: any\n }\n}\n\nexport type MouseEventsMap = {\n [event: string]: MouseHandler | MouseHandler[]\n}\n\nexport default Vue.extend({\n name: 'mouse',\n\n methods: {\n getDefaultMouseEventHandlers (suffix: string, getEvent: MouseHandler): MouseEventsMap {\n return this.getMouseEventHandlers({\n ['click' + suffix]: { event: 'click' },\n ['contextmenu' + suffix]: { event: 'contextmenu', prevent: true, result: false },\n ['mousedown' + suffix]: { event: 'mousedown' },\n ['mousemove' + suffix]: { event: 'mousemove' },\n ['mouseup' + suffix]: { event: 'mouseup' },\n ['mouseenter' + suffix]: { event: 'mouseenter' },\n ['mouseleave' + suffix]: { event: 'mouseleave' },\n ['touchstart' + suffix]: { event: 'touchstart' },\n ['touchmove' + suffix]: { event: 'touchmove' },\n ['touchend' + suffix]: { event: 'touchend' },\n }, getEvent)\n },\n getMouseEventHandlers (events: MouseEvents, getEvent: MouseHandler): MouseEventsMap {\n const on: MouseEventsMap = {}\n\n for (const event in events) {\n const eventOptions = events[event]\n\n if (!this.$listeners[event]) continue\n\n // TODO somehow pull in modifiers\n\n const prefix = eventOptions.passive ? '&' : ((eventOptions.once ? '~' : '') + (eventOptions.capture ? '!' : ''))\n const key = prefix + eventOptions.event\n\n const handler: MouseHandler = e => {\n const mouseEvent: MouseEvent = e as MouseEvent\n if (eventOptions.button === undefined || (mouseEvent.buttons > 0 && mouseEvent.button === eventOptions.button)) {\n if (eventOptions.prevent) {\n e.preventDefault()\n }\n if (eventOptions.stop) {\n e.stopPropagation()\n }\n this.$emit(event, getEvent(e))\n }\n\n return eventOptions.result\n }\n\n if (key in on) {\n /* istanbul ignore next */\n if (Array.isArray(on[key])) {\n (on[key] as MouseHandler[]).push(handler)\n } else {\n on[key] = [on[key], handler] as MouseHandler[]\n }\n } else {\n on[key] = handler\n }\n }\n\n return on\n },\n },\n})\n"],"sourceRoot":"","file":"mouse.js"}
+70
View File
@@ -0,0 +1,70 @@
import Vue from 'vue';
import { validateTimestamp, parseTimestamp, parseDate } from '../util/timestamp';
export default Vue.extend({
name: 'times',
props: {
now: {
type: String,
validator: validateTimestamp
}
},
data: () => ({
times: {
now: parseTimestamp('0000-00-00 00:00', true),
today: parseTimestamp('0000-00-00', true)
}
}),
computed: {
parsedNow() {
return this.now ? parseTimestamp(this.now, true) : null;
}
},
watch: {
parsedNow: 'updateTimes'
},
created() {
this.updateTimes();
this.setPresent();
},
methods: {
setPresent() {
this.times.now.present = this.times.today.present = true;
this.times.now.past = this.times.today.past = false;
this.times.now.future = this.times.today.future = false;
},
updateTimes() {
const now = this.parsedNow || this.getNow();
this.updateDay(now, this.times.now);
this.updateTime(now, this.times.now);
this.updateDay(now, this.times.today);
},
getNow() {
return parseDate(new Date());
},
updateDay(now, target) {
if (now.date !== target.date) {
target.year = now.year;
target.month = now.month;
target.day = now.day;
target.weekday = now.weekday;
target.date = now.date;
}
},
updateTime(now, target) {
if (now.time !== target.time) {
target.hour = now.hour;
target.minute = now.minute;
target.time = now.time;
}
}
}
});
//# sourceMappingURL=times.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/components/VCalendar/mixins/times.ts"],"names":[],"mappings":"AAAA,OAAO,GAAP,MAAgB,KAAhB;AAEA,SACE,iBADF,EAEE,cAFF,EAGE,SAHF,QAIO,mBAJP;AAOA,eAAe,GAAG,CAAC,MAAJ,CAAW;AACxB,EAAA,IAAI,EAAE,OADkB;AAGxB,EAAA,KAAK,EAAE;AACL,IAAA,GAAG,EAAE;AACH,MAAA,IAAI,EAAE,MADH;AAEH,MAAA,SAAS,EAAE;AAFR;AADA,GAHiB;AAUxB,EAAA,IAAI,EAAE,OAAO;AACX,IAAA,KAAK,EAAE;AACL,MAAA,GAAG,EAAE,cAAc,CAAC,kBAAD,EAAqB,IAArB,CADd;AAEL,MAAA,KAAK,EAAE,cAAc,CAAC,YAAD,EAAe,IAAf;AAFhB;AADI,GAAP,CAVkB;AAiBxB,EAAA,QAAQ,EAAE;AACR,IAAA,SAAS,GAAA;AACP,aAAO,KAAK,GAAL,GAAW,cAAc,CAAC,KAAK,GAAN,EAAW,IAAX,CAAzB,GAA4C,IAAnD;AACD;;AAHO,GAjBc;AAuBxB,EAAA,KAAK,EAAE;AACL,IAAA,SAAS,EAAE;AADN,GAvBiB;;AA2BxB,EAAA,OAAO,GAAA;AACL,SAAK,WAAL;AACA,SAAK,UAAL;AACD,GA9BuB;;AAgCxB,EAAA,OAAO,EAAE;AACP,IAAA,UAAU,GAAA;AACR,WAAK,KAAL,CAAW,GAAX,CAAe,OAAf,GAAyB,KAAK,KAAL,CAAW,KAAX,CAAiB,OAAjB,GAA2B,IAApD;AACA,WAAK,KAAL,CAAW,GAAX,CAAe,IAAf,GAAsB,KAAK,KAAL,CAAW,KAAX,CAAiB,IAAjB,GAAwB,KAA9C;AACA,WAAK,KAAL,CAAW,GAAX,CAAe,MAAf,GAAwB,KAAK,KAAL,CAAW,KAAX,CAAiB,MAAjB,GAA0B,KAAlD;AACD,KALM;;AAMP,IAAA,WAAW,GAAA;AACT,YAAM,GAAG,GAAsB,KAAK,SAAL,IAAkB,KAAK,MAAL,EAAjD;AACA,WAAK,SAAL,CAAe,GAAf,EAAoB,KAAK,KAAL,CAAW,GAA/B;AACA,WAAK,UAAL,CAAgB,GAAhB,EAAqB,KAAK,KAAL,CAAW,GAAhC;AACA,WAAK,SAAL,CAAe,GAAf,EAAoB,KAAK,KAAL,CAAW,KAA/B;AACD,KAXM;;AAYP,IAAA,MAAM,GAAA;AACJ,aAAO,SAAS,CAAC,IAAI,IAAJ,EAAD,CAAhB;AACD,KAdM;;AAeP,IAAA,SAAS,CAAE,GAAF,EAA0B,MAA1B,EAAmD;AAC1D,UAAI,GAAG,CAAC,IAAJ,KAAa,MAAM,CAAC,IAAxB,EAA8B;AAC5B,QAAA,MAAM,CAAC,IAAP,GAAc,GAAG,CAAC,IAAlB;AACA,QAAA,MAAM,CAAC,KAAP,GAAe,GAAG,CAAC,KAAnB;AACA,QAAA,MAAM,CAAC,GAAP,GAAa,GAAG,CAAC,GAAjB;AACA,QAAA,MAAM,CAAC,OAAP,GAAiB,GAAG,CAAC,OAArB;AACA,QAAA,MAAM,CAAC,IAAP,GAAc,GAAG,CAAC,IAAlB;AACD;AACF,KAvBM;;AAwBP,IAAA,UAAU,CAAE,GAAF,EAA0B,MAA1B,EAAmD;AAC3D,UAAI,GAAG,CAAC,IAAJ,KAAa,MAAM,CAAC,IAAxB,EAA8B;AAC5B,QAAA,MAAM,CAAC,IAAP,GAAc,GAAG,CAAC,IAAlB;AACA,QAAA,MAAM,CAAC,MAAP,GAAgB,GAAG,CAAC,MAApB;AACA,QAAA,MAAM,CAAC,IAAP,GAAc,GAAG,CAAC,IAAlB;AACD;AACF;;AA9BM;AAhCe,CAAX,CAAf","sourcesContent":["import Vue from 'vue'\n\nimport {\n validateTimestamp,\n parseTimestamp,\n parseDate,\n} from '../util/timestamp'\nimport { CalendarTimestamp } from 'vuetify/types'\n\nexport default Vue.extend({\n name: 'times',\n\n props: {\n now: {\n type: String,\n validator: validateTimestamp,\n },\n },\n\n data: () => ({\n times: {\n now: parseTimestamp('0000-00-00 00:00', true),\n today: parseTimestamp('0000-00-00', true),\n },\n }),\n\n computed: {\n parsedNow (): CalendarTimestamp | null {\n return this.now ? parseTimestamp(this.now, true) : null\n },\n },\n\n watch: {\n parsedNow: 'updateTimes',\n },\n\n created () {\n this.updateTimes()\n this.setPresent()\n },\n\n methods: {\n setPresent (): void {\n this.times.now.present = this.times.today.present = true\n this.times.now.past = this.times.today.past = false\n this.times.now.future = this.times.today.future = false\n },\n updateTimes (): void {\n const now: CalendarTimestamp = this.parsedNow || this.getNow()\n this.updateDay(now, this.times.now)\n this.updateTime(now, this.times.now)\n this.updateDay(now, this.times.today)\n },\n getNow (): CalendarTimestamp {\n return parseDate(new Date())\n },\n updateDay (now: CalendarTimestamp, target: CalendarTimestamp): void {\n if (now.date !== target.date) {\n target.year = now.year\n target.month = now.month\n target.day = now.day\n target.weekday = now.weekday\n target.date = now.date\n }\n },\n updateTime (now: CalendarTimestamp, target: CalendarTimestamp): void {\n if (now.time !== target.time) {\n target.hour = now.hour\n target.minute = now.minute\n target.time = now.time\n }\n },\n },\n})\n"],"sourceRoot":"","file":"times.js"}