diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 66d89ca4..96a565c6 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,7 +17,8 @@ "qrious": "^4.0.2", "qs": "^6.13.1", "vue": "^3.5.13", - "vue-i18n": "^11.1.4" + "vue-i18n": "^11.1.4", + "vue3-persian-datetime-picker": "^1.2.2" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.6", @@ -961,8 +962,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/boolbase": { "version": "1.0.0", @@ -974,7 +974,6 @@ "version": "1.1.14", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1069,8 +1068,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/core-js": { "version": "3.49.0", @@ -1549,6 +1547,11 @@ "node": ">= 6" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1606,6 +1609,26 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -1720,6 +1743,21 @@ "node": ">=0.8.19" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1755,6 +1793,11 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jalaali-js": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/jalaali-js/-/jalaali-js-1.2.8.tgz", + "integrity": "sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2142,7 +2185,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2158,6 +2200,28 @@ "node": "*" } }, + "node_modules/moment-jalaali": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/moment-jalaali/-/moment-jalaali-0.9.6.tgz", + "integrity": "sha512-v8wXjQplvk5ez+sUqgsWIrafwIf1BEXXvzTYwsg1wHcqh27nSgKPCJ6FnZRrCz03MoNyB9N31L0oms+vE8Rq7g==", + "dependencies": { + "jalaali-js": "^1.1.0", + "moment": "^2.22.2", + "moment-timezone": "^0.5.21", + "rimraf": "^3.0.2" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2215,6 +2279,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -2294,6 +2366,14 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2419,6 +2499,21 @@ "node": ">=4" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rolldown": { "version": "1.0.0-rc.18", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.18.tgz", @@ -2879,6 +2974,14 @@ "vue": "^3.0.0" } }, + "node_modules/vue3-persian-datetime-picker": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vue3-persian-datetime-picker/-/vue3-persian-datetime-picker-1.2.2.tgz", + "integrity": "sha512-d7nkj5vgtUvEXZboSdRmP1uwBfXvXgXqdvsOOMQb34jiMZU/aBDrTYWTEe1N+XKF9pvTTJn8Rws9ttJmyhK/hw==", + "dependencies": { + "moment-jalaali": "^0.9.4" + } + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -2911,6 +3014,11 @@ "node": ">=0.10.0" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index c59727f5..a835827a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,7 +20,8 @@ "qrious": "^4.0.2", "qs": "^6.13.1", "vue": "^3.5.13", - "vue-i18n": "^11.1.4" + "vue-i18n": "^11.1.4", + "vue3-persian-datetime-picker": "^1.2.2" }, "devDependencies": { "@vitejs/plugin-vue": "^6.0.6", diff --git a/frontend/src/components/DateTimePicker.vue b/frontend/src/components/DateTimePicker.vue new file mode 100644 index 00000000..c17bb457 --- /dev/null +++ b/frontend/src/components/DateTimePicker.vue @@ -0,0 +1,383 @@ + + + + + + + + diff --git a/frontend/src/composables/useDatepicker.js b/frontend/src/composables/useDatepicker.js new file mode 100644 index 00000000..03eba91c --- /dev/null +++ b/frontend/src/composables/useDatepicker.js @@ -0,0 +1,45 @@ +// Module-scoped reactive ref for the panel's "Calendar Type" setting. +// Loaded from /panel/setting/defaultSettings on first use, so any +// component (modals, inbound forms, future pages) can read the same +// value without prop-drilling and without re-fetching. +// +// useInbounds (which already reads defaultSettings for its own state) +// calls setDatepicker() after its fetch so we don't issue a second +// HTTP round-trip on the inbounds page. + +import { readonly, ref } from 'vue'; +import { HttpUtil } from '@/utils'; + +const datepicker = ref('gregorian'); +let fetched = false; +let pending = null; + +async function loadOnce() { + if (fetched) return; + if (pending) { + await pending; + return; + } + pending = (async () => { + try { + const msg = await HttpUtil.post('/panel/setting/defaultSettings'); + if (msg?.success) { + datepicker.value = msg.obj?.datepicker || 'gregorian'; + } + } finally { + fetched = true; + pending = null; + } + })(); + await pending; +} + +export function setDatepicker(value) { + fetched = true; + datepicker.value = value || 'gregorian'; +} + +export function useDatepicker() { + loadOnce(); + return { datepicker: readonly(datepicker) }; +} diff --git a/frontend/src/models/dbinbound.js b/frontend/src/models/dbinbound.js index 404498eb..61e08c8b 100644 --- a/frontend/src/models/dbinbound.js +++ b/frontend/src/models/dbinbound.js @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import { ObjectUtil, NumberFormatter, SizeFormatter } from '@/utils'; import { Inbound, Protocols } from './inbound.js'; @@ -78,7 +79,7 @@ export class DBInbound { if (this.expiryTime === 0) { return null; } - return moment(this.expiryTime); + return dayjs(this.expiryTime); } set _expiryTime(t) { diff --git a/frontend/src/models/inbound.js b/frontend/src/models/inbound.js index 791885e9..c17c894e 100644 --- a/frontend/src/models/inbound.js +++ b/frontend/src/models/inbound.js @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import { ObjectUtil, RandomUtil, Base64, NumberFormatter, SizeFormatter, Wireguard } from '@/utils'; export const Protocols = { @@ -2523,7 +2524,7 @@ Inbound.ClientBase = class extends XrayCommonClass { if (this.expiryTime < 0) { return this.expiryTime / -86400000; } - return moment(this.expiryTime); + return dayjs(this.expiryTime); } set _expiryTime(t) { diff --git a/frontend/src/pages/inbounds/ClientBulkModal.vue b/frontend/src/pages/inbounds/ClientBulkModal.vue index 8c94c849..1f9ca72f 100644 --- a/frontend/src/pages/inbounds/ClientBulkModal.vue +++ b/frontend/src/pages/inbounds/ClientBulkModal.vue @@ -13,6 +13,7 @@ import { USERS_SECURITY, TLS_FLOW_CONTROL, } from '@/models/inbound.js'; +import DateTimePicker from '@/components/DateTimePicker.vue'; // Bulk-add up to 500 clients in one go. The legacy panel offers five // generation modes — this component preserves them all: @@ -250,8 +251,7 @@ async function submit() { {{ t('pages.inbounds.expireDate') }} - + diff --git a/frontend/src/pages/inbounds/ClientFormModal.vue b/frontend/src/pages/inbounds/ClientFormModal.vue index 2ae3d658..a70e69f0 100644 --- a/frontend/src/pages/inbounds/ClientFormModal.vue +++ b/frontend/src/pages/inbounds/ClientFormModal.vue @@ -11,6 +11,7 @@ import { ColorUtils, } from '@/utils'; import { Inbound, Protocols, USERS_SECURITY, TLS_FLOW_CONTROL } from '@/models/inbound.js'; +import DateTimePicker from '@/components/DateTimePicker.vue'; const { t } = useI18n(); @@ -363,8 +364,7 @@ const title = computed(() => {{ t('pages.inbounds.expireDate') }} - + {{ t('depleted') }} diff --git a/frontend/src/pages/inbounds/InboundFormModal.vue b/frontend/src/pages/inbounds/InboundFormModal.vue index f2fd332c..227ae68e 100644 --- a/frontend/src/pages/inbounds/InboundFormModal.vue +++ b/frontend/src/pages/inbounds/InboundFormModal.vue @@ -30,6 +30,7 @@ import { } from '@/models/inbound.js'; import { DBInbound } from '@/models/dbinbound.js'; import FinalMaskForm from '@/components/FinalMaskForm.vue'; +import DateTimePicker from '@/components/DateTimePicker.vue'; const { t } = useI18n(); @@ -572,8 +573,7 @@ watch( {{ t('pages.inbounds.expireDate') }} - + @@ -667,8 +667,7 @@ watch( - + diff --git a/frontend/src/pages/inbounds/useInbounds.js b/frontend/src/pages/inbounds/useInbounds.js index 3e6af2d2..d5bb982f 100644 --- a/frontend/src/pages/inbounds/useInbounds.js +++ b/frontend/src/pages/inbounds/useInbounds.js @@ -9,6 +9,7 @@ import { computed, ref, shallowRef } from 'vue'; import { HttpUtil, ObjectUtil } from '@/utils'; import { DBInbound } from '@/models/dbinbound.js'; import { Protocols } from '@/models/inbound.js'; +import { setDatepicker } from '@/composables/useDatepicker.js'; const ONLINE_GRACE_MS = 60_000; @@ -146,6 +147,9 @@ export function useInbounds() { pageSize.value = s.pageSize ?? 0; remarkModel.value = s.remarkModel || '-ieo'; datepicker.value = s.datepicker || 'gregorian'; + // Mirror into the global composable so date-pickers in modals can + // pick the right calendar without re-fetching the settings. + setDatepicker(datepicker.value); ipLimitEnable.value = !!s.ipLimitEnable; } diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 663770ff..8f49efa9 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -127,6 +127,14 @@ export default defineConfig({ if (id.includes('dayjs')) return 'vendor-dayjs'; if (id.includes('qrious')) return 'vendor-qrious'; if (id.includes('axios')) return 'vendor-axios'; + // The persian datepicker pulls in moment + moment-jalaali; bundle + // the trio together so unrelated pages don't pay the cost. + if ( + id.includes('vue3-persian-datetime-picker') + || id.includes('moment-jalaali') + || id.includes('jalaali-js') + || id.includes('/node_modules/moment/') + ) return 'vendor-jalali'; return 'vendor'; }, }, diff --git a/web/assets/moment/moment-jalali.min.js b/web/assets/moment/moment-jalali.min.js deleted file mode 100644 index 8b6ebfde..00000000 --- a/web/assets/moment/moment-jalali.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){function t(e){var n=t.modules[e];if(!n)throw new Error('failed to require "'+e+'"');return"exports"in n||"function"!=typeof n.definition||(n.client=n.component=!0,n.definition.call(this,n.exports={},n),delete n.definition),n.exports}t.modules={moment:{exports:moment}},t.register=function(e,n){t.modules[e]={definition:n}},t.define=function(e,n){t.modules[e]={exports:n}},t.register("jalaali-js",(function(t,e){function n(t){return 0===a(t).leap}function r(t,e){return e<=6?31:e<=11||n(t)?30:29}function a(t){var e,n,r,a,i,s,o=[-61,9,38,199,426,686,756,818,1111,1181,1210,1635,2060,2097,2192,2262,2324,2394,2456,3178],u=o.length,f=t+621,l=-14,j=o[0];if(t=o[u-1])throw new Error("Invalid Jalaali year "+t);for(s=1;s=0){if(e<=185)return{jy:r,jm:1+c(e,31),jd:h(e,31)+1};e-=186}else r-=1,e+=179,1===i.leap&&(e+=1);return{jy:r,jm:7+c(e,30),jd:h(e,30)+1}}function o(t,e,n){var r=c(1461*(t+c(e-8,6)+100100),4)+c(153*h(e+9,12)+2,5)+n-34840408;return r=r-c(3*c(t+100100+c(e-8,6),100),4)+752}function u(t){var e,n,r,a;return e=(e=4*t+139361631)+4*c(3*c(4*t+183187720,146097),4)-3908,n=5*c(h(e,1461),4)+308,r=c(h(n,153),5)+1,a=h(c(n,153),12)+1,{gy:c(e,1461)-100100+c(8-a,6),gm:a,gd:r}}function c(t,e){return~~(t/e)}function h(t,e){return t-~~(t/e)*e}e.exports={toJalaali:function(t,e,n){"[object Date]"===Object.prototype.toString.call(t)&&(n=t.getDate(),e=t.getMonth()+1,t=t.getFullYear());return s(o(t,e,n))},toGregorian:function(t,e,n){return u(i(t,e,n))},isValidJalaaliDate:function(t,e,n){return t>=-61&&t<=3177&&e>=1&&e<=12&&n>=1&&n<=r(t,e)},isLeapJalaaliYear:n,jalaaliMonthLength:r,jalCal:a,j2d:i,d2j:s,g2d:o,d2g:u}})),t.register("moment-jalaali",(function(e,n){n.exports=W;var r,a=t("moment"),i=t("jalaali-js"),s=/(\[[^\[]*\])|(\\)?j(Mo|MM?M?M?|Do|DDDo|DD?D?D?|w[o|w]?|YYYYY|YYYY|YY|gg(ggg?)?|)|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,o=/(\[[^\[]*\])|(\\)?(LTS?|LL?L?L?|l{1,4})/g,u=/\d\d?/,c=/\d{1,3}/,h=/\d{3}/,f=/\d{1,4}/,l=/[+\-]?\d{1,6}/,j=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,_=/Z|[\+\-]\d\d:?\d\d/i,d=/T/i,D=/[\+\-]?\d+(\.\d{1,3})?/,M={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},Y={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},m={jm:"jmonth",jmonths:"jmonth",jy:"jyear",jyears:"jyear"},g={},p="DDD w M D".split(" "),y="M D w".split(" "),v={jM:function(){return this.jMonth()+1},jMMM:function(t){return this.localeData().jMonthsShort(this,t)},jMMMM:function(t){return this.localeData().jMonths(this,t)},jD:function(){return this.jDate()},jDDD:function(){return this.jDayOfYear()},jw:function(){return this.jWeek()},jYY:function(){return S(this.jYear()%100,2)},jYYYY:function(){return S(this.jYear(),4)},jYYYYY:function(){return S(this.jYear(),5)},jgg:function(){return S(this.jWeekYear()%100,2)},jgggg:function(){return this.jWeekYear()},jggggg:function(){return S(this.jWeekYear(),5)}};function w(t,e){return function(n){return S(t.call(this,n),e)}}function L(t,e){return function(n){return this.localeData().ordinal(t.call(this,n),e)}}function O(t,e){var n;for(n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}function S(t,e){for(var n=t+"";n.length47?1300:1400);break;case"jYYYY":case"jYYYYY":i[0]=~~e}null==e&&(n._isValid=!1)}function x(t){var e,n,r,a=t._f.match(s),i=t._i+"",o=a.length;for(t._a=[],e=0;eW.jDaysInMonth(r,a)||a<0||a>11)&&(t._isValid=!1),n=A((e=E(r,a,i)).gy,e.gm,e.gd),isNaN(e.gy)&&(t._isValid=!1),t._jDiff=0,~~n.jy!==r&&(t._jDiff+=1),~~n.jm!==a&&(t._jDiff+=1),~~n.jd!==i&&(t._jDiff+=1),[e.gy,e.gm,e.gd])}(t)}function P(t,e,n){var r,a=n-e,i=n-t.day();return i>a&&(i-=7),i57724432199999&&(c._isValid=!1),c}function W(t,e,n,r){return V(t,e,n,r,!1)}function C(t,e){for(var n=5,r=function(t){return e.localeData().longDateFormat(t)||t};n>0&&o.test(t);)n-=1,t=t.replace(o,r);return t}function A(t,e,n){try{var r=i.toJalaali(t,e+1,n);return r.jm-=1,r}catch(t){return{jy:NaN,jm:NaN,jd:NaN}}}function E(t,e,n){try{var r=i.toGregorian(t,e+1,n);return r.gm-=1,r}catch(t){return{gy:NaN,gm:NaN,gd:NaN}}}function H(t,e){return~~(t/e)}function G(t,e){return t-~~(t/e)*e}O(W,a),W.fn=F(a.fn),W.utc=function(t,e,n,r){return V(t,e,n,r,!0)},W.unix=function(t){return V(1e3*t)},W.fn.format=function(t){return t&&(t=C(t,this),g[t]||(g[t]=function(t){var e,n=t.match(s),r=n.length;for(e=0;e1&&void 0!==arguments[1]?arguments[1]:2,e=String(Math.abs(t)),i=e.length,o="";for(t<0&&(o+="-");i1999?u=o.year:ua.year&&(u=a.year),isNaN(h)||h<1||h>12?h=o.month:u<=r.year&&h=a.year&&h>a.month&&(h=a.month),isNaN(d)||d<1?d=o.day:h<=r.month&&d=a.month&&d>a.day&&(d=a.day),{year:parseInt(u),month:parseInt(h),day:parseInt(d)}},c=function(t,n,e){var i=s(n,e),o=t.initTime,a=t.options.maxTime,r=t.options.minTime,u=i.hour,h=i.minute,d=i.second;return isNaN(u)||u<0||u>23?u=o.hour:ua.hour&&(u=a.hour),isNaN(h)||h<0||h>59?h=o.minute:u<=r.hour&&h=a.hour&&h>a.minute&&(h=a.minute),isNaN(d)||d<0||d>59?d=o.second:u<=r.hour&&h<=r.minute&&d=a.hour&&h>=a.minute&&d>a.second&&(d=a.second),{hour:parseInt(u),minute:parseInt(h),second:parseInt(d)}},p=function(t,n,e,i){var o=t.options.minDate,a=t.options.maxDate,s=l(t,{year:n,month:e,day:i});return o=r(o)?s:l(t,{year:o.year,month:o.month,day:o.day}),s<=(a=r(a)?s:l(t,{year:a.year,month:a.month,day:a.day}))&&s>=o},m=function(t,n){var e=t.options.separatorChars,i=n.split(e.between),o=t.options.date?i[0].split(e.date):{},a=t.options.date?t.options.time&&i[1]?i[1].split(e.time):{}:i[0].split(e.time);return{year:parseInt(o[0]),month:parseInt(o[1]),day:parseInt(o[2]),hour:parseInt(a[0]),minute:parseInt(a[1]),second:parseInt(a[2])}},l=function(t,n){var e=t.options.separatorChars;return"".concat(n.year).concat(e.date).concat(h(n.month)).concat(e.date).concat(h(n.day))},y=function(t,n){if(!n)return!1;var e=n.substr(0,10).split(t.options.separatorChars.date);return 3===e.length&&4===e[0].length&&2===e[1].length&&2===e[2].length},f=function(t,n){if(!n)return!1;var e=n.substr(t.options.date?11:0,8).split(t.options.separatorChars.time);return e.length===(t.options.hasSecond?3:2)&&!e.find((function(t){return 2!==t.toString().length}))},v="jdp",g="".concat(v,"-container"),D="".concat(v,"-overlay"),w="div.".concat(v,"-years"),_="div.".concat(v,"-year"),b="div.".concat(v,"-months"),C="div.".concat(v,"-month"),T="div.".concat(v,"-days"),x="div.".concat(v,"-day"),I="div.".concat(v,"-day.not-in-month"),M="div.".concat(v,"-day.disabled-day"),S="".concat(I,".disabled-day"),A="div.".concat(v,"-day-name"),E="div.".concat(v,"-icon-plus"),O="div.".concat(v,"-icon-minus"),j="div.".concat(v,"-footer"),N="div.".concat(v,"-btn-today"),P="div.".concat(v,"-btn-empty"),V="div.".concat(v,"-btn-close"),B="div.".concat(v,"-time-container"),H="div.".concat(v,"-time"),Y="not-in-range",L="holly-day",k="".concat(v,":change"),z="click",R="focusin",J="today",W="attr",q="data-jdp-only-date",F="data-jdp-only-time",X=("data-".concat(v),"visible"),G="block",K="none",Q=function t(n){if(["html","body","#document"].indexOf((n.nodeName||"").toLowerCase())>=0)return window;if(n instanceof HTMLElement){var e=window.getComputedStyle(n),i=e.overflow,o=e.overflowX,a=e.overflowY;if(/auto|scroll|overlay/.test(i+a+o))return n}return t(n.parentNode)},U=function(t){var n=document.createEvent("Event");return n.initEvent(t,!0,!0),n},Z=function(t,n){t&&(t.dispatchEvent(U(n)),n===k&&(t.dispatchEvent(U("change")),t.dispatchEvent(U("input"))))},$=function(t,n,i,a,r){var s=t.split(".");t=s.shift()||"div";var u=s,h=window.document.createElement(t);return o(n)?window.document.querySelector(n).appendChild(h):n.appendChild(h),u.length&&(h.className=u.join(" ")),i&&a&&function(t,n,e){for(var i=n.split(" "),o=0,a=i.length;o2e3||t.yearChange(n.target.value)}));if(i)for(var a=function(t){function n(t){return 100*Math.round(t/100)}var e=t.initDate.year;return{min:t.options.minDate.year||n(e-200),max:t.options.maxDate.year||n(e+200)}}(t),r=a.min;r<=a.max;r++){var s=$("option",o);s.value=r,s.text=nt(r,t.options.persianDigits),s.selected=r===t.initDate.year}else o.tabIndex=-1,o.value=t.initDate.year,o.type="number"},mt=function(t){pt(t),function(t){var n=$(b,t.dpContainer);dt(t,n,!1);var e=$(C,n);ct(t,n,!1);var i=$("select",e,"change",(function(n){t.monthChange(n.target.value)}));i.tabIndex=-1;for(var o=function(t){var n=t.initDate.year,e=t.options.minDate,i=t.options.maxDate,o=[],a=1,r=12;n===e.year?(a=e.month,n===i.year&&(r=i.month)):n===i.year&&(a=1,r=i.month);for(var s=a;s<=r;s++)o.push(s);return o}(t),a=t.options.months,r=0;r=r+f,(a.inBeforeMonth||a.inAfterMonth)&&(a.inBeforeMonth?(v++,a.day=v,a.year=m,a.month=d):(g++,a.day=g,a.year=l,a.month=c)),a.isValid=p(t,a.year,a.month,a.day),a.className=ht(it(a.year,a.month,a.day)),t.inputValue.day===a.day&&t.inputValue.year===a.year&&t.inputValue.month===a.month&&(a.className+=".".concat("selected")),t.today.day===a.day&&t.today.year===a.year&&t.today.month===a.month&&(a.className+=".".concat("today")),i(t.options.dayRendering)&&s(a,t.options.dayRendering(a,t.input)),a.isHollyDay&&(a.className+=".".concat(L));var u=a.isValid?x:M;(a.inBeforeMonth||a.inAfterMonth)&&(u=I,a.isValid||(u=S));var h=$(u+a.className,n,null,null,nt(a.day,t.options.persianDigits));h.day=a.day,h.month=a.month,h.year=a.year,a.isValid&&h.addEventListener(z,(function(){t.setValue({year:h.year,month:h.month,day:h.day})})),o(a)},w=0;w<=h;w++)D(w)}(t)},lt=function(t){var n,e=$(j,t.dpContainer);if(t.options.showTodayBtn&&t.options.date){var i=function(t){return p(t,t.today.year,t.today.month,t.today.day)}(t);$(N+(i?"":".disabled-btn"),e,z,(function(){i&&t.setValue(t.today)}),"امروز")}t.options.date||!t.options.time||null!==(n=t.input)&&void 0!==n&&n.value||$(N,e,z,(function(){t.setValue(t.initTime),t.hide()}),"انتخاب"),t.options.showEmptyBtn&&$(P,e,z,(function(){t.input.value="",Z(t.input,k),t.options.hideAfterChange&&t.hide()}),"خالی"),t.options.showCloseBtn&&$(V,e,z,(function(){t.hide()}),"بستن")},yt=function(t){tt(t.dpContainer,""),t.options.date&&mt(t),t.options.time&&function(t){var n=B+(t.options.time&&!t.options.date?".jdp-only-time":""),e=$(n,t.dpContainer);t.options.hasSecond&&ut(t,e,"second"),ut(t,e,"minute"),ut(t,e,"hour")}(t),lt(t)};var ft=/iphone|ipod|android|ie|blackberry|fennec/.test(null===(at=window.navigator)||void 0===at||null===(rt=at.userAgent)||void 0===rt?void 0:rt.toLowerCase()),vt={init:function(t){var n;this.updateOptions(t),Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector,window.addEventListener("resize",(function(){vt.setPosition()})),this.options.autoHide&&document.body.addEventListener("click",(function(t){var n,e,o;vt.isShow&&(n=vt.dpContainer,!((o=(e=t).path||e.composedPath&&e.composedPath()||!1)?-1!==o.indexOf(n):n.outerHTML.indexOf(e.target.outerHTML)>-1))&&function(t){try{return i(t.composedPath)?t.composedPath()[0]:t.target}catch(n){return t.target}}(t)!==vt.input&&vt.hide()})),this.options.autoShow&&(n=this.options.selector,document.body.addEventListener(R,(function(t){t.target&&t.target.matches(n)&&vt.show(t.target)})))},updateOptions:function(t){this.options=Dt(t)},options:a({days:["ش","ی","د","س","چ","پ","ج"],months:["فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"],initDate:null,today:null,initTime:null,hasSecond:!0,time:!1,date:!0,minDate:{},maxDate:{},minTime:{},maxTime:{},separatorChars:{date:"/",between:" ",time:":"},persianDigits:!1,zIndex:1e3,container:"body",selector:"input[data-jdp]",autoShow:!0,autoHide:!0,hideAfterChange:!0,plusHtml:'',minusHtml:'',changeMonthRotateYear:!1,showTodayBtn:!0,showEmptyBtn:!0,showCloseBtn:ft,autoReadOnlyInput:ft,useDropDownYears:!0,topSpace:0,bottomSpace:0}),input:null,get dpContainer(){return this._dpContainer||(this._dpContainer=$(g,this.options.container),this.overlayElm=$(D,this.options.container),this.dpContainer.style.zIndex=this.options.zIndex,this.overlayElm.style.zIndex=this.options.zIndex-1),this._dpContainer},get today(){return this._today=this._today||this.options.today||function(){var t,n,e=new Date,i=parseInt(e.getFullYear()),o=parseInt(e.getMonth())+1,a=parseInt(e.getDate());i>1600?(t=979,i-=1600):(t=0,i-=621);var r=o>2?i+1:i;return n=365*i+parseInt((r+3)/4)-parseInt((r+99)/100)+parseInt((r+399)/400)-80+a+[0,31,59,90,120,151,181,212,243,273,304,334][o-1],t+=33*parseInt(n/12053),n%=12053,t+=4*parseInt(n/1461),(n%=1461)>365&&(t+=parseInt((n-1)/365),n=(n-1)%365),{year:t,month:n<186?1+parseInt(n/31):7+parseInt((n-186)/30),day:1+(n<186?n%31:(n-186)%30)}}(),this._today},get inputValue(){var t=a(this.input.value);return t=function(t,n){if(!n)return!1;var e=t.options.separatorChars,i=t.options.date?"\\d{4}".concat(e.date,"\\d{2}").concat(e.date,"\\d{2}"):"",o=t.options.time?"\\d{2}".concat(e.time,"\\d{2}")+(t.options.hasSecond?"".concat(e.time,"\\d{2}"):""):"";return new RegExp(i+(i&&o?e.between:"")+o).test(n,"g")}(this,t)||o(t)&&y(this,t)?m(this,t):{}},get initDate(){return this.options.initDate?this.options.initDate:(this._initDate||(this._initDate=a(this.input.value)||{},r(this._initDate)?this._initDate=this.options.initDate||a(this.today):o(this._initDate)&&y(this,this._initDate)?this._initDate=m(this,this._initDate):this._initDate=a(this.today),this._initDate=d(this,this._initDate)),this._initDate)},get initTime(){if(this._initTime)return this._initTime;var t=new Date,n={hour:t.getHours(),minute:t.getMinutes(),second:0};return this._initTime=a(this.input.value)||this.options.initTime||n,o(this._initTime)&&(f(this,this._initTime)?this._initTime=m(this,this._initTime):this._initTime=n),this._initTime=c(this,this._initTime),this._initTime},_draw:function(){yt(this)},show:function(t){var n=this;this._initDate=null,this._initTime=null,this._value=null,this.input=t,this._draw(),function(t,n){n.autoReadOnlyInput&&!t.readOnly&&(t.setAttribute("readonly","readonly"),t.readOnly=!0)}(t,this.options),this.dpContainer.style.visibility=X,this.dpContainer.style.display=G,this.overlayElm.style.display=G,setTimeout((function(){n.dpContainer.style.visibility=X,n.dpContainer.style.display=G,n.overlayElm.style.display=G,n.isShow=!0}),300),this.setPosition(),function(t){Q(t).addEventListener("scroll",(function(){vt.setPosition()}),{passive:!0})}(t)},hide:function(){this.dpContainer.style.visibility="hidden",this.dpContainer.style.display=K,this.overlayElm.style.display=K,this.isShow=!1},setPosition:function(){if(this.dpContainer.style.visibility===X){var t=this.input.getBoundingClientRect(),n=t.height,e=t.left,i=t.top+n;i+=this.options.topSpace;var o=window.document.body.offsetWidth,a=this.dpContainer.offsetWidth,r=this.dpContainer.offsetHeight;e+a>=o&&(e-=e+a-(o+10)),i-n>=r&&i+r>=window.innerHeight&&(i-=r+n+this.options.bottomSpace+this.options.topSpace),this.dpContainer.style.position="fixed",this.dpContainer.style.left=e+"px",this.dpContainer.style.top=i+"px"}},get getValue(){return this._value=this._value||this.inputValue||{},this._value},setValue:function(t){var n,e,i,o,a;this._value=s({year:this.today.year,month:this.today.month,day:this.today.day,hour:this.initTime.hour,minute:this.initTime.minute,second:this.initTime.second},s(this._value,t)),this._initTime=null,this.input.value=(n=this,e=this._value,i=n.options.separatorChars,o=n.options.date?"".concat(e.year).concat(i.date).concat(h(e.month)).concat(i.date).concat(h(e.day)):"",a=n.options.time?"".concat(h(e.hour)).concat(i.time).concat(h(e.minute))+(n.options.hasSecond?i.time+h(e.second):""):"",o+(o&&a?i.between:"")+a),Z(this.input,k),!this.options.time&&this.options.hideAfterChange?this.hide():this._draw()},increaseMonth:function(){var t=12===this._initDate.month;this.options.changeMonthRotateYear&&t&&this.increaseYear(),this.monthChange(t?1:this._initDate.month+1)},decreaseMonth:function(){var t=1===this._initDate.month;this.options.changeMonthRotateYear&&t&&this.decreaseYear(),this.monthChange(t?12:this._initDate.month-1)},monthChange:function(t){this._initDate=d(this,this._initDate,{month:t}),this._draw()},increaseYear:function(){this.yearChange(this._initDate.year+1)},decreaseYear:function(){this.yearChange(this._initDate.year-1)},yearChange:function(t){this._initDate=d(this,this._initDate,{year:t}),this._draw()}},gt=function(t,n){var e,i=null===(e=vt.input)||void 0===e?void 0:e.getAttribute(t);if(!n&&i===J)return a(vt.today);if(!o(i))return{};try{i=document.querySelector(i).value}catch(t){}return i=n?f(vt,i)?m(vt,i):{}:y(vt,i)?m(vt,i):{}},Dt=function(t){return!e(vt.options._date)&&e(t.date)&&(t.date=vt.options._date),!e(vt.options._time)&&e(t.time)&&(t.time=vt.options._time),t.separatorChars=s(vt.options.separatorChars,t.separatorChars),(t=s({},vt.options,t)).minDate===J&&(t.minDate=a(vt.today)),t.maxDate===J&&(t.maxDate=a(vt.today)),(t.initDate===W||t._initDateIsAttr)&&(delete t.initDate,t._initDateIsAttr=!0,window.Object.defineProperty(t,"initDate",{get:function(){return gt("data-jdp-init-date")},enumerable:!0})),(t.minDate===W||t._minDateIsAttr)&&(delete t.minDate,t._minDateIsAttr=!0,window.Object.defineProperty(t,"minDate",{get:function(){return gt("data-jdp-min-date")},enumerable:!0})),(t.maxDate===W||t._maxDateIsAttr)&&(delete t.maxDate,t._maxDateIsAttr=!0,window.Object.defineProperty(t,"maxDate",{get:function(){return gt("data-jdp-max-date")},enumerable:!0})),(t.minTime===W||t._minTimeIsAttr)&&(delete t.minTime,t._minTimeIsAttr=!0,window.Object.defineProperty(t,"minTime",{get:function(){return gt("data-jdp-min-time",!0)},enumerable:!0})),(t.maxTime===W||t._maxTimeIsAttr)&&(delete t.maxTime,t._maxTimeIsAttr=!0,window.Object.defineProperty(t,"maxTime",{get:function(){return gt("data-jdp-max-time",!0)},enumerable:!0})),t._date=t.date,delete t.date,window.Object.defineProperty(t,"date",{get:function(){var n,e;return!(null!==(n=vt.input)&&void 0!==n&&n.hasAttribute(F))&&(t._date||(null===(e=vt.input)||void 0===e?void 0:e.hasAttribute(q)))},enumerable:!0}),t._time=t.time,delete t.time,window.Object.defineProperty(t,"time",{get:function(){var n,e;return!(null!==(n=vt.input)&&void 0!==n&&n.hasAttribute(q))&&(t._time||(null===(e=vt.input)||void 0===e?void 0:e.hasAttribute(F)))},enumerable:!0}),t};window.jalaliDatepicker={startWatch:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};vt.init(t)},show:function(t){vt.show(t)},hide:function(){vt.hide()},updateOptions:function(t){vt.updateOptions(t)}}}()}(); \ No newline at end of file diff --git a/web/html/component/aPersianDatepicker.html b/web/html/component/aPersianDatepicker.html deleted file mode 100644 index cb4c2918..00000000 --- a/web/html/component/aPersianDatepicker.html +++ /dev/null @@ -1,73 +0,0 @@ -{{define "component/persianDatepickerTemplate"}} - -{{end}} - -{{define "component/aPersianDatepicker"}} - - - - -{{end}} \ No newline at end of file