@ramathibodi/nuxt-commons 0.1.73 → 4.0.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.
Files changed (260) hide show
  1. package/README.md +81 -55
  2. package/dist/module.json +4 -4
  3. package/dist/module.mjs +5 -4
  4. package/dist/runtime/bridges/authentication.d.ts +21 -0
  5. package/dist/runtime/bridges/authentication.js +20 -0
  6. package/dist/runtime/bridges/graphql.d.ts +17 -0
  7. package/dist/runtime/bridges/graphql.js +45 -0
  8. package/dist/runtime/components/Alert.d.vue.ts +3 -0
  9. package/dist/runtime/components/Alert.vue +17 -22
  10. package/dist/runtime/components/Alert.vue.d.ts +3 -0
  11. package/dist/runtime/components/BarcodeReader.d.vue.ts +9 -0
  12. package/dist/runtime/components/BarcodeReader.vue +56 -73
  13. package/dist/runtime/components/BarcodeReader.vue.d.ts +9 -0
  14. package/dist/runtime/components/ExportCSV.d.vue.ts +55 -0
  15. package/dist/runtime/components/ExportCSV.vue +39 -68
  16. package/dist/runtime/components/ExportCSV.vue.d.ts +55 -0
  17. package/dist/runtime/components/FileBtn.d.vue.ts +53 -0
  18. package/dist/runtime/components/FileBtn.vue +23 -38
  19. package/dist/runtime/components/FileBtn.vue.d.ts +53 -0
  20. package/dist/runtime/components/ImportCSV.d.vue.ts +52 -0
  21. package/dist/runtime/components/ImportCSV.vue +60 -99
  22. package/dist/runtime/components/ImportCSV.vue.d.ts +52 -0
  23. package/dist/runtime/components/MrzReader.d.vue.ts +19 -0
  24. package/dist/runtime/components/MrzReader.vue +128 -0
  25. package/dist/runtime/components/MrzReader.vue.d.ts +19 -0
  26. package/dist/runtime/components/SplitterPanel.d.vue.ts +15 -0
  27. package/dist/runtime/components/SplitterPanel.vue +18 -27
  28. package/dist/runtime/components/SplitterPanel.vue.d.ts +15 -0
  29. package/dist/runtime/components/TabsGroup.d.vue.ts +19 -0
  30. package/dist/runtime/components/TabsGroup.vue +8 -12
  31. package/dist/runtime/components/TabsGroup.vue.d.ts +19 -0
  32. package/dist/runtime/components/TextBarcode.d.vue.ts +12 -0
  33. package/dist/runtime/components/TextBarcode.vue +22 -33
  34. package/dist/runtime/components/TextBarcode.vue.d.ts +12 -0
  35. package/dist/runtime/components/device/IdCardButton.d.vue.ts +57 -0
  36. package/dist/runtime/components/device/IdCardButton.vue +30 -55
  37. package/dist/runtime/components/device/IdCardButton.vue.d.ts +57 -0
  38. package/dist/runtime/components/device/IdCardWebSocket.d.vue.ts +55 -0
  39. package/dist/runtime/components/device/IdCardWebSocket.vue +104 -153
  40. package/dist/runtime/components/device/IdCardWebSocket.vue.d.ts +55 -0
  41. package/dist/runtime/components/device/Scanner.d.vue.ts +66 -0
  42. package/dist/runtime/components/device/Scanner.vue +97 -166
  43. package/dist/runtime/components/device/Scanner.vue.d.ts +66 -0
  44. package/dist/runtime/components/dialog/Confirm.d.vue.ts +37 -0
  45. package/dist/runtime/components/dialog/Confirm.vue +30 -47
  46. package/dist/runtime/components/dialog/Confirm.vue.d.ts +37 -0
  47. package/dist/runtime/components/dialog/Host.d.vue.ts +9 -0
  48. package/dist/runtime/components/dialog/Host.vue +34 -53
  49. package/dist/runtime/components/dialog/Host.vue.d.ts +9 -0
  50. package/dist/runtime/components/dialog/Index.d.vue.ts +24 -0
  51. package/dist/runtime/components/dialog/Index.vue +20 -28
  52. package/dist/runtime/components/dialog/Index.vue.d.ts +24 -0
  53. package/dist/runtime/components/dialog/Loading.d.vue.ts +21 -0
  54. package/dist/runtime/components/dialog/Loading.vue +12 -17
  55. package/dist/runtime/components/dialog/Loading.vue.d.ts +21 -0
  56. package/dist/runtime/components/dialog/default/Confirm.d.vue.ts +40 -0
  57. package/dist/runtime/components/dialog/default/Confirm.vue +29 -50
  58. package/dist/runtime/components/dialog/default/Confirm.vue.d.ts +40 -0
  59. package/dist/runtime/components/dialog/default/Loading.d.vue.ts +23 -0
  60. package/dist/runtime/components/dialog/default/Loading.vue +12 -17
  61. package/dist/runtime/components/dialog/default/Loading.vue.d.ts +23 -0
  62. package/dist/runtime/components/dialog/default/Notify.d.vue.ts +23 -0
  63. package/dist/runtime/components/dialog/default/Notify.vue +19 -36
  64. package/dist/runtime/components/dialog/default/Notify.vue.d.ts +23 -0
  65. package/dist/runtime/components/dialog/default/Printing.d.vue.ts +21 -0
  66. package/dist/runtime/components/dialog/default/Printing.vue +13 -17
  67. package/dist/runtime/components/dialog/default/Printing.vue.d.ts +21 -0
  68. package/dist/runtime/components/dialog/default/VerifyUser.d.vue.ts +29 -0
  69. package/dist/runtime/components/dialog/default/VerifyUser.vue +44 -70
  70. package/dist/runtime/components/dialog/default/VerifyUser.vue.d.ts +29 -0
  71. package/dist/runtime/components/document/Form.d.vue.ts +9 -0
  72. package/dist/runtime/components/document/Form.vue +27 -34
  73. package/dist/runtime/components/document/Form.vue.d.ts +9 -0
  74. package/dist/runtime/components/document/TemplateBuilder.d.vue.ts +24 -0
  75. package/dist/runtime/components/document/TemplateBuilder.vue +154 -182
  76. package/dist/runtime/components/document/TemplateBuilder.vue.d.ts +24 -0
  77. package/dist/runtime/components/form/ActionPad.d.vue.ts +114 -0
  78. package/dist/runtime/components/form/ActionPad.vue +48 -73
  79. package/dist/runtime/components/form/ActionPad.vue.d.ts +114 -0
  80. package/dist/runtime/components/form/Birthdate.d.vue.ts +38 -0
  81. package/dist/runtime/components/form/Birthdate.vue +44 -64
  82. package/dist/runtime/components/form/Birthdate.vue.d.ts +38 -0
  83. package/dist/runtime/components/form/CheckboxGroup.d.vue.ts +41 -0
  84. package/dist/runtime/components/form/CheckboxGroup.vue +34 -52
  85. package/dist/runtime/components/form/CheckboxGroup.vue.d.ts +41 -0
  86. package/dist/runtime/components/form/CodeEditor.d.vue.ts +25 -0
  87. package/dist/runtime/components/form/CodeEditor.vue +18 -28
  88. package/dist/runtime/components/form/CodeEditor.vue.d.ts +25 -0
  89. package/dist/runtime/components/form/Date.d.vue.ts +86 -0
  90. package/dist/runtime/components/form/Date.vue +109 -150
  91. package/dist/runtime/components/form/Date.vue.d.ts +86 -0
  92. package/dist/runtime/components/form/DateTime.d.vue.ts +36 -0
  93. package/dist/runtime/components/form/DateTime.vue +94 -131
  94. package/dist/runtime/components/form/DateTime.vue.d.ts +36 -0
  95. package/dist/runtime/components/form/Dialog.d.vue.ts +69 -0
  96. package/dist/runtime/components/form/Dialog.vue +60 -84
  97. package/dist/runtime/components/form/Dialog.vue.d.ts +69 -0
  98. package/dist/runtime/components/form/EditPad.d.vue.ts +113 -0
  99. package/dist/runtime/components/form/EditPad.vue +49 -73
  100. package/dist/runtime/components/form/EditPad.vue.d.ts +113 -0
  101. package/dist/runtime/components/form/File.d.vue.ts +65 -0
  102. package/dist/runtime/components/form/File.vue +112 -174
  103. package/dist/runtime/components/form/File.vue.d.ts +65 -0
  104. package/dist/runtime/components/form/Hidden.d.vue.ts +12 -0
  105. package/dist/runtime/components/form/Hidden.vue +17 -22
  106. package/dist/runtime/components/form/Hidden.vue.d.ts +12 -0
  107. package/dist/runtime/components/form/Iterator.d.vue.ts +279 -0
  108. package/dist/runtime/components/form/Iterator.vue +162 -240
  109. package/dist/runtime/components/form/Iterator.vue.d.ts +279 -0
  110. package/dist/runtime/components/form/Login.d.vue.ts +32 -0
  111. package/dist/runtime/components/form/Login.vue +23 -43
  112. package/dist/runtime/components/form/Login.vue.d.ts +32 -0
  113. package/dist/runtime/components/form/Pad.d.vue.ts +674 -0
  114. package/dist/runtime/components/form/Pad.vue +166 -253
  115. package/dist/runtime/components/form/Pad.vue.d.ts +674 -0
  116. package/dist/runtime/components/form/SignPad.d.vue.ts +62 -0
  117. package/dist/runtime/components/form/SignPad.vue +80 -118
  118. package/dist/runtime/components/form/SignPad.vue.d.ts +62 -0
  119. package/dist/runtime/components/form/System.d.vue.ts +34 -0
  120. package/dist/runtime/components/form/System.vue +18 -24
  121. package/dist/runtime/components/form/System.vue.d.ts +34 -0
  122. package/dist/runtime/components/form/Table.d.vue.ts +221 -0
  123. package/dist/runtime/components/form/Table.vue +123 -170
  124. package/dist/runtime/components/form/Table.vue.d.ts +221 -0
  125. package/dist/runtime/components/form/TableData.d.vue.ts +102 -0
  126. package/dist/runtime/components/form/TableData.vue +109 -127
  127. package/dist/runtime/components/form/TableData.vue.d.ts +102 -0
  128. package/dist/runtime/components/form/Time.d.vue.ts +49 -0
  129. package/dist/runtime/components/form/Time.vue +64 -87
  130. package/dist/runtime/components/form/Time.vue.d.ts +49 -0
  131. package/dist/runtime/components/form/images/Capture.d.vue.ts +96 -0
  132. package/dist/runtime/components/form/images/Capture.vue +104 -139
  133. package/dist/runtime/components/form/images/Capture.vue.d.ts +96 -0
  134. package/dist/runtime/components/form/images/Edit.d.vue.ts +29 -0
  135. package/dist/runtime/components/form/images/Edit.vue +57 -69
  136. package/dist/runtime/components/form/images/Edit.vue.d.ts +29 -0
  137. package/dist/runtime/components/form/images/Field.d.vue.ts +27 -0
  138. package/dist/runtime/components/form/images/Field.vue +136 -194
  139. package/dist/runtime/components/form/images/Field.vue.d.ts +27 -0
  140. package/dist/runtime/components/form/images/Pad.d.vue.ts +13 -0
  141. package/dist/runtime/components/form/images/Pad.vue +23 -28
  142. package/dist/runtime/components/form/images/Pad.vue.d.ts +13 -0
  143. package/dist/runtime/components/label/Date.d.vue.ts +13 -0
  144. package/dist/runtime/components/label/Date.vue +13 -21
  145. package/dist/runtime/components/label/Date.vue.d.ts +13 -0
  146. package/dist/runtime/components/label/DateAgo.d.vue.ts +20 -0
  147. package/dist/runtime/components/label/DateAgo.vue +43 -67
  148. package/dist/runtime/components/label/DateAgo.vue.d.ts +20 -0
  149. package/dist/runtime/components/label/DateCount.d.vue.ts +22 -0
  150. package/dist/runtime/components/label/DateCount.vue +58 -97
  151. package/dist/runtime/components/label/DateCount.vue.d.ts +22 -0
  152. package/dist/runtime/components/label/Field.d.vue.ts +38 -0
  153. package/dist/runtime/components/label/Field.vue +18 -32
  154. package/dist/runtime/components/label/Field.vue.d.ts +38 -0
  155. package/dist/runtime/components/label/FormatMoney.d.vue.ts +12 -0
  156. package/dist/runtime/components/label/FormatMoney.vue +12 -20
  157. package/dist/runtime/components/label/FormatMoney.vue.d.ts +12 -0
  158. package/dist/runtime/components/label/Mask.d.vue.ts +10 -0
  159. package/dist/runtime/components/label/Mask.vue +21 -30
  160. package/dist/runtime/components/label/Mask.vue.d.ts +10 -0
  161. package/dist/runtime/components/label/Object.d.vue.ts +8 -0
  162. package/dist/runtime/components/label/Object.vue +10 -12
  163. package/dist/runtime/components/label/Object.vue.d.ts +8 -0
  164. package/dist/runtime/components/master/Autocomplete.d.vue.ts +70 -0
  165. package/dist/runtime/components/master/Autocomplete.vue +25 -26
  166. package/dist/runtime/components/master/Autocomplete.vue.d.ts +70 -0
  167. package/dist/runtime/components/master/Combobox.d.vue.ts +70 -0
  168. package/dist/runtime/components/master/Combobox.vue +26 -27
  169. package/dist/runtime/components/master/Combobox.vue.d.ts +70 -0
  170. package/dist/runtime/components/master/RadioGroup.d.vue.ts +51 -0
  171. package/dist/runtime/components/master/RadioGroup.vue +44 -47
  172. package/dist/runtime/components/master/RadioGroup.vue.d.ts +51 -0
  173. package/dist/runtime/components/master/Select.d.vue.ts +68 -0
  174. package/dist/runtime/components/master/Select.vue +25 -26
  175. package/dist/runtime/components/master/Select.vue.d.ts +68 -0
  176. package/dist/runtime/components/master/label.d.vue.ts +24 -0
  177. package/dist/runtime/components/master/label.vue +22 -34
  178. package/dist/runtime/components/master/label.vue.d.ts +24 -0
  179. package/dist/runtime/components/model/Autocomplete.d.vue.ts +82 -0
  180. package/dist/runtime/components/model/Autocomplete.vue +50 -37
  181. package/dist/runtime/components/model/Autocomplete.vue.d.ts +82 -0
  182. package/dist/runtime/components/model/Combobox.d.vue.ts +82 -0
  183. package/dist/runtime/components/model/Combobox.vue +51 -37
  184. package/dist/runtime/components/model/Combobox.vue.d.ts +82 -0
  185. package/dist/runtime/components/model/Pad.d.vue.ts +72 -0
  186. package/dist/runtime/components/model/Pad.vue +50 -53
  187. package/dist/runtime/components/model/Pad.vue.d.ts +72 -0
  188. package/dist/runtime/components/model/Select.d.vue.ts +72 -0
  189. package/dist/runtime/components/model/Select.vue +42 -32
  190. package/dist/runtime/components/model/Select.vue.d.ts +72 -0
  191. package/dist/runtime/components/model/Table.d.vue.ts +272 -0
  192. package/dist/runtime/components/model/Table.vue +121 -133
  193. package/dist/runtime/components/model/Table.vue.d.ts +272 -0
  194. package/dist/runtime/components/model/iterator.d.vue.ts +321 -0
  195. package/dist/runtime/components/model/iterator.vue +148 -175
  196. package/dist/runtime/components/model/iterator.vue.d.ts +321 -0
  197. package/dist/runtime/components/model/label.d.vue.ts +26 -0
  198. package/dist/runtime/components/model/label.vue +25 -35
  199. package/dist/runtime/components/model/label.vue.d.ts +26 -0
  200. package/dist/runtime/components/pdf/Print.d.vue.ts +17 -0
  201. package/dist/runtime/components/pdf/Print.vue +27 -38
  202. package/dist/runtime/components/pdf/Print.vue.d.ts +17 -0
  203. package/dist/runtime/components/pdf/View.d.vue.ts +52 -0
  204. package/dist/runtime/components/pdf/View.vue +58 -83
  205. package/dist/runtime/components/pdf/View.vue.d.ts +52 -0
  206. package/dist/runtime/composables/alert.d.ts +4 -0
  207. package/dist/runtime/composables/api.d.ts +4 -0
  208. package/dist/runtime/composables/api.js +4 -2
  209. package/dist/runtime/composables/assetFile.js +4 -2
  210. package/dist/runtime/composables/dialog.d.ts +1 -1
  211. package/dist/runtime/composables/document/template.js +3 -3
  212. package/dist/runtime/composables/document/templateFormHidden.d.ts +4 -0
  213. package/dist/runtime/composables/document/templateFormTable.js +1 -0
  214. package/dist/runtime/composables/graphql.d.ts +2 -2
  215. package/dist/runtime/composables/graphql.js +5 -5
  216. package/dist/runtime/composables/graphqlModel.d.ts +6 -6
  217. package/dist/runtime/composables/graphqlModelItem.d.ts +4 -4
  218. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  219. package/dist/runtime/composables/graphqlModelOperation.js +2 -1
  220. package/dist/runtime/composables/graphqlOperation.js +5 -1
  221. package/dist/runtime/composables/hostAgentWs.d.ts +1 -1
  222. package/dist/runtime/composables/localStorageModel.d.ts +4 -0
  223. package/dist/runtime/composables/lookupList.d.ts +4 -0
  224. package/dist/runtime/composables/lookupListMaster.js +3 -3
  225. package/dist/runtime/composables/menu.d.ts +4 -0
  226. package/dist/runtime/composables/menu.js +2 -2
  227. package/dist/runtime/composables/useMrzReader.d.ts +48 -0
  228. package/dist/runtime/composables/useMrzReader.js +423 -0
  229. package/dist/runtime/composables/useTesseract.d.ts +16 -0
  230. package/dist/runtime/composables/useTesseract.js +45 -0
  231. package/dist/runtime/composables/userPermission.d.ts +1 -1
  232. package/dist/runtime/composables/utils/fuzzy.d.ts +2 -1
  233. package/dist/runtime/labs/Calendar.d.vue.ts +35 -0
  234. package/dist/runtime/labs/Calendar.vue +47 -75
  235. package/dist/runtime/labs/Calendar.vue.d.ts +35 -0
  236. package/dist/runtime/labs/form/EditMobile.d.vue.ts +12 -0
  237. package/dist/runtime/labs/form/EditMobile.vue +19 -36
  238. package/dist/runtime/labs/form/EditMobile.vue.d.ts +12 -0
  239. package/dist/runtime/labs/form/TextFieldMask.d.vue.ts +21 -0
  240. package/dist/runtime/labs/form/TextFieldMask.vue +19 -25
  241. package/dist/runtime/labs/form/TextFieldMask.vue.d.ts +21 -0
  242. package/dist/runtime/plugins/dialogManager.js +2 -2
  243. package/dist/runtime/plugins/permission.js +3 -3
  244. package/dist/runtime/types/bridge.d.ts +14 -0
  245. package/dist/runtime/utils/asset.d.ts +2 -0
  246. package/dist/runtime/utils/asset.js +49 -0
  247. package/dist/runtime/utils/datetime.js +1 -1
  248. package/dist/types.d.mts +2 -6
  249. package/package.json +79 -57
  250. package/scripts/ci-release.mjs +125 -0
  251. package/scripts/enrich-vue-docs-from-ai.mjs +197 -0
  252. package/scripts/generate-ai-summary.mjs +321 -0
  253. package/scripts/generate-composables-md.mjs +129 -0
  254. package/scripts/release-version.mjs +68 -0
  255. package/scripts/release.mjs +49 -0
  256. package/templates/public/tesseract/mrz.traineddata.gz +0 -0
  257. package/templates/public/tesseract/ocrb.traineddata.gz +0 -0
  258. package/dist/module.cjs +0 -5
  259. package/dist/module.d.ts +0 -8
  260. package/dist/types.d.ts +0 -7
@@ -0,0 +1,423 @@
1
+ import { ref } from "vue";
2
+ import { useTesseract } from "./useTesseract.js";
3
+ export function useMrzReader(options = {}) {
4
+ const scaleFactor = options.scaleFactor ?? 2;
5
+ const useOpenCv = options.useOpenCv ?? true;
6
+ const ocr = useTesseract({
7
+ lang: options.lang ?? "ocrb",
8
+ langPath: options.langPath ?? "/tesseract/"
9
+ });
10
+ const opencvReady = ref(false);
11
+ const opencvTried = ref(false);
12
+ let opencvInstance = null;
13
+ const MRZ_CHARS = /^[A-Z0-9<]+$/;
14
+ const WEIGHTS = [7, 3, 1];
15
+ async function ensureOpenCvReady() {
16
+ if (!useOpenCv || !import.meta.client) return false;
17
+ if (opencvReady.value && opencvInstance) return true;
18
+ if (opencvTried.value) return false;
19
+ opencvTried.value = true;
20
+ const resolveCv = async (mod) => {
21
+ let defaultExport = mod.default;
22
+ if (defaultExport && typeof defaultExport.then === "function") {
23
+ try {
24
+ defaultExport = await defaultExport;
25
+ } catch {
26
+ defaultExport = void 0;
27
+ }
28
+ }
29
+ const first = defaultExport;
30
+ if (first && typeof first.Mat === "function")
31
+ return first;
32
+ const second = mod.cv;
33
+ if (second && typeof second.Mat === "function")
34
+ return second;
35
+ return void 0;
36
+ };
37
+ let importedCv;
38
+ try {
39
+ const mod = await import("@techstark/opencv-js");
40
+ importedCv = await resolveCv(mod);
41
+ } catch {
42
+ importedCv = void 0;
43
+ }
44
+ opencvInstance = importedCv;
45
+ opencvReady.value = !!opencvInstance;
46
+ return opencvReady.value;
47
+ }
48
+ function charValue(ch) {
49
+ if (ch === "<") return 0;
50
+ const code = ch.charCodeAt(0);
51
+ if (code >= 48 && code <= 57) return code - 48;
52
+ if (code >= 65 && code <= 90) return code - 55;
53
+ return -1;
54
+ }
55
+ function checksum(input) {
56
+ let sum = 0;
57
+ for (let i = 0; i < input.length; i++) {
58
+ const value = charValue(input[i]);
59
+ if (value < 0) return void 0;
60
+ sum += value * WEIGHTS[i % 3];
61
+ }
62
+ return String(sum % 10);
63
+ }
64
+ function normalizeMrzText(raw) {
65
+ return raw.toUpperCase().replace(/[^A-Z0-9<\r\n]/g, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
66
+ }
67
+ function normalizeLine44(line) {
68
+ return line.replace(/[^A-Z0-9<]/g, "").padEnd(44, "<").slice(0, 44);
69
+ }
70
+ function asDigits(text) {
71
+ return text.replace(/[ODQ]/g, "0").replace(/[IL]/g, "1").replace(/Z/g, "2").replace(/S/g, "5").replace(/B/g, "8").replace(/G/g, "6");
72
+ }
73
+ function asLetters(text) {
74
+ return text.replace(/0/g, "O").replace(/1/g, "I").replace(/2/g, "Z").replace(/5/g, "S").replace(/8/g, "B");
75
+ }
76
+ function normalizeCountryCode(code) {
77
+ const clean = code.replace(/</g, "").trim();
78
+ if (!/^[A-Z]{3}$/.test(clean)) return void 0;
79
+ return clean;
80
+ }
81
+ function isValidDateYYMMDD(value) {
82
+ if (!/^\d{6}$/.test(value)) return false;
83
+ const mm = Number(value.slice(2, 4));
84
+ const dd = Number(value.slice(4, 6));
85
+ return mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;
86
+ }
87
+ function parseNameField(nameField) {
88
+ const clean = nameField.replace(/<+$/g, "");
89
+ const [rawSurname, rawGiven] = clean.split("<<");
90
+ return {
91
+ surname: rawSurname?.replace(/</g, " ").trim() || void 0,
92
+ givenNames: rawGiven?.replace(/</g, " ").trim() || void 0
93
+ };
94
+ }
95
+ function validateTd3Passport(lines, raw) {
96
+ if (lines.length !== 2) return void 0;
97
+ const line1 = normalizeLine44(lines[0]);
98
+ const line2 = normalizeLine44(lines[1]);
99
+ if (!MRZ_CHARS.test(line1) || !MRZ_CHARS.test(line2)) return void 0;
100
+ const documentType = line1.slice(0, 2).replace(/</g, "").replace(/^F/, "P");
101
+ const issuingState = normalizeCountryCode(asLetters(line1.slice(2, 5)));
102
+ const { surname, givenNames } = parseNameField(line1.slice(5, 44));
103
+ const passportNumber = line2.slice(0, 9);
104
+ const passportCheck = asDigits(line2.slice(9, 10));
105
+ const nationality = normalizeCountryCode(asLetters(line2.slice(10, 13)));
106
+ const birthDate = asDigits(line2.slice(13, 19));
107
+ const birthCheck = asDigits(line2.slice(19, 20));
108
+ const sex = line2.slice(20, 21).replace(/</g, "X");
109
+ const expirationDate = asDigits(line2.slice(21, 27));
110
+ const expirationCheck = asDigits(line2.slice(27, 28));
111
+ const personalNumber = line2.slice(28, 42);
112
+ const personalCheck = asDigits(line2.slice(42, 43));
113
+ const compositeCheck = asDigits(line2.slice(43, 44));
114
+ if (!documentType.startsWith("P")) return void 0;
115
+ if (!/^[A-Z0-9<]{9}$/.test(passportNumber)) return void 0;
116
+ if (!/^[A-Z0-9<]{14}$/.test(personalNumber)) return void 0;
117
+ if (!/^\d$/.test(passportCheck) || !/^\d$/.test(birthCheck) || !/^\d$/.test(expirationCheck) || !/^\d$/.test(personalCheck) || !/^\d$/.test(compositeCheck)) return void 0;
118
+ if (!isValidDateYYMMDD(birthDate) || !isValidDateYYMMDD(expirationDate)) return void 0;
119
+ const numberCalc = checksum(passportNumber);
120
+ const birthCalc = checksum(birthDate);
121
+ const expirationCalc = checksum(expirationDate);
122
+ const personalCalc = checksum(personalNumber);
123
+ const compositeCalc = checksum(`${passportNumber}${passportCheck}${birthDate}${birthCheck}${expirationDate}${expirationCheck}${personalNumber}${personalCheck}`);
124
+ if (!numberCalc || !birthCalc || !expirationCalc || !personalCalc || !compositeCalc) return void 0;
125
+ if (numberCalc !== passportCheck) return void 0;
126
+ if (birthCalc !== birthCheck) return void 0;
127
+ if (expirationCalc !== expirationCheck) return void 0;
128
+ if (personalCalc !== personalCheck) return void 0;
129
+ if (compositeCalc !== compositeCheck) return void 0;
130
+ return {
131
+ raw,
132
+ lines: [line1, line2],
133
+ fields: {
134
+ documentType,
135
+ issuingState,
136
+ surname,
137
+ givenNames,
138
+ passportNumber: passportNumber.replace(/<+$/g, ""),
139
+ nationality,
140
+ birthDate,
141
+ sex,
142
+ expirationDate,
143
+ personalNumber: personalNumber.replace(/<+$/g, ""),
144
+ checkDigits: {
145
+ passportNumber: passportCheck,
146
+ birthDate: birthCheck,
147
+ expirationDate: expirationCheck,
148
+ personalNumber: personalCheck,
149
+ composite: compositeCheck
150
+ }
151
+ }
152
+ };
153
+ }
154
+ function copyFrameToCanvas(source) {
155
+ const canvas = document.createElement("canvas");
156
+ const width = source.videoWidth || source.width;
157
+ const height = source.videoHeight || source.height;
158
+ canvas.width = width;
159
+ canvas.height = height;
160
+ canvas.getContext("2d")?.drawImage(source, 0, 0, width, height);
161
+ return canvas;
162
+ }
163
+ function scoreTwoLineTextBand(grayData, width, height) {
164
+ const totalPixels = width * height;
165
+ if (totalPixels < 2e3) return 0;
166
+ let sum = 0;
167
+ for (let i = 0; i < grayData.length; i += 4)
168
+ sum += grayData[i];
169
+ const mean = sum / totalPixels;
170
+ if (mean < 120) return 0;
171
+ const darkThreshold = Math.max(55, mean - 32);
172
+ const rowCounts = new Float32Array(height);
173
+ for (let y = 0; y < height; y++) {
174
+ let count = 0;
175
+ for (let x = 0; x < width; x++) {
176
+ const idx = (y * width + x) * 4;
177
+ if (grayData[idx] < darkThreshold)
178
+ count++;
179
+ }
180
+ rowCounts[y] = count;
181
+ }
182
+ const smooth = new Float32Array(height);
183
+ for (let y = 0; y < height; y++) {
184
+ const a = rowCounts[Math.max(0, y - 1)];
185
+ const b = rowCounts[y];
186
+ const c = rowCounts[Math.min(height - 1, y + 1)];
187
+ smooth[y] = (a + b + c) / 3;
188
+ }
189
+ let peak1 = 0;
190
+ let peak1Idx = -1;
191
+ for (let i = 0; i < height; i++) {
192
+ if (smooth[i] > peak1) {
193
+ peak1 = smooth[i];
194
+ peak1Idx = i;
195
+ }
196
+ }
197
+ let peak2 = 0;
198
+ for (let i = 0; i < height; i++) {
199
+ if (Math.abs(i - peak1Idx) < Math.max(3, Math.floor(height * 0.14)))
200
+ continue;
201
+ if (smooth[i] > peak2)
202
+ peak2 = smooth[i];
203
+ }
204
+ const avg = smooth.reduce((acc, v) => acc + v, 0) / Math.max(1, smooth.length);
205
+ const prominence = peak1 + peak2 - avg * 2;
206
+ if (peak1 < width * 0.2 || peak2 < width * 0.2) return 0;
207
+ return prominence / Math.max(1, width);
208
+ }
209
+ function findMrzRegionCandidates(sourceCanvas) {
210
+ const srcW = sourceCanvas.width;
211
+ const srcH = sourceCanvas.height;
212
+ if (!srcW || !srcH) return [];
213
+ const probeW = Math.min(640, srcW);
214
+ const scale = probeW / srcW;
215
+ const probeH = Math.max(1, Math.floor(srcH * scale));
216
+ const probe = document.createElement("canvas");
217
+ probe.width = probeW;
218
+ probe.height = probeH;
219
+ const ctx = probe.getContext("2d");
220
+ if (!ctx) return [];
221
+ ctx.drawImage(sourceCanvas, 0, 0, srcW, srcH, 0, 0, probeW, probeH);
222
+ const widths = [0.58, 0.68, 0.78, 0.88, 0.94];
223
+ const heights = [0.14, 0.18, 0.22, 0.26];
224
+ const xCenters = [0.5, 0.42, 0.58, 0.34, 0.66];
225
+ const scored = [];
226
+ for (const wRatio of widths) {
227
+ for (const hRatio of heights) {
228
+ const w = Math.max(56, Math.floor(probeW * wRatio));
229
+ const h = Math.max(30, Math.floor(probeH * hRatio));
230
+ const yStart = Math.floor(probeH * 0.24);
231
+ const yEnd = Math.floor(probeH * 0.94);
232
+ const step = Math.max(10, Math.floor(h * 0.28));
233
+ for (const center of xCenters) {
234
+ const x = Math.max(0, Math.min(probeW - w, Math.floor(probeW * center - w / 2)));
235
+ for (let y = yStart; y + h < yEnd; y += step) {
236
+ const img = ctx.getImageData(x, y, w, h);
237
+ const score = scoreTwoLineTextBand(img.data, w, h);
238
+ if (score <= 0) continue;
239
+ scored.push({ x: Math.round(x / scale), y: Math.round(y / scale), w: Math.round(w / scale), h: Math.round(h / scale), score });
240
+ }
241
+ }
242
+ }
243
+ }
244
+ scored.sort((a, b) => b.score - a.score);
245
+ return scored.slice(0, 4);
246
+ }
247
+ function findMrzCandidatesWithOpenCv(sourceCanvas) {
248
+ if (!opencvReady.value || !opencvInstance) return [];
249
+ const cv = opencvInstance;
250
+ let src;
251
+ let gray;
252
+ let blur;
253
+ let edges;
254
+ let kernel;
255
+ let closed;
256
+ let contours;
257
+ let hierarchy;
258
+ try {
259
+ src = cv.imread(sourceCanvas);
260
+ gray = new cv.Mat();
261
+ blur = new cv.Mat();
262
+ edges = new cv.Mat();
263
+ kernel = cv.getStructuringElement(cv.MORPH_RECT, new cv.Size(9, 3));
264
+ closed = new cv.Mat();
265
+ contours = new cv.MatVector();
266
+ hierarchy = new cv.Mat();
267
+ cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
268
+ cv.GaussianBlur(gray, blur, new cv.Size(5, 5), 0, 0, cv.BORDER_DEFAULT);
269
+ cv.Canny(blur, edges, 50, 140, 3, false);
270
+ cv.morphologyEx(edges, closed, cv.MORPH_CLOSE, kernel);
271
+ cv.findContours(closed, contours, hierarchy, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);
272
+ const output = [];
273
+ for (let i = 0; i < contours.size(); i++) {
274
+ const contour = contours.get(i);
275
+ const rect = cv.boundingRect(contour);
276
+ contour.delete?.();
277
+ const ratio = rect.width / Math.max(1, rect.height);
278
+ if (rect.width < sourceCanvas.width * 0.45 || rect.height < sourceCanvas.height * 0.1) continue;
279
+ if (ratio < 2.2 || ratio > 10) continue;
280
+ output.push({
281
+ x: rect.x,
282
+ y: rect.y,
283
+ w: rect.width,
284
+ h: rect.height,
285
+ score: rect.width * rect.height / (sourceCanvas.width * sourceCanvas.height)
286
+ });
287
+ }
288
+ output.sort((a, b) => b.score - a.score);
289
+ return output.slice(0, 4);
290
+ } catch {
291
+ return [];
292
+ } finally {
293
+ src?.delete?.();
294
+ gray?.delete?.();
295
+ blur?.delete?.();
296
+ edges?.delete?.();
297
+ kernel?.delete?.();
298
+ closed?.delete?.();
299
+ contours?.delete?.();
300
+ hierarchy?.delete?.();
301
+ }
302
+ }
303
+ function applyBinarize(canvas) {
304
+ const ctx = canvas.getContext("2d");
305
+ if (!ctx) return;
306
+ const img = ctx.getImageData(0, 0, canvas.width, canvas.height);
307
+ const data = img.data;
308
+ let min = 255;
309
+ let max = 0;
310
+ for (let i = 0; i < data.length; i += 4) {
311
+ const g = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
312
+ if (g < min) min = g;
313
+ if (g > max) max = g;
314
+ }
315
+ const range = Math.max(1, max - min);
316
+ const threshold = 0.58 * 255;
317
+ for (let i = 0; i < data.length; i += 4) {
318
+ const g = (0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2] - min) * (255 / range);
319
+ const v = g > threshold ? 255 : 0;
320
+ data[i] = v;
321
+ data[i + 1] = v;
322
+ data[i + 2] = v;
323
+ data[i + 3] = 255;
324
+ }
325
+ ctx.putImageData(img, 0, 0);
326
+ }
327
+ function renderCandidate(outputCanvas, sourceCanvas, candidate, angleDeg = 0, zoom = 1, binarize = true) {
328
+ outputCanvas.width = Math.max(1, Math.floor(candidate.w * zoom));
329
+ outputCanvas.height = Math.max(1, Math.floor(candidate.h * zoom));
330
+ const ctx = outputCanvas.getContext("2d");
331
+ if (!ctx) return;
332
+ ctx.save();
333
+ ctx.translate(outputCanvas.width / 2, outputCanvas.height / 2);
334
+ ctx.rotate(angleDeg * Math.PI / 180);
335
+ ctx.drawImage(
336
+ sourceCanvas,
337
+ candidate.x,
338
+ candidate.y,
339
+ candidate.w,
340
+ candidate.h,
341
+ -outputCanvas.width / 2,
342
+ -outputCanvas.height / 2,
343
+ outputCanvas.width,
344
+ outputCanvas.height
345
+ );
346
+ ctx.restore();
347
+ if (binarize)
348
+ applyBinarize(outputCanvas);
349
+ }
350
+ function pickPassportCandidates(lines) {
351
+ const candidates = [];
352
+ for (let i = 0; i < lines.length - 1; i++) {
353
+ if (lines[i].length < 30 || lines[i + 1].length < 30) continue;
354
+ candidates.push([normalizeLine44(lines[i]), normalizeLine44(lines[i + 1])]);
355
+ }
356
+ if (!candidates.length) {
357
+ const sorted = [...lines].sort((a, b) => b.length - a.length);
358
+ if (sorted.length >= 2)
359
+ candidates.push([normalizeLine44(sorted[0]), normalizeLine44(sorted[1])]);
360
+ }
361
+ return candidates;
362
+ }
363
+ async function decodeFromCanvas(sourceCanvas) {
364
+ await ocr.ensureReady();
365
+ if (useOpenCv)
366
+ await ensureOpenCvReady();
367
+ const candidates = opencvReady.value ? findMrzCandidatesWithOpenCv(sourceCanvas) : findMrzRegionCandidates(sourceCanvas);
368
+ const fallback = {
369
+ x: Math.floor(sourceCanvas.width * 0.05),
370
+ y: Math.floor(sourceCanvas.height * 0.64),
371
+ w: Math.floor(sourceCanvas.width * 0.9),
372
+ h: Math.floor(sourceCanvas.height * 0.24),
373
+ score: 0
374
+ };
375
+ const selected = (candidates.length ? candidates : [fallback]).slice(0, 3);
376
+ const probe = document.createElement("canvas");
377
+ for (const candidate of selected) {
378
+ for (const angle of [0, -6, 6]) {
379
+ for (const binarize of [true, false]) {
380
+ renderCandidate(probe, sourceCanvas, candidate, angle, scaleFactor, binarize);
381
+ const raw = await ocr.recognize(probe);
382
+ const lines = normalizeMrzText(raw);
383
+ const mrzCandidates = pickPassportCandidates(lines);
384
+ for (const mrz of mrzCandidates) {
385
+ const parsed = validateTd3Passport(mrz, raw);
386
+ if (parsed) return parsed;
387
+ }
388
+ }
389
+ }
390
+ }
391
+ return void 0;
392
+ }
393
+ async function decodeFromVideoElement(video) {
394
+ const canvas = copyFrameToCanvas(video);
395
+ return decodeFromCanvas(canvas);
396
+ }
397
+ async function decodeFromImageFile(file) {
398
+ const image = await new Promise((resolve, reject) => {
399
+ const reader = new FileReader();
400
+ reader.onload = () => {
401
+ const img = new Image();
402
+ img.onload = () => resolve(img);
403
+ img.onerror = () => reject(new Error("Failed to load image"));
404
+ img.src = reader.result;
405
+ };
406
+ reader.onerror = () => reject(new Error("Failed to read file"));
407
+ reader.readAsDataURL(file);
408
+ });
409
+ const canvas = document.createElement("canvas");
410
+ canvas.width = image.naturalWidth;
411
+ canvas.height = image.naturalHeight;
412
+ canvas.getContext("2d")?.drawImage(image, 0, 0);
413
+ return decodeFromCanvas(canvas);
414
+ }
415
+ return {
416
+ ensureOpenCvReady,
417
+ opencvReady,
418
+ ocrProgress: ocr.progress,
419
+ ocrStatus: ocr.status,
420
+ decodeFromVideoElement,
421
+ decodeFromImageFile
422
+ };
423
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Options for configuring client-side Tesseract OCR behavior.
3
+ */
4
+ export interface UseTesseractOptions {
5
+ lang?: string;
6
+ langPath?: string;
7
+ }
8
+ /**
9
+ * Provides lazy-loaded Tesseract OCR helpers with reactive status/progress state.
10
+ */
11
+ export declare function useTesseract(options?: UseTesseractOptions): {
12
+ progress: import("vue").Ref<number, number>;
13
+ status: import("vue").Ref<string, string>;
14
+ ensureReady: () => Promise<typeof import("tesseract.js")>;
15
+ recognize: (canvas: HTMLCanvasElement) => Promise<string>;
16
+ };
@@ -0,0 +1,45 @@
1
+ import { ref } from "vue";
2
+ export function useTesseract(options = {}) {
3
+ const progress = ref(0);
4
+ const status = ref("idle");
5
+ const lang = options.lang ?? "ocrb";
6
+ const langPath = options.langPath ?? "/tesseract/";
7
+ let lib = null;
8
+ function resolvedLangPath() {
9
+ if (!import.meta.client)
10
+ return langPath;
11
+ return new URL(langPath, window.location.origin).toString();
12
+ }
13
+ async function ensureReady() {
14
+ if (!import.meta.client)
15
+ throw new Error("Tesseract OCR is client-only.");
16
+ if (!lib) {
17
+ lib = await import("tesseract.js");
18
+ }
19
+ return lib;
20
+ }
21
+ async function recognize(canvas) {
22
+ const tesseract = await ensureReady();
23
+ progress.value = 0;
24
+ status.value = "starting";
25
+ const result = await tesseract.recognize(canvas, lang, {
26
+ gzip: true,
27
+ cacheMethod: "refresh",
28
+ langPath: resolvedLangPath(),
29
+ logger: (m) => {
30
+ if (m?.status)
31
+ status.value = m.status;
32
+ if (m?.status === "recognizing text" && typeof m?.progress === "number")
33
+ progress.value = Math.round(m.progress * 100);
34
+ }
35
+ });
36
+ status.value = "idle";
37
+ return result?.data?.text || "";
38
+ }
39
+ return {
40
+ progress,
41
+ status,
42
+ ensureReady,
43
+ recognize
44
+ };
45
+ }
@@ -1 +1 @@
1
- export declare const useUserPermission: () => import("../types/permission").PermissionPlugin;
1
+ export declare const useUserPermission: () => unknown;
@@ -1,2 +1,3 @@
1
1
  import type { MaybeRefOrGetter } from 'vue';
2
- export declare function useFuzzy(searchTerm: MaybeRefOrGetter<string>, items: MaybeRefOrGetter<any[]>, fieldName: MaybeRefOrGetter<string[]>, options?: MaybeRefOrGetter<Record<string, any>>): import("vue").ComputedRef<import("fuse.js").FuseResult<any>[]>;
2
+ import type { UseFuseReturn } from '@vueuse/integrations/useFuse';
3
+ export declare function useFuzzy(searchTerm: MaybeRefOrGetter<string>, items: MaybeRefOrGetter<any[]>, fieldName: MaybeRefOrGetter<string[]>, options?: MaybeRefOrGetter<Record<string, any>>): UseFuseReturn<any>['results'];
@@ -0,0 +1,35 @@
1
+ type Event = {
2
+ id: string | undefined;
3
+ title: string;
4
+ start: string;
5
+ end: string;
6
+ color: string;
7
+ detail?: string;
8
+ props: Record<string, any> | any[];
9
+ };
10
+ interface CalendarProps {
11
+ modelValue: Event[];
12
+ locale?: 'th' | 'en';
13
+ toolBarLeft?: string;
14
+ toolBarCenter?: string;
15
+ toolBarRight?: string;
16
+ height?: string | number;
17
+ selectViewDay?: string;
18
+ mode: 'dayGridMonth' | 'timeGridDay';
19
+ }
20
+ declare const __VLS_export: import("vue").DefineComponent<CalendarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
21
+ dialog: (...args: any[]) => void;
22
+ select: (...args: any[]) => void;
23
+ }, string, import("vue").PublicProps, Readonly<CalendarProps> & Readonly<{
24
+ onDialog?: ((...args: any[]) => any) | undefined;
25
+ onSelect?: ((...args: any[]) => any) | undefined;
26
+ }>, {
27
+ height: string | number;
28
+ mode: "dayGridMonth" | "timeGridDay";
29
+ locale: "th" | "en";
30
+ toolBarLeft: string;
31
+ toolBarCenter: string;
32
+ toolBarRight: string;
33
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
@@ -1,84 +1,56 @@
1
- <script lang="ts" setup>
2
- import FullCalendar from '@fullcalendar/vue3'
3
- import dayGridPlugin from '@fullcalendar/daygrid'
4
- import timeGridPlugin from '@fullcalendar/timegrid'
5
- import listPlugin from '@fullcalendar/list'
6
- import interactionPlugin from '@fullcalendar/interaction'
7
- import { ref, computed, withDefaults } from 'vue'
8
- import { type CalendarOptions } from '@fullcalendar/core'
9
-
10
- type Event = {
11
- id: string | undefined
12
- title: string
13
- start: string // YYYY-MM-DD | YYYY-MM-DD HH:mm:ss
14
- end: string // YYYY-MM-DD
15
- color: string
16
- detail?: string
17
- props: Record<string, any> | any[]
18
- }
19
-
20
- interface CalendarProps {
21
- modelValue: Event[]
22
- locale?: 'th' | 'en'
23
- toolBarLeft?: string
24
- toolBarCenter?: string
25
- toolBarRight?: string
26
- height?: string | number
27
- selectViewDay?: string
28
- mode: 'dayGridMonth' | 'timeGridDay'
29
- }
30
-
31
- const props = withDefaults(defineProps<CalendarProps>(), {
32
- locale: 'th',
33
- height: 1200,
34
- toolBarLeft: 'today prev,next',
35
- toolBarCenter: 'title',
36
- toolBarRight: 'timeGridDay,timeGridWeek,dayGridMonth',
37
- mode: 'dayGridMonth',
38
- })
39
-
40
- const emit = defineEmits(['select', 'dialog'])
41
-
1
+ <script setup>
2
+ import FullCalendar from "@fullcalendar/vue3";
3
+ import dayGridPlugin from "@fullcalendar/daygrid";
4
+ import timeGridPlugin from "@fullcalendar/timegrid";
5
+ import listPlugin from "@fullcalendar/list";
6
+ import interactionPlugin from "@fullcalendar/interaction";
7
+ import { ref, computed } from "vue";
8
+ import {} from "@fullcalendar/core";
9
+ const props = defineProps({
10
+ modelValue: { type: Array, required: true },
11
+ locale: { type: String, required: false, default: "th" },
12
+ toolBarLeft: { type: String, required: false, default: "today prev,next" },
13
+ toolBarCenter: { type: String, required: false, default: "title" },
14
+ toolBarRight: { type: String, required: false, default: "timeGridDay,timeGridWeek,dayGridMonth" },
15
+ height: { type: [String, Number], required: false, default: 1200 },
16
+ selectViewDay: { type: String, required: false },
17
+ mode: { type: String, required: true, default: "dayGridMonth" }
18
+ });
19
+ const emit = defineEmits(["select", "dialog"]);
42
20
  const buttonText = computed(() => {
43
21
  return {
44
- today: props.locale === 'th' ? 'วันนี้' : 'today',
45
- month: props.locale === 'th' ? 'เดือน' : 'month',
46
- week: props.locale === 'th' ? 'สัปดาห์' : 'week',
47
- day: props.locale === 'th' ? 'วัน' : 'day',
48
- list: props.locale === 'th' ? 'รายการ' : 'list',
49
- year: props.locale === 'th' ? 'ปี' : 'year',
50
- }
51
- })
52
-
53
- const calendarRef = ref<InstanceType<typeof FullCalendar>>()
54
- const dateViewDay = ref({ date: '', props: {} })
55
-
56
- const handleDateClick = (info: any) => {
57
- emit('select', info.event)
58
- }
59
-
60
- const handleEventClick = (info: any) => {
61
- emit('dialog', true)
62
- emit('select', info.event)
63
- }
64
-
65
- const eventContentDay = (arg: any) => {
66
- const list = document.createElement('div')
67
- list.innerHTML = document.getElementById(arg.event.id.toString())?.innerHTML || ''
68
- return { domNodes: [list] }
69
- }
70
-
71
- // @ts-expect-error
72
- const calendarOptions = ref<CalendarOptions>({
22
+ today: props.locale === "th" ? "\u0E27\u0E31\u0E19\u0E19\u0E35\u0E49" : "today",
23
+ month: props.locale === "th" ? "\u0E40\u0E14\u0E37\u0E2D\u0E19" : "month",
24
+ week: props.locale === "th" ? "\u0E2A\u0E31\u0E1B\u0E14\u0E32\u0E2B\u0E4C" : "week",
25
+ day: props.locale === "th" ? "\u0E27\u0E31\u0E19" : "day",
26
+ list: props.locale === "th" ? "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23" : "list",
27
+ year: props.locale === "th" ? "\u0E1B\u0E35" : "year"
28
+ };
29
+ });
30
+ const calendarRef = ref();
31
+ const dateViewDay = ref({ date: "", props: {} });
32
+ const handleDateClick = (info) => {
33
+ emit("select", info.event);
34
+ };
35
+ const handleEventClick = (info) => {
36
+ emit("dialog", true);
37
+ emit("select", info.event);
38
+ };
39
+ const eventContentDay = (arg) => {
40
+ const list = document.createElement("div");
41
+ list.innerHTML = document.getElementById(arg.event.id.toString())?.innerHTML || "";
42
+ return { domNodes: [list] };
43
+ };
44
+ const calendarOptions = ref({
73
45
  plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
74
46
  initialView: props.mode,
75
47
  locale: props.locale,
76
48
  dayMaxEvents: true,
77
- timeZone: 'UTC',
49
+ timeZone: "UTC",
78
50
  headerToolbar: {
79
51
  left: props.toolBarLeft,
80
52
  center: props.toolBarCenter,
81
- right: props.toolBarRight,
53
+ right: props.toolBarRight
82
54
  },
83
55
  buttonText: buttonText.value,
84
56
  events: props.modelValue,
@@ -87,13 +59,13 @@ const calendarOptions = ref<CalendarOptions>({
87
59
  eventClick: handleEventClick,
88
60
  nowIndicator: true,
89
61
  height: props.height,
90
- eventColor: '#378006',
91
- })
62
+ eventColor: "#378006"
63
+ });
92
64
  </script>
93
65
 
94
66
  <template>
95
67
  <FullCalendar
96
68
  ref="calendarRef"
97
- :options="calendarOptions as CalendarOptions"
69
+ :options="calendarOptions"
98
70
  />
99
71
  </template>