@dragonmastery/dragoncore-vue 0.0.2 → 0.0.4

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 (186) hide show
  1. package/LICENSE +2 -2
  2. package/dist/{ChangePasswordPage-Btu5lf-r.js → ChangePasswordPage-DCews8GU.js} +2 -2
  3. package/dist/{ChangePasswordPage-Btu5lf-r.js.map → ChangePasswordPage-DCews8GU.js.map} +1 -1
  4. package/dist/ChangePasswordPage-Dm5vW0nl.js +6 -0
  5. package/dist/CreateTeamForm-zVlGgmL9.js +27 -0
  6. package/dist/CreateTeamMemberForm-DkCbsJDn.js +27 -0
  7. package/dist/{CreateUserPage-Cmx8xjjv.js → CreateUserPage-B8qeBZij.js} +2 -2
  8. package/dist/{CreateUserPage-Cmx8xjjv.js.map → CreateUserPage-B8qeBZij.js.map} +1 -1
  9. package/dist/CreateUserPage-WjYDkwpb.js +6 -0
  10. package/dist/CreditBalanceDashboard-BTW4IK66.js +27 -0
  11. package/dist/CreditManagement-0JxmCIAd.js +27 -0
  12. package/dist/CustomerCreateSupportTicketForm-CQcv4vrX.js +27 -0
  13. package/dist/CustomerSupportTicketDetailPage-DQa_Zvfe.js +703 -0
  14. package/dist/CustomerSupportTicketDetailPage-DQa_Zvfe.js.map +1 -0
  15. package/dist/CustomerSupportTicketList-CMPRQ_7O.js +27 -0
  16. package/dist/CustomerSupportTicketParent-BOYIren9.js +7 -0
  17. package/dist/{CustomerSupportTicketParent-2mONd9kL.js → CustomerSupportTicketParent-sT8hpgrA.js} +6 -6
  18. package/dist/CustomerSupportTicketParent-sT8hpgrA.js.map +1 -0
  19. package/dist/CustomerSupportTicketSuccess-CnRWm6gX.js +27 -0
  20. package/dist/EditTeamForm-BM90JTjr.js +27 -0
  21. package/dist/EditTeamMemberForm-B8-pI6Xm.js +6 -0
  22. package/dist/{EditTeamMemberForm-ru4WgLz-.js → EditTeamMemberForm-CKbKomrL.js} +27 -5
  23. package/dist/EditTeamMemberForm-CKbKomrL.js.map +1 -0
  24. package/dist/EditUserPage-BG-Fkx_c.js +7 -0
  25. package/dist/{EditUserPage-BxJ5QvIM.js → EditUserPage-XqF25iwz.js} +4 -4
  26. package/dist/{EditUserPage-BxJ5QvIM.js.map → EditUserPage-XqF25iwz.js.map} +1 -1
  27. package/dist/ForgotPassword-CjWv2V7p.js +7 -0
  28. package/dist/{ForgotPassword-CqhenzUG.js → ForgotPassword-D3bjL48L.js} +2 -2
  29. package/dist/{ForgotPassword-CqhenzUG.js.map → ForgotPassword-D3bjL48L.js.map} +1 -1
  30. package/dist/LoginForm--br4Il85.js +7 -0
  31. package/dist/{LoginForm-_PZ51Uwe.js → LoginForm-C85U2E2r.js} +3 -3
  32. package/dist/{LoginForm-_PZ51Uwe.js.map → LoginForm-C85U2E2r.js.map} +1 -1
  33. package/dist/Logout-DHT-5Qz3.js +6 -0
  34. package/dist/{Logout-BMjiqHnS.js → Logout-DZuWLh0O.js} +3 -3
  35. package/dist/{Logout-BMjiqHnS.js.map → Logout-DZuWLh0O.js.map} +1 -1
  36. package/dist/ResetPassword-DAn7dYAp.js +27 -0
  37. package/dist/SavedFiltersPage-BNasEKOY.js +391 -0
  38. package/dist/SavedFiltersPage-BNasEKOY.js.map +1 -0
  39. package/dist/Signup-VZa7U-Ur.js +7 -0
  40. package/dist/{Signup-c2-_yMOM.js → Signup-hpV8J5cM.js} +3 -3
  41. package/dist/{Signup-c2-_yMOM.js.map → Signup-hpV8J5cM.js.map} +1 -1
  42. package/dist/StaffCreateSupportTicketForm-DoHCw60c.js +27 -0
  43. package/dist/StaffSupportTicketDetailPage-D49ibqrO.js +1884 -0
  44. package/dist/StaffSupportTicketDetailPage-D49ibqrO.js.map +1 -0
  45. package/dist/StaffSupportTicketList-BgCIa_9v.js +27 -0
  46. package/dist/StaffSupportTicketParent-C7Mm7W_0.js +7 -0
  47. package/dist/{StaffSupportTicketParent-Cx1buQZw.js → StaffSupportTicketParent-CxrPxXSH.js} +6 -6
  48. package/dist/StaffSupportTicketParent-CxrPxXSH.js.map +1 -0
  49. package/dist/StaffSupportTicketSuccess-DZF2WpZc.js +27 -0
  50. package/dist/SupportStaffPage-nd0HowtH.js +156 -0
  51. package/dist/SupportStaffPage-nd0HowtH.js.map +1 -0
  52. package/dist/SupportTicketDevLifecycleBadge-Cl4y47Sy.js +116 -0
  53. package/dist/SupportTicketDevLifecycleBadge-Cl4y47Sy.js.map +1 -0
  54. package/dist/SupportTicketMaintenancePage-rcJ7EfDj.js +56 -0
  55. package/dist/SupportTicketMaintenancePage-rcJ7EfDj.js.map +1 -0
  56. package/dist/TeamAttachmentsTab-BoOIuTU1.js +27 -0
  57. package/dist/{TeamHistoryTab-gB3H2KZv.js → TeamHistoryTab-CNelXR3Q.js} +19 -6
  58. package/dist/TeamHistoryTab-CNelXR3Q.js.map +1 -0
  59. package/dist/TeamHistoryTab-siesF93u.js +4 -0
  60. package/dist/TeamList-TpS3BhPd.js +27 -0
  61. package/dist/TeamMemberList-CQTxcWNS.js +27 -0
  62. package/dist/TeamMemberParent-Bt0kbyKQ.js +27 -0
  63. package/dist/{NoteList-C0hRPNMO.js → TeamNotesTab-BhVRLG8h.js} +30 -69
  64. package/dist/TeamNotesTab-BhVRLG8h.js.map +1 -0
  65. package/dist/TeamNotesTab-Crp-afAe.js +7 -0
  66. package/dist/TeamParent-BvLiiJq6.js +27 -0
  67. package/dist/TimelineNoteInput-BRsQ2QTz.js +490 -0
  68. package/dist/TimelineNoteInput-BRsQ2QTz.js.map +1 -0
  69. package/dist/{InlineAttachments-I39rOvip.js → TimelineSystemEvent-B69B3eeL.js} +589 -126
  70. package/dist/TimelineSystemEvent-B69B3eeL.js.map +1 -0
  71. package/dist/UserListPage-D68AjrjM.js +4 -0
  72. package/dist/{UserListPage-WU56KiWj.js → UserListPage-OGYOLwlw.js} +3 -3
  73. package/dist/{UserListPage-WU56KiWj.js.map → UserListPage-OGYOLwlw.js.map} +1 -1
  74. package/dist/UserProfilePage-Q68NAGQQ.js +7 -0
  75. package/dist/{UserProfilePage-BtLUY1kt.js → UserProfilePage-uAIfC_NW.js} +4 -4
  76. package/dist/{UserProfilePage-BtLUY1kt.js.map → UserProfilePage-uAIfC_NW.js.map} +1 -1
  77. package/dist/ViewTeam-Bb1WH_Us.js +27 -0
  78. package/dist/ViewTeamMember-CBTAnAhS.js +27 -0
  79. package/dist/{convertToLocalDateTime-D4IoNvRj.js → convertToLocalDateTime-DOSGtMn8.js} +13 -3
  80. package/dist/convertToLocalDateTime-DOSGtMn8.js.map +1 -0
  81. package/dist/{displayIdFormatter-Dz900Awr.js → displayIdFormatter-BoKcrgF5.js} +1 -1
  82. package/dist/{displayIdFormatter-Dz900Awr.js.map → displayIdFormatter-BoKcrgF5.js.map} +1 -1
  83. package/dist/extractRpcErrorMessage-C_UbKgHL.js +20 -0
  84. package/dist/extractRpcErrorMessage-C_UbKgHL.js.map +1 -0
  85. package/dist/index.d.ts +1594 -1320
  86. package/dist/index.js +25 -40
  87. package/dist/{src-o5fMIo5_.js → src-ChwBeNHB.js} +4006 -1522
  88. package/dist/src-ChwBeNHB.js.map +1 -0
  89. package/dist/{useMutation-CFwe7H9j.js → useMutation-B4_S4Xoa.js} +3 -3
  90. package/dist/{useMutation-CFwe7H9j.js.map → useMutation-B4_S4Xoa.js.map} +1 -1
  91. package/dist/{useQuery-p7oJO7OD.js → useQuery-B7ndu5_P.js} +3 -3
  92. package/dist/{useQuery-p7oJO7OD.js.map → useQuery-B7ndu5_P.js.map} +1 -1
  93. package/dist/{useQueryCache-ByayvZgZ.js → useQueryCache-DqcDMsxb.js} +2 -2
  94. package/dist/{useQueryCache-ByayvZgZ.js.map → useQueryCache-DqcDMsxb.js.map} +1 -1
  95. package/dist/{useRpcAuth-BLlRSHy8.js → useRpcAuth-Dp2sec-X.js} +13 -4
  96. package/dist/useRpcAuth-Dp2sec-X.js.map +1 -0
  97. package/package.json +8 -8
  98. package/dist/ChangePasswordPage-mBBuQMkT.js +0 -6
  99. package/dist/CreateTeamForm-n2ut93vM.js +0 -43
  100. package/dist/CreateTeamMemberForm-CcH3AxNL.js +0 -43
  101. package/dist/CreateUserPage-CDrGuW9B.js +0 -6
  102. package/dist/CreditBalanceDashboard-DLz0ioP3.js +0 -43
  103. package/dist/CreditManagement-D3q5S-qc.js +0 -43
  104. package/dist/CustomerCreateSupportTicketForm-Ci7QYkG-.js +0 -43
  105. package/dist/CustomerEditSupportTicketForm-Dd5ZB74k.js +0 -159
  106. package/dist/CustomerEditSupportTicketForm-Dd5ZB74k.js.map +0 -1
  107. package/dist/CustomerEditSupportTicketForm-lLchVjnw.js +0 -9
  108. package/dist/CustomerSupportTicketAttachmentsTab-gBrVO97t.js +0 -43
  109. package/dist/CustomerSupportTicketCustomerNotesTab-D0jhzbOY.js +0 -8
  110. package/dist/CustomerSupportTicketCustomerNotesTab-D1aa9It7.js +0 -23
  111. package/dist/CustomerSupportTicketCustomerNotesTab-D1aa9It7.js.map +0 -1
  112. package/dist/CustomerSupportTicketHistoryTab-BNTf8EZq.js +0 -6
  113. package/dist/CustomerSupportTicketHistoryTab-CFYN_Sa4.js +0 -17
  114. package/dist/CustomerSupportTicketHistoryTab-CFYN_Sa4.js.map +0 -1
  115. package/dist/CustomerSupportTicketList-BkOzFxMP.js +0 -6
  116. package/dist/CustomerSupportTicketList-C2nUPawb.js +0 -166
  117. package/dist/CustomerSupportTicketList-C2nUPawb.js.map +0 -1
  118. package/dist/CustomerSupportTicketParent-2mONd9kL.js.map +0 -1
  119. package/dist/CustomerSupportTicketParent-N8ko1yFE.js +0 -7
  120. package/dist/CustomerSupportTicketSuccess-w_-9NXT4.js +0 -43
  121. package/dist/CustomerViewSupportTicket-CVwNH0lS.js +0 -11
  122. package/dist/CustomerViewSupportTicket-tZkxragu.js +0 -363
  123. package/dist/CustomerViewSupportTicket-tZkxragu.js.map +0 -1
  124. package/dist/EditTeamForm-BioqiTWE.js +0 -43
  125. package/dist/EditTeamMemberForm-DCq0Gsn_.js +0 -7
  126. package/dist/EditTeamMemberForm-ru4WgLz-.js.map +0 -1
  127. package/dist/EditUserPage-XOBuxUxd.js +0 -7
  128. package/dist/FieldsetSection-CsHN38_o.js +0 -27
  129. package/dist/FieldsetSection-CsHN38_o.js.map +0 -1
  130. package/dist/ForgotPassword-CpqvcSFg.js +0 -7
  131. package/dist/InlineAttachments-I39rOvip.js.map +0 -1
  132. package/dist/LoginForm-AM0qkfbU.js +0 -7
  133. package/dist/Logout-BfiBjlaH.js +0 -6
  134. package/dist/NoteList-C0hRPNMO.js.map +0 -1
  135. package/dist/NotificationEmailsPage-BjRqtW95.js +0 -141
  136. package/dist/NotificationEmailsPage-BjRqtW95.js.map +0 -1
  137. package/dist/NotificationEmailsPage-bx-9rg3x.js +0 -7
  138. package/dist/ResetPassword-BQLkR9TZ.js +0 -43
  139. package/dist/Signup-CnCcQlB8.js +0 -7
  140. package/dist/StaffCreateSupportTicketForm-ChVFDJdA.js +0 -43
  141. package/dist/StaffEditSupportTicketForm-DY1Zkf5k.js +0 -9
  142. package/dist/StaffEditSupportTicketForm-DuUKuIGg.js +0 -263
  143. package/dist/StaffEditSupportTicketForm-DuUKuIGg.js.map +0 -1
  144. package/dist/StaffSupportTicketAttachmentsTab-DpDXsHXP.js +0 -43
  145. package/dist/StaffSupportTicketCustomerNotesTab-CusqQV2-.js +0 -23
  146. package/dist/StaffSupportTicketCustomerNotesTab-CusqQV2-.js.map +0 -1
  147. package/dist/StaffSupportTicketCustomerNotesTab-rbJHJ0_V.js +0 -8
  148. package/dist/StaffSupportTicketHistoryTab-D24myEm3.js +0 -17
  149. package/dist/StaffSupportTicketHistoryTab-D24myEm3.js.map +0 -1
  150. package/dist/StaffSupportTicketHistoryTab-nmVma5vp.js +0 -6
  151. package/dist/StaffSupportTicketInternalNotesTab-D8HM--dp.js +0 -23
  152. package/dist/StaffSupportTicketInternalNotesTab-D8HM--dp.js.map +0 -1
  153. package/dist/StaffSupportTicketInternalNotesTab-DihYd5XI.js +0 -8
  154. package/dist/StaffSupportTicketList-DelptSmK.js +0 -43
  155. package/dist/StaffSupportTicketParent-BCrj3ckV.js +0 -7
  156. package/dist/StaffSupportTicketParent-Cx1buQZw.js.map +0 -1
  157. package/dist/StaffSupportTicketSuccess-BYxtY5wZ.js +0 -43
  158. package/dist/StaffSupportTicketWorkflowTab-BrDDBeK9.js +0 -9
  159. package/dist/StaffSupportTicketWorkflowTab-DmVTPzxS.js +0 -1234
  160. package/dist/StaffSupportTicketWorkflowTab-DmVTPzxS.js.map +0 -1
  161. package/dist/SupportTicketHistoryTab-CLMopA7a.js +0 -220
  162. package/dist/SupportTicketHistoryTab-CLMopA7a.js.map +0 -1
  163. package/dist/SupportTicketStatusBadge-YdZzjvkh.js +0 -163
  164. package/dist/SupportTicketStatusBadge-YdZzjvkh.js.map +0 -1
  165. package/dist/TeamAttachmentsTab-BxUpTWYh.js +0 -43
  166. package/dist/TeamHistoryTab-CUCT9MRG.js +0 -5
  167. package/dist/TeamHistoryTab-gB3H2KZv.js.map +0 -1
  168. package/dist/TeamList-By6pzWm5.js +0 -43
  169. package/dist/TeamMemberList-CYV9fWEb.js +0 -43
  170. package/dist/TeamMemberParent-CVvGqpxD.js +0 -43
  171. package/dist/TeamNotesTab-pfXTDhg6.js +0 -23
  172. package/dist/TeamNotesTab-pfXTDhg6.js.map +0 -1
  173. package/dist/TeamNotesTab-u4cDC67X.js +0 -8
  174. package/dist/TeamParent-BxT1KubK.js +0 -43
  175. package/dist/UserListPage-DsQdH2Sm.js +0 -4
  176. package/dist/UserProfilePage-B73JhjUu.js +0 -7
  177. package/dist/ViewTeam-DzX-obEl.js +0 -43
  178. package/dist/ViewTeamMember-PF6S_4Pb.js +0 -43
  179. package/dist/ZiniaContainer-C7c7Vwkh.js +0 -18
  180. package/dist/ZiniaContainer-C7c7Vwkh.js.map +0 -1
  181. package/dist/convertToLocalDateTime-D4IoNvRj.js.map +0 -1
  182. package/dist/creditValueFormatter-DftEzu8d.js +0 -128
  183. package/dist/creditValueFormatter-DftEzu8d.js.map +0 -1
  184. package/dist/src-o5fMIo5_.js.map +0 -1
  185. package/dist/useRpcAuth-BLlRSHy8.js.map +0 -1
  186. /package/dist/{TeamMembersTab-CpE9BaCi.js → TeamMembersTab-DTJxmb-M.js} +0 -0
@@ -0,0 +1,27 @@
1
+ import "./useRpcAuth-Dp2sec-X.js";
2
+ import "./useQueryCache-DqcDMsxb.js";
3
+ import "./useMutation-B4_S4Xoa.js";
4
+ import "./useQuery-B7ndu5_P.js";
5
+ import { ut as TeamParent_default } from "./src-ChwBeNHB.js";
6
+ import "./AppLink-CHMMrSFI.js";
7
+ import "./TimelineSystemEvent-B69B3eeL.js";
8
+ import "./TeamMembersTab-4gmnP9sD.js";
9
+ import "./Appearance-BfPdKMXw.js";
10
+ import "./useBreadcrumbs-DmgSucoe.js";
11
+ import "./EditTeamMemberForm-CKbKomrL.js";
12
+ import "./TeamHistoryTab-CNelXR3Q.js";
13
+ import "./UserProfilePage-uAIfC_NW.js";
14
+ import "./ChangePasswordPage-DCews8GU.js";
15
+ import "./TeamNotesTab-BhVRLG8h.js";
16
+ import "./CustomerSupportTicketParent-sT8hpgrA.js";
17
+ import "./SupportTicketDevLifecycleBadge-Cl4y47Sy.js";
18
+ import "./StaffSupportTicketParent-CxrPxXSH.js";
19
+ import "./LoginForm-C85U2E2r.js";
20
+ import "./Signup-hpV8J5cM.js";
21
+ import "./ForgotPassword-D3bjL48L.js";
22
+ import "./Logout-DZuWLh0O.js";
23
+ import "./UserListPage-OGYOLwlw.js";
24
+ import "./CreateUserPage-B8qeBZij.js";
25
+ import "./EditUserPage-XqF25iwz.js";
26
+
27
+ export { TeamParent_default as default };
@@ -0,0 +1,490 @@
1
+ import { a as InlineAttachments_default, r as formatTicketDate } from "./TimelineSystemEvent-B69B3eeL.js";
2
+ import { Comment, Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, h, normalizeClass, openBlock, ref, renderSlot, resolveDynamicComponent, toDisplayString, unref, useSlots, vModelCheckbox, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
3
+ import { supportTicketNumberToPriority } from "@dragonmastery/dragoncore-shared";
4
+ import { useForm, withMetadata } from "@dragonmastery/zinia-forms-core";
5
+ import { z } from "zod";
6
+
7
+ //#region src/slices/support_ticket/shared/SupportTicketAttachmentsCollapsible.vue
8
+ const _hoisted_1$3 = {
9
+ key: 0,
10
+ class: "w-full"
11
+ };
12
+ const _hoisted_2$3 = { class: "collapse collapse-arrow bg-base-200" };
13
+ const _hoisted_3$3 = { class: "collapse-title text-sm font-medium px-4 py-2 min-h-0" };
14
+ const _hoisted_4$3 = { class: "flex items-center gap-2" };
15
+ const _hoisted_5$1 = { class: "collapse-content px-0" };
16
+ const _hoisted_6$1 = { class: "px-4 pb-4" };
17
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
18
+ __name: "SupportTicketAttachmentsCollapsible",
19
+ props: {
20
+ recordId: {},
21
+ locked: { type: Boolean },
22
+ editable: { type: Boolean }
23
+ },
24
+ emits: ["uploaded", "deleted"],
25
+ setup(__props, { emit: __emit }) {
26
+ const attachmentsCount = ref(0);
27
+ const emit = __emit;
28
+ const attachmentsExpanded = ref(false);
29
+ return (_ctx, _cache) => {
30
+ return __props.recordId ? (openBlock(), createElementBlock("div", _hoisted_1$3, [createElementVNode("div", _hoisted_2$3, [
31
+ withDirectives(createElementVNode("input", {
32
+ type: "checkbox",
33
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => attachmentsExpanded.value = $event)
34
+ }, null, 512), [[vModelCheckbox, attachmentsExpanded.value]]),
35
+ createElementVNode("div", _hoisted_3$3, [createElementVNode("div", _hoisted_4$3, [_cache[4] || (_cache[4] = createElementVNode("svg", {
36
+ xmlns: "http://www.w3.org/2000/svg",
37
+ class: "h-4 w-4",
38
+ fill: "none",
39
+ viewBox: "0 0 24 24",
40
+ stroke: "currentColor"
41
+ }, [createElementVNode("path", {
42
+ "stroke-linecap": "round",
43
+ "stroke-linejoin": "round",
44
+ "stroke-width": "2",
45
+ d: "M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"
46
+ })], -1)), createElementVNode("span", null, "Attachments (" + toDisplayString(attachmentsCount.value) + ")", 1)])]),
47
+ createElementVNode("div", _hoisted_5$1, [createElementVNode("div", _hoisted_6$1, [createVNode(InlineAttachments_default, {
48
+ "record-id": __props.recordId,
49
+ "can-upload": __props.editable && !__props.locked,
50
+ "can-delete": __props.editable && !__props.locked,
51
+ "onUpdate:attachmentsCount": _cache[1] || (_cache[1] = ($event) => attachmentsCount.value = $event),
52
+ onUploaded: _cache[2] || (_cache[2] = ($event) => emit("uploaded")),
53
+ onDeleted: _cache[3] || (_cache[3] = ($event) => emit("deleted"))
54
+ }, null, 8, [
55
+ "record-id",
56
+ "can-upload",
57
+ "can-delete"
58
+ ])])])
59
+ ])])) : createCommentVNode("v-if", true);
60
+ };
61
+ }
62
+ });
63
+ var SupportTicketAttachmentsCollapsible_default = _sfc_main$3;
64
+
65
+ //#endregion
66
+ //#region src/slices/support_ticket/utils/parseRecordVersions.ts
67
+ const SKIP_FIELDS = new Set([
68
+ "updated_at",
69
+ "updated_by",
70
+ "id",
71
+ "display_id"
72
+ ]);
73
+ /** Fields that store user IDs - display names from lookup instead of raw IDs */
74
+ const USER_ID_FIELDS = new Set([
75
+ "assigned_to",
76
+ "created_by",
77
+ "updated_by",
78
+ "archived_by",
79
+ "deleted_by"
80
+ ]);
81
+ function truncate(value, maxLength = 50) {
82
+ if (value.length <= maxLength) return value;
83
+ return value.substring(0, maxLength) + "...";
84
+ }
85
+ function formatEnumValue(value) {
86
+ return value.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
87
+ }
88
+ function formatFieldValue(fieldName, value, truncateLong = false, displayMap) {
89
+ if (value === null || value === void 0) return "";
90
+ if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}/.test(value)) return formatTicketDate(value).formatted;
91
+ if (typeof value === "boolean") return value ? "Yes" : "No";
92
+ if (typeof value === "string" && USER_ID_FIELDS.has(fieldName) && displayMap) return displayMap.get(value) ?? value;
93
+ if (fieldName === "priority") {
94
+ if (typeof value === "number") return formatEnumValue(supportTicketNumberToPriority(value));
95
+ if (typeof value === "string") return formatEnumValue(value);
96
+ }
97
+ if (typeof value === "string") {
98
+ if (fieldName.includes("status") || fieldName.includes("type") || fieldName.includes("lifecycle")) return formatEnumValue(value);
99
+ if (truncateLong && (fieldName === "title" || fieldName === "description")) return truncate(value);
100
+ }
101
+ return String(value);
102
+ }
103
+ function generateActionMessage(fieldName, oldValue, newValue) {
104
+ switch (fieldName) {
105
+ case "assigned_to":
106
+ if (oldValue === null || oldValue === void 0) return "assigned to";
107
+ return "reassigned to";
108
+ case "title": return "changed the title";
109
+ case "description": return "updated the description";
110
+ case "type": return "changed type";
111
+ case "priority": return "changed priority";
112
+ case "approval_status": return "changed status";
113
+ case "dev_lifecycle": return "moved";
114
+ case "credit_value":
115
+ if (oldValue === null || oldValue === void 0) return "set credits";
116
+ return "changed credits";
117
+ case "delivered_value":
118
+ if (oldValue === null || oldValue === void 0) return "set delivered value";
119
+ return "changed delivered value";
120
+ case "start_at":
121
+ if (oldValue === null || oldValue === void 0) return "set start date";
122
+ if (newValue === null || newValue === void 0) return "cleared start date";
123
+ return "changed start date";
124
+ case "target_at":
125
+ if (oldValue === null || oldValue === void 0) return "set target date";
126
+ if (newValue === null || newValue === void 0) return "cleared target date";
127
+ return "changed target date";
128
+ case "completed_at":
129
+ if (oldValue === null || oldValue === void 0) return "marked as completed";
130
+ if (newValue === null || newValue === void 0) return "cleared completed date";
131
+ return "changed completed date";
132
+ case "locked_approval_at":
133
+ if (oldValue === null || oldValue === void 0 && newValue !== null && newValue !== void 0) return "locked the ticket";
134
+ return "changed lock status";
135
+ case "archived_at":
136
+ if (oldValue === null || oldValue === void 0 && newValue !== null && newValue !== void 0) return "archived the ticket";
137
+ if (oldValue !== null && oldValue !== void 0 && (newValue === null || newValue === void 0)) return "unarchived the ticket";
138
+ return "changed archive status";
139
+ case "requester_email": return "changed requester email";
140
+ case "requester_name": return "changed requester name";
141
+ case "attachment_added": return "added attachment";
142
+ case "attachment_removed": return "removed attachment";
143
+ default: return `updated ${fieldName.replace(/_/g, " ")}`;
144
+ }
145
+ }
146
+ function parseRecord(recordJson) {
147
+ if (!recordJson) return null;
148
+ try {
149
+ return JSON.parse(recordJson);
150
+ } catch {
151
+ return null;
152
+ }
153
+ }
154
+ function parseRecordVersions(versions, displayMap) {
155
+ const events = [];
156
+ for (const version of versions) {
157
+ const author = version.auth_username || "Unknown";
158
+ const timestamp = version.recorded_at;
159
+ if (version.operation === "insert") {
160
+ events.push({
161
+ id: `${version.id}-insert`,
162
+ timestamp,
163
+ author,
164
+ message: "created this ticket"
165
+ });
166
+ continue;
167
+ }
168
+ if (version.operation === "update") {
169
+ const oldRecord = parseRecord(version.old_record);
170
+ const newRecord = parseRecord(version.record);
171
+ if (!oldRecord || !newRecord) continue;
172
+ for (const [fieldName, newValue] of Object.entries(newRecord)) {
173
+ if (SKIP_FIELDS.has(fieldName)) continue;
174
+ const oldValue = oldRecord[fieldName];
175
+ if (oldValue !== newValue) {
176
+ const oldFormatted = oldValue !== null && oldValue !== void 0 ? formatFieldValue(fieldName, oldValue, true, displayMap) : null;
177
+ const newFormatted = newValue !== null && newValue !== void 0 ? formatFieldValue(fieldName, newValue, true, displayMap) : null;
178
+ events.push({
179
+ id: `${version.id}-${fieldName}`,
180
+ timestamp,
181
+ author,
182
+ message: generateActionMessage(fieldName, oldValue, newValue),
183
+ oldValue: oldFormatted || null,
184
+ newValue: newFormatted || null,
185
+ fieldName
186
+ });
187
+ }
188
+ }
189
+ }
190
+ }
191
+ events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
192
+ return events;
193
+ }
194
+
195
+ //#endregion
196
+ //#region src/slices/support_ticket/shared/ActionBannerAlert.vue
197
+ const _hoisted_1$2 = { class: "flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-3" };
198
+ const _hoisted_2$2 = { class: "flex items-start gap-3 min-w-0" };
199
+ const _hoisted_3$2 = { class: "flex-1 min-w-0" };
200
+ const _hoisted_4$2 = {
201
+ key: 0,
202
+ class: "grid grid-cols-2 gap-2 sm:flex sm:flex-row sm:flex-wrap sm:ml-auto sm:shrink-0 sm:[&>*]:w-auto"
203
+ };
204
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
205
+ __name: "ActionBannerAlert",
206
+ props: {
207
+ variant: {},
208
+ icon: {}
209
+ },
210
+ setup(__props) {
211
+ const props = __props;
212
+ const slots = useSlots();
213
+ const variantBorderClass = computed(() => {
214
+ return {
215
+ warning: "border-l-warning",
216
+ success: "border-l-success",
217
+ error: "border-l-error",
218
+ info: "border-l-info",
219
+ neutral: "border-l-base-content/30"
220
+ }[props.variant];
221
+ });
222
+ const hasActions = computed(() => {
223
+ const actionsSlot = slots.actions;
224
+ if (!actionsSlot) return false;
225
+ return !!actionsSlot()?.length;
226
+ });
227
+ const iconComponent = computed(() => {
228
+ if (!props.icon) return null;
229
+ return {
230
+ lock: () => h("svg", {
231
+ xmlns: "http://www.w3.org/2000/svg",
232
+ fill: "none",
233
+ viewBox: "0 0 24 24",
234
+ "stroke-width": "1.5",
235
+ stroke: "currentColor",
236
+ class: "w-5 h-5"
237
+ }, [h("path", {
238
+ "stroke-linecap": "round",
239
+ "stroke-linejoin": "round",
240
+ d: "M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"
241
+ })]),
242
+ clock: () => h("svg", {
243
+ xmlns: "http://www.w3.org/2000/svg",
244
+ fill: "none",
245
+ viewBox: "0 0 24 24",
246
+ "stroke-width": "1.5",
247
+ stroke: "currentColor",
248
+ class: "w-5 h-5"
249
+ }, [h("path", {
250
+ "stroke-linecap": "round",
251
+ "stroke-linejoin": "round",
252
+ d: "M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"
253
+ })]),
254
+ info: () => h("svg", {
255
+ xmlns: "http://www.w3.org/2000/svg",
256
+ fill: "none",
257
+ viewBox: "0 0 24 24",
258
+ "stroke-width": "1.5",
259
+ stroke: "currentColor",
260
+ class: "w-5 h-5"
261
+ }, [h("path", {
262
+ "stroke-linecap": "round",
263
+ "stroke-linejoin": "round",
264
+ d: "M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
265
+ })]),
266
+ archive: () => h("svg", {
267
+ xmlns: "http://www.w3.org/2000/svg",
268
+ fill: "none",
269
+ viewBox: "0 0 24 24",
270
+ "stroke-width": "1.5",
271
+ stroke: "currentColor",
272
+ class: "w-5 h-5"
273
+ }, [h("path", {
274
+ "stroke-linecap": "round",
275
+ "stroke-linejoin": "round",
276
+ d: "M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z"
277
+ })])
278
+ }[props.icon] ?? null;
279
+ });
280
+ return (_ctx, _cache) => {
281
+ return openBlock(), createElementBlock("div", {
282
+ role: "alert",
283
+ class: normalizeClass(["py-3 px-4 w-full rounded-lg border border-base-300 border-l-4 bg-base-200/60", variantBorderClass.value])
284
+ }, [createCommentVNode(" Mobile-first: stack vertically on small screens, row on desktop "), createElementVNode("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [__props.icon ? (openBlock(), createBlock(resolveDynamicComponent(iconComponent.value), {
285
+ key: 0,
286
+ class: "shrink-0 w-5 h-5 opacity-90 mt-0.5"
287
+ })) : createCommentVNode("v-if", true), createElementVNode("span", _hoisted_3$2, [renderSlot(_ctx.$slots, "default")])]), hasActions.value ? (openBlock(), createElementBlock("div", _hoisted_4$2, [renderSlot(_ctx.$slots, "actions")])) : createCommentVNode("v-if", true)])], 2);
288
+ };
289
+ }
290
+ });
291
+ var ActionBannerAlert_default = _sfc_main$2;
292
+
293
+ //#endregion
294
+ //#region src/slices/support_ticket/shared/MetadataField.vue
295
+ const _hoisted_1$1 = { class: "flex flex-col" };
296
+ const _hoisted_2$1 = { class: "text-xs font-semibold uppercase tracking-wide text-base-content/50 mb-0.5" };
297
+ const _hoisted_3$1 = ["onKeydown"];
298
+ const _hoisted_4$1 = { key: 1 };
299
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
300
+ __name: "MetadataField",
301
+ props: {
302
+ label: {},
303
+ copyable: {
304
+ type: Boolean,
305
+ default: false
306
+ }
307
+ },
308
+ setup(__props) {
309
+ const props = __props;
310
+ const slots = useSlots();
311
+ const valueRef = ref(null);
312
+ const copied = ref(false);
313
+ let copyTimeoutId = null;
314
+ const hasContent = computed(() => {
315
+ const defaultSlot = slots.default;
316
+ if (!defaultSlot) return false;
317
+ const vnodes = defaultSlot();
318
+ if (!vnodes || !Array.isArray(vnodes)) return false;
319
+ return vnodes.some((v) => v.type !== Comment);
320
+ });
321
+ async function handleCopy() {
322
+ if (!props.copyable) return;
323
+ const text = valueRef.value?.textContent?.trim();
324
+ if (!text) return;
325
+ try {
326
+ await navigator.clipboard.writeText(text);
327
+ copied.value = true;
328
+ if (copyTimeoutId) clearTimeout(copyTimeoutId);
329
+ copyTimeoutId = setTimeout(() => {
330
+ copied.value = false;
331
+ copyTimeoutId = null;
332
+ }, 1500);
333
+ } catch {}
334
+ }
335
+ return (_ctx, _cache) => {
336
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("span", _hoisted_2$1, toDisplayString(__props.label), 1), hasContent.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [__props.copyable ? (openBlock(), createElementBlock("span", {
337
+ key: 0,
338
+ ref_key: "valueRef",
339
+ ref: valueRef,
340
+ role: "button",
341
+ tabindex: "0",
342
+ class: "font-mono cursor-pointer select-all",
343
+ onClick: handleCopy,
344
+ onKeydown: [withKeys(handleCopy, ["enter"]), withKeys(withModifiers(handleCopy, ["prevent"]), ["space"])]
345
+ }, [createTextVNode(toDisplayString(copied.value ? "Copied!" : void 0) + " ", 1), !copied.value ? renderSlot(_ctx.$slots, "default", { key: 0 }) : createCommentVNode("v-if", true)], 40, _hoisted_3$1)) : (openBlock(), createElementBlock("span", _hoisted_4$1, [renderSlot(_ctx.$slots, "default")]))], 64)) : renderSlot(_ctx.$slots, "empty", { key: 1 }, () => [_cache[0] || (_cache[0] = createElementVNode("span", { class: "text-base-content/50 italic text-sm" }, "Not set", -1))])]);
346
+ };
347
+ }
348
+ });
349
+ var MetadataField_default = _sfc_main$1;
350
+
351
+ //#endregion
352
+ //#region src/slices/support_ticket/shared/timelineNoteFormMetadata.ts
353
+ /** Schema for adding a comment/note on support ticket timeline. */
354
+ const TimelineNoteCreateSchema = z.object({
355
+ body: z.string().min(1, "Comment is required").trim(),
356
+ is_internal: z.boolean().optional().default(false)
357
+ });
358
+ const timelineNoteCreateMetadata = withMetadata(TimelineNoteCreateSchema, "timelineNoteCreateForm", {
359
+ body: {
360
+ label: "Comment",
361
+ placeholder: "Add a comment...",
362
+ inputType: "textarea"
363
+ },
364
+ is_internal: {
365
+ label: "Internal Note",
366
+ helpText: "Internal notes are not visible to the customer"
367
+ }
368
+ });
369
+
370
+ //#endregion
371
+ //#region src/slices/support_ticket/shared/TimelineNoteInput.vue
372
+ const _hoisted_1 = { class: "border-t border-base-200 pt-4 mt-4 w-full" };
373
+ const _hoisted_2 = {
374
+ key: 0,
375
+ class: "bg-base-200/50 rounded-lg p-4 text-center"
376
+ };
377
+ const _hoisted_3 = { class: "col-span-full" };
378
+ const _hoisted_4 = { class: "col-span-full flex flex-wrap gap-2 justify-between items-center" };
379
+ const _hoisted_5 = {
380
+ key: 0,
381
+ class: "join"
382
+ };
383
+ const _hoisted_6 = ["disabled"];
384
+ const _hoisted_7 = ["disabled"];
385
+ const _hoisted_8 = { key: 1 };
386
+ const _sfc_main = /* @__PURE__ */ defineComponent({
387
+ __name: "TimelineNoteInput",
388
+ props: {
389
+ showTypeToggle: { type: Boolean },
390
+ disabled: { type: Boolean },
391
+ noteType: {},
392
+ onSubmit: { type: Function }
393
+ },
394
+ emits: ["update:noteType"],
395
+ setup(__props, { expose: __expose, emit: __emit }) {
396
+ const props = __props;
397
+ const formWrapperRef = ref(null);
398
+ const emit = __emit;
399
+ const { form, zinia, ZiniaForm, ZiniaSubmitButton, ZiniaFormErrorsSummary, refreshFormData } = useForm(timelineNoteCreateMetadata, {
400
+ storeName: "timeline-note-input",
401
+ persistToLocalStorage: false,
402
+ renderStyle: "daisy_ui",
403
+ fetchData: async () => ({
404
+ body: "",
405
+ is_internal: props.noteType === "internal"
406
+ })
407
+ });
408
+ watch(() => props.noteType, (noteType) => {
409
+ if (noteType !== void 0) form.setValue("is_internal", noteType === "internal");
410
+ }, { immediate: true });
411
+ watch(() => form.values.is_internal, (isInternal) => {
412
+ if (props.showTypeToggle) emit("update:noteType", isInternal ? "internal" : "customer");
413
+ });
414
+ function handleKeydown(e) {
415
+ if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
416
+ e.preventDefault();
417
+ (formWrapperRef.value?.closest("form"))?.requestSubmit();
418
+ }
419
+ }
420
+ async function handleSubmit(formData) {
421
+ await props.onSubmit({
422
+ content: (formData.body ?? "").trim(),
423
+ noteType: props.showTypeToggle && formData.is_internal ? "internal" : "customer"
424
+ });
425
+ }
426
+ function handleSuccess() {
427
+ refreshFormData();
428
+ document.activeElement?.blur();
429
+ }
430
+ function handleError(_error) {}
431
+ function reset() {
432
+ refreshFormData();
433
+ }
434
+ __expose({ reset });
435
+ return (_ctx, _cache) => {
436
+ return openBlock(), createElementBlock("div", _hoisted_1, [__props.disabled ? (openBlock(), createElementBlock("div", _hoisted_2, [..._cache[2] || (_cache[2] = [createElementVNode("span", { class: "text-base-content/50 text-sm inline-flex items-center gap-1.5" }, [createElementVNode("svg", {
437
+ xmlns: "http://www.w3.org/2000/svg",
438
+ fill: "none",
439
+ viewBox: "0 0 24 24",
440
+ "stroke-width": "1.5",
441
+ stroke: "currentColor",
442
+ class: "w-4 h-4"
443
+ }, [createElementVNode("path", {
444
+ "stroke-linecap": "round",
445
+ "stroke-linejoin": "round",
446
+ d: "M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"
447
+ })]), createTextVNode(" This ticket has been locked. You can no longer add comments. ")], -1)])])) : (openBlock(), createBlock(unref(ZiniaForm), {
448
+ key: 1,
449
+ onHandleSubmit: handleSubmit,
450
+ onSuccess: handleSuccess,
451
+ onError: handleError,
452
+ title: "",
453
+ subtitle: ""
454
+ }, {
455
+ default: withCtx(() => [createElementVNode("div", {
456
+ ref_key: "formWrapperRef",
457
+ ref: formWrapperRef,
458
+ class: "grid grid-cols-1 gap-4 w-full",
459
+ onKeydown: handleKeydown
460
+ }, [
461
+ __props.showTypeToggle ? (openBlock(), createElementBlock("p", {
462
+ key: 0,
463
+ class: normalizeClass(["col-span-full text-xs mb-1", unref(form).values.is_internal ? "text-warning" : "text-info"])
464
+ }, toDisplayString(unref(form).values.is_internal ? "🔒 Internal — not visible to customer" : "Visible to customer"), 3)) : createCommentVNode("v-if", true),
465
+ createElementVNode("div", _hoisted_3, [createVNode(unref(zinia).BodyField, { class: "textarea w-full" })]),
466
+ createElementVNode("div", _hoisted_4, [__props.showTypeToggle ? (openBlock(), createElementBlock("div", _hoisted_5, [createElementVNode("button", {
467
+ type: "button",
468
+ class: normalizeClass(["btn btn-sm join-item", !unref(form).values.is_internal ? "btn-info btn-active" : ""]),
469
+ disabled: unref(form).isSubmitting,
470
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(form).setValue("is_internal", false))
471
+ }, " Customer Note ", 10, _hoisted_6), createElementVNode("button", {
472
+ type: "button",
473
+ class: normalizeClass(["btn btn-sm join-item", unref(form).values.is_internal ? "btn-warning btn-active" : ""]),
474
+ disabled: unref(form).isSubmitting,
475
+ onClick: _cache[1] || (_cache[1] = ($event) => unref(form).setValue("is_internal", true))
476
+ }, " Internal Note ", 10, _hoisted_7)])) : (openBlock(), createElementBlock("div", _hoisted_8)), createVNode(unref(ZiniaSubmitButton), {
477
+ submitText: "Comment",
478
+ submittingText: "Adding..."
479
+ })])
480
+ ], 544)]),
481
+ _: 1
482
+ }))]);
483
+ };
484
+ }
485
+ });
486
+ var TimelineNoteInput_default = _sfc_main;
487
+
488
+ //#endregion
489
+ export { SupportTicketAttachmentsCollapsible_default as a, parseRecordVersions as i, MetadataField_default as n, ActionBannerAlert_default as r, TimelineNoteInput_default as t };
490
+ //# sourceMappingURL=TimelineNoteInput-BRsQ2QTz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimelineNoteInput-BRsQ2QTz.js","names":["events: SystemEvent[]","map: Record<AlertVariant, string>","copyTimeoutId: ReturnType<typeof setTimeout> | null"],"sources":["../src/slices/support_ticket/shared/SupportTicketAttachmentsCollapsible.vue","../src/slices/support_ticket/utils/parseRecordVersions.ts","../src/slices/support_ticket/shared/ActionBannerAlert.vue","../src/slices/support_ticket/shared/MetadataField.vue","../src/slices/support_ticket/shared/timelineNoteFormMetadata.ts","../src/slices/support_ticket/shared/TimelineNoteInput.vue"],"sourcesContent":["<template>\n <div v-if=\"recordId\" class=\"w-full\">\n <div class=\"collapse collapse-arrow bg-base-200\">\n <input type=\"checkbox\" v-model=\"attachmentsExpanded\" />\n <div class=\"collapse-title text-sm font-medium px-4 py-2 min-h-0\">\n <div class=\"flex items-center gap-2\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13\"\n />\n </svg>\n <span>Attachments ({{ attachmentsCount }})</span>\n </div>\n </div>\n <div class=\"collapse-content px-0\">\n <div class=\"px-4 pb-4\">\n <InlineAttachments\n :record-id=\"recordId\"\n :can-upload=\"editable && !locked\"\n :can-delete=\"editable && !locked\"\n @update:attachments-count=\"attachmentsCount = $event\"\n @uploaded=\"emit('uploaded')\"\n @deleted=\"emit('deleted')\"\n />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport InlineAttachments from './InlineAttachments.vue';\n\nconst attachmentsCount = ref(0);\n\ninterface Props {\n recordId: string;\n locked: boolean;\n editable: boolean;\n}\n\ndefineProps<Props>();\n\nconst emit = defineEmits<{ uploaded: []; deleted: [] }>();\n\nconst attachmentsExpanded = ref(false);\n</script>\n","import {\n supportTicketNumberToPriority,\n type RecordVersionReadDto,\n} from '@dragonmastery/dragoncore-shared';\nimport { formatTicketDate } from './formatTicketDate';\n\nexport interface SystemEvent {\n id: string;\n timestamp: string;\n author: string;\n message: string;\n oldValue?: string | null;\n newValue?: string | null;\n fieldName?: string; // Field name that changed (for filtering)\n}\n\nconst SKIP_FIELDS = new Set(['updated_at', 'updated_by', 'id', 'display_id']);\n\n/** Fields that store user IDs - display names from lookup instead of raw IDs */\nconst USER_ID_FIELDS = new Set([\n 'assigned_to',\n 'created_by',\n 'updated_by',\n 'archived_by',\n 'deleted_by',\n]);\n\nfunction truncate(value: string, maxLength: number = 50): string {\n if (value.length <= maxLength) return value;\n return value.substring(0, maxLength) + '...';\n}\n\nfunction formatEnumValue(value: string): string {\n return value\n .split('_')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n\nfunction formatFieldValue(\n fieldName: string,\n value: unknown,\n truncateLong: boolean = false,\n displayMap?: Map<string, string>,\n): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n return formatTicketDate(value).formatted;\n }\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n // User ID fields: display name from lookup when available\n if (typeof value === 'string' && USER_ID_FIELDS.has(fieldName) && displayMap) {\n return displayMap.get(value) ?? value;\n }\n // Priority: DB stores number (1-4), record_versions may have legacy string or new number\n if (fieldName === 'priority') {\n if (typeof value === 'number') {\n return formatEnumValue(supportTicketNumberToPriority(value));\n }\n if (typeof value === 'string') return formatEnumValue(value);\n }\n if (typeof value === 'string') {\n if (\n fieldName.includes('status') ||\n fieldName.includes('type') ||\n fieldName.includes('lifecycle')\n ) {\n return formatEnumValue(value);\n }\n // Truncate title and description\n if (truncateLong && (fieldName === 'title' || fieldName === 'description')) {\n return truncate(value);\n }\n }\n return String(value);\n}\n\nfunction generateActionMessage(fieldName: string, oldValue: unknown, newValue: unknown): string {\n switch (fieldName) {\n case 'assigned_to':\n if (oldValue === null || oldValue === undefined) return 'assigned to';\n return 'reassigned to';\n case 'title':\n return 'changed the title';\n case 'description':\n return 'updated the description';\n case 'type':\n return 'changed type';\n case 'priority':\n return 'changed priority';\n case 'approval_status':\n return 'changed status';\n case 'dev_lifecycle':\n return 'moved';\n case 'credit_value':\n if (oldValue === null || oldValue === undefined) return 'set credits';\n return 'changed credits';\n case 'delivered_value':\n if (oldValue === null || oldValue === undefined) return 'set delivered value';\n return 'changed delivered value';\n case 'start_at':\n if (oldValue === null || oldValue === undefined) return 'set start date';\n if (newValue === null || newValue === undefined) return 'cleared start date';\n return 'changed start date';\n case 'target_at':\n if (oldValue === null || oldValue === undefined) return 'set target date';\n if (newValue === null || newValue === undefined) return 'cleared target date';\n return 'changed target date';\n case 'completed_at':\n if (oldValue === null || oldValue === undefined) return 'marked as completed';\n if (newValue === null || newValue === undefined) return 'cleared completed date';\n return 'changed completed date';\n case 'locked_approval_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'locked the ticket';\n }\n return 'changed lock status';\n case 'archived_at':\n if (\n oldValue === null ||\n (oldValue === undefined && newValue !== null && newValue !== undefined)\n ) {\n return 'archived the ticket';\n }\n if (\n oldValue !== null &&\n oldValue !== undefined &&\n (newValue === null || newValue === undefined)\n ) {\n return 'unarchived the ticket';\n }\n return 'changed archive status';\n case 'requester_email':\n return 'changed requester email';\n case 'requester_name':\n return 'changed requester name';\n case 'attachment_added':\n return 'added attachment';\n case 'attachment_removed':\n return 'removed attachment';\n default:\n return `updated ${fieldName.replace(/_/g, ' ')}`;\n }\n}\n\nfunction parseRecord(recordJson: string | null | undefined): Record<string, unknown> | null {\n if (!recordJson) return null;\n try {\n return JSON.parse(recordJson);\n } catch {\n return null;\n }\n}\n\nexport function parseRecordVersions(\n versions: RecordVersionReadDto[],\n displayMap?: Map<string, string>,\n): SystemEvent[] {\n const events: SystemEvent[] = [];\n\n for (const version of versions) {\n const author = version.auth_username || 'Unknown';\n const timestamp = version.recorded_at;\n\n if (version.operation === 'insert') {\n events.push({\n id: `${version.id}-insert`,\n timestamp,\n author,\n message: 'created this ticket',\n });\n continue;\n }\n\n if (version.operation === 'update') {\n const oldRecord = parseRecord(version.old_record);\n const newRecord = parseRecord(version.record);\n\n if (!oldRecord || !newRecord) continue;\n\n for (const [fieldName, newValue] of Object.entries(newRecord)) {\n if (SKIP_FIELDS.has(fieldName)) continue;\n\n const oldValue = oldRecord[fieldName];\n\n if (oldValue !== newValue) {\n const oldFormatted =\n oldValue !== null && oldValue !== undefined\n ? formatFieldValue(fieldName, oldValue, true, displayMap)\n : null;\n const newFormatted =\n newValue !== null && newValue !== undefined\n ? formatFieldValue(fieldName, newValue, true, displayMap)\n : null;\n\n events.push({\n id: `${version.id}-${fieldName}`,\n timestamp,\n author,\n message: generateActionMessage(fieldName, oldValue, newValue),\n oldValue: oldFormatted || null,\n newValue: newFormatted || null,\n fieldName,\n });\n }\n }\n }\n }\n\n events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n return events;\n}\n","<template>\n <div\n role=\"alert\"\n :class=\"[\n 'py-3 px-4 w-full rounded-lg border border-base-300 border-l-4 bg-base-200/60',\n variantBorderClass,\n ]\"\n >\n <!-- Mobile-first: stack vertically on small screens, row on desktop -->\n <div\n class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:gap-3\"\n >\n <div class=\"flex items-start gap-3 min-w-0\">\n <component :is=\"iconComponent\" v-if=\"icon\" class=\"shrink-0 w-5 h-5 opacity-90 mt-0.5\" />\n <span class=\"flex-1 min-w-0\">\n <slot />\n </span>\n </div>\n <div\n v-if=\"hasActions\"\n class=\"grid grid-cols-2 gap-2 sm:flex sm:flex-row sm:flex-wrap sm:ml-auto sm:shrink-0 sm:[&>*]:w-auto\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, useSlots, h } from 'vue';\n\ntype AlertVariant = 'warning' | 'success' | 'error' | 'info' | 'neutral';\ntype IconType = 'lock' | 'clock' | 'info' | 'archive';\n\ninterface Props {\n variant: AlertVariant;\n icon?: IconType;\n}\n\nconst props = defineProps<Props>();\n\nconst slots = useSlots();\n\nconst variantBorderClass = computed(() => {\n const map: Record<AlertVariant, string> = {\n warning: 'border-l-warning',\n success: 'border-l-success',\n error: 'border-l-error',\n info: 'border-l-info',\n neutral: 'border-l-base-content/30',\n };\n return map[props.variant];\n});\n\nconst hasActions = computed(() => {\n const actionsSlot = slots.actions;\n if (!actionsSlot) return false;\n const vnodes = actionsSlot();\n return !!vnodes?.length;\n});\n\nconst iconComponent = computed(() => {\n if (!props.icon) return null;\n const icons = {\n lock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z',\n }),\n ],\n ),\n clock: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z',\n }),\n ],\n ),\n info: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z',\n }),\n ],\n ),\n archive: () =>\n h(\n 'svg',\n {\n xmlns: 'http://www.w3.org/2000/svg',\n fill: 'none',\n viewBox: '0 0 24 24',\n 'stroke-width': '1.5',\n stroke: 'currentColor',\n class: 'w-5 h-5',\n },\n [\n h('path', {\n 'stroke-linecap': 'round',\n 'stroke-linejoin': 'round',\n d: 'M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z',\n }),\n ],\n ),\n };\n return icons[props.icon] ?? null;\n});\n</script>\n","<template>\n <div class=\"flex flex-col\">\n <span class=\"text-xs font-semibold uppercase tracking-wide text-base-content/50 mb-0.5\">\n {{ label }}\n </span>\n <template v-if=\"hasContent\">\n <span\n v-if=\"copyable\"\n ref=\"valueRef\"\n role=\"button\"\n tabindex=\"0\"\n class=\"font-mono cursor-pointer select-all\"\n @click=\"handleCopy\"\n @keydown.enter=\"handleCopy\"\n @keydown.space.prevent=\"handleCopy\"\n >\n {{ copied ? 'Copied!' : undefined }}\n <template v-if=\"!copied\"><slot /></template>\n </span>\n <span v-else>\n <slot />\n </span>\n </template>\n <template v-else>\n <slot name=\"empty\">\n <span class=\"text-base-content/50 italic text-sm\">Not set</span>\n </slot>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { Comment } from 'vue';\nimport { ref, computed, useSlots } from 'vue';\n\ninterface Props {\n label: string;\n copyable?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n copyable: false,\n});\n\nconst slots = useSlots();\nconst valueRef = ref<HTMLSpanElement | null>(null);\nconst copied = ref(false);\nlet copyTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\nconst hasContent = computed(() => {\n const defaultSlot = slots.default;\n if (!defaultSlot) return false;\n const vnodes = defaultSlot();\n if (!vnodes || !Array.isArray(vnodes)) return false;\n return vnodes.some((v) => v.type !== Comment);\n});\n\nasync function handleCopy() {\n if (!props.copyable) return;\n const text = valueRef.value?.textContent?.trim();\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n copied.value = true;\n if (copyTimeoutId) clearTimeout(copyTimeoutId);\n copyTimeoutId = setTimeout(() => {\n copied.value = false;\n copyTimeoutId = null;\n }, 1500);\n } catch {\n // ignore clipboard errors\n }\n}\n</script>\n","import { withMetadata } from '@dragonmastery/zinia-forms-core';\nimport { z } from 'zod';\n\n/** Schema for adding a comment/note on support ticket timeline. */\nconst TimelineNoteCreateSchema = z.object({\n body: z.string().min(1, 'Comment is required').trim(),\n is_internal: z.boolean().optional().default(false),\n});\n\nexport const timelineNoteCreateMetadata = withMetadata(\n TimelineNoteCreateSchema,\n 'timelineNoteCreateForm',\n {\n body: {\n label: 'Comment',\n placeholder: 'Add a comment...',\n inputType: 'textarea',\n },\n is_internal: {\n label: 'Internal Note',\n helpText: 'Internal notes are not visible to the customer',\n },\n },\n);\n\nexport type TimelineNoteCreateDto = z.infer<typeof TimelineNoteCreateSchema>;\n","<template>\n <div class=\"border-t border-base-200 pt-4 mt-4 w-full\">\n <template v-if=\"disabled\">\n <div class=\"bg-base-200/50 rounded-lg p-4 text-center\">\n <span class=\"text-base-content/50 text-sm inline-flex items-center gap-1.5\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"1.5\"\n stroke=\"currentColor\"\n class=\"w-4 h-4\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n d=\"M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z\"\n />\n </svg>\n This ticket has been locked. You can no longer add comments.\n </span>\n </div>\n </template>\n <ZiniaForm\n v-else\n @handle-submit=\"handleSubmit\"\n @success=\"handleSuccess\"\n @error=\"handleError\"\n title=\"\"\n subtitle=\"\"\n >\n <div ref=\"formWrapperRef\" class=\"grid grid-cols-1 gap-4 w-full\" @keydown=\"handleKeydown\">\n <p\n v-if=\"showTypeToggle\"\n class=\"col-span-full text-xs mb-1\"\n :class=\"form.values.is_internal ? 'text-warning' : 'text-info'\"\n >\n {{\n form.values.is_internal\n ? '🔒 Internal — not visible to customer'\n : 'Visible to customer'\n }}\n </p>\n <div class=\"col-span-full\">\n <zinia.BodyField class=\"textarea w-full\" />\n </div>\n <div class=\"col-span-full flex flex-wrap gap-2 justify-between items-center\">\n <div v-if=\"showTypeToggle\" class=\"join\">\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n !form.values.is_internal ? 'btn-info btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', false)\"\n >\n Customer Note\n </button>\n <button\n type=\"button\"\n :class=\"[\n 'btn btn-sm join-item',\n form.values.is_internal ? 'btn-warning btn-active' : '',\n ]\"\n :disabled=\"form.isSubmitting\"\n @click=\"form.setValue('is_internal', true)\"\n >\n Internal Note\n </button>\n </div>\n <div v-else></div>\n <ZiniaSubmitButton submitText=\"Comment\" submittingText=\"Adding...\" />\n </div>\n </div>\n </ZiniaForm>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useForm } from '@dragonmastery/zinia-forms-core';\nimport { ref, watch } from 'vue';\nimport { timelineNoteCreateMetadata } from './timelineNoteFormMetadata';\n\ninterface Props {\n showTypeToggle: boolean;\n disabled: boolean;\n /** When provided, noteType is controlled (e.g. synced with URL query param) */\n noteType?: 'customer' | 'internal';\n /** Called when form submits with validated data. Must return a Promise. */\n onSubmit: (payload: { content: string; noteType: 'customer' | 'internal' }) => Promise<void>;\n}\n\nconst props = defineProps<Props>();\nconst formWrapperRef = ref<HTMLElement | null>(null);\n\nconst emit = defineEmits<{\n 'update:noteType': [value: 'customer' | 'internal'];\n}>();\n\nconst { form, zinia, ZiniaForm, ZiniaSubmitButton, ZiniaFormErrorsSummary, refreshFormData } =\n useForm(timelineNoteCreateMetadata, {\n storeName: 'timeline-note-input',\n persistToLocalStorage: false,\n renderStyle: 'daisy_ui',\n fetchData: async () => ({\n body: '',\n is_internal: props.noteType === 'internal',\n }),\n });\n\n// Sync form's is_internal when controlled noteType prop changes (e.g. from URL)\nwatch(\n () => props.noteType,\n (noteType) => {\n if (noteType !== undefined) {\n form.setValue('is_internal', noteType === 'internal');\n }\n },\n { immediate: true },\n);\n\n// Emit when user toggles note type (for URL sync in StaffTimeline)\nwatch(\n () => form.values.is_internal,\n (isInternal) => {\n if (props.showTypeToggle) {\n emit('update:noteType', isInternal ? 'internal' : 'customer');\n }\n },\n);\n\nfunction handleKeydown(e: KeyboardEvent) {\n if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {\n e.preventDefault();\n const form = formWrapperRef.value?.closest('form');\n form?.requestSubmit();\n }\n}\n\nasync function handleSubmit(formData: { body: string; is_internal: boolean }) {\n await props.onSubmit({\n content: (formData.body ?? '').trim(),\n noteType: props.showTypeToggle && formData.is_internal ? 'internal' : 'customer',\n });\n}\n\nfunction handleSuccess() {\n refreshFormData();\n (document.activeElement as HTMLElement)?.blur();\n}\n\nfunction handleError(_error: Error | unknown) {\n // Form displays errors via ZiniaFormErrorsSummary\n}\n\nfunction reset() {\n refreshFormData();\n}\n\ndefineExpose({ reset });\n</script>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;EA2CA,MAAM,mBAAmB,IAAI,EAAE;EAU/B,MAAM,OAAO;EAEb,MAAM,sBAAsB,IAAI,MAAM;;UAtDzB,QAAA,YAAA,WAAA,EAAX,mBAmCM,OAnCN,cAmCM,CAlCJ,mBAiCM,OAjCN,cAiCM;mBAhCJ,mBAAuD,SAAA;KAAhD,MAAK;kEAAoB,oBAAmB,QAAA;qCAAnB,oBAAA,MAAmB,CAAA,CAAA;IACnD,mBAkBM,OAlBN,cAkBM,CAjBJ,mBAgBM,OAhBN,cAgBM,CAAA,OAAA,OAAA,OAAA,KAfJ,mBAaM,OAAA;KAZJ,OAAM;KACN,OAAM;KACN,MAAK;KACL,SAAQ;KACR,QAAO;QAEP,mBAKE,QAAA;KAJA,kBAAe;KACf,mBAAgB;KAChB,gBAAa;KACb,GAAE;eAGN,mBAAiD,QAAA,MAA3C,kBAAa,gBAAG,iBAAA,MAAgB,GAAG,KAAC,EAAA,CAAA,CAAA,CAAA,CAAA;IAG9C,mBAWM,OAXN,cAWM,CAVJ,mBASM,OATN,cASM,CARJ,YAOE,2BAAA;KANC,aAAW,QAAA;KACX,cAAY,QAAA,YAAQ,CAAK,QAAA;KACzB,cAAY,QAAA,YAAQ,CAAK,QAAA;KACzB,6BAAwB,OAAA,OAAA,OAAA,MAAA,WAAE,iBAAA,QAAmB;KAC7C,YAAQ,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,WAAA;KACd,WAAO,OAAA,OAAA,OAAA,MAAA,WAAE,KAAI,UAAA;;;;;;;;;;;;;;ACf1B,MAAM,cAAc,IAAI,IAAI;CAAC;CAAc;CAAc;CAAM;CAAa,CAAC;;AAG7E,MAAM,iBAAiB,IAAI,IAAI;CAC7B;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,SAAS,OAAe,YAAoB,IAAY;AAC/D,KAAI,MAAM,UAAU,UAAW,QAAO;AACtC,QAAO,MAAM,UAAU,GAAG,UAAU,GAAG;;AAGzC,SAAS,gBAAgB,OAAuB;AAC9C,QAAO,MACJ,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,aAAa,CAAC,CACzE,KAAK,IAAI;;AAGd,SAAS,iBACP,WACA,OACA,eAAwB,OACxB,YACQ;AACR,KAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,KAAI,OAAO,UAAU,YAAY,qBAAqB,KAAK,MAAM,CAC/D,QAAO,iBAAiB,MAAM,CAAC;AAEjC,KAAI,OAAO,UAAU,UAAW,QAAO,QAAQ,QAAQ;AAEvD,KAAI,OAAO,UAAU,YAAY,eAAe,IAAI,UAAU,IAAI,WAChE,QAAO,WAAW,IAAI,MAAM,IAAI;AAGlC,KAAI,cAAc,YAAY;AAC5B,MAAI,OAAO,UAAU,SACnB,QAAO,gBAAgB,8BAA8B,MAAM,CAAC;AAE9D,MAAI,OAAO,UAAU,SAAU,QAAO,gBAAgB,MAAM;;AAE9D,KAAI,OAAO,UAAU,UAAU;AAC7B,MACE,UAAU,SAAS,SAAS,IAC5B,UAAU,SAAS,OAAO,IAC1B,UAAU,SAAS,YAAY,CAE/B,QAAO,gBAAgB,MAAM;AAG/B,MAAI,iBAAiB,cAAc,WAAW,cAAc,eAC1D,QAAO,SAAS,MAAM;;AAG1B,QAAO,OAAO,MAAM;;AAGtB,SAAS,sBAAsB,WAAmB,UAAmB,UAA2B;AAC9F,SAAQ,WAAR;EACE,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK,QACH,QAAO;EACT,KAAK,cACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,WACH,QAAO;EACT,KAAK,kBACH,QAAO;EACT,KAAK,gBACH,QAAO;EACT,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK;AACH,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,OAAI,aAAa,QAAQ,aAAa,OAAW,QAAO;AACxD,UAAO;EACT,KAAK;AACH,OACE,aAAa,QACZ,aAAa,UAAa,aAAa,QAAQ,aAAa,OAE7D,QAAO;AAET,UAAO;EACT,KAAK;AACH,OACE,aAAa,QACZ,aAAa,UAAa,aAAa,QAAQ,aAAa,OAE7D,QAAO;AAET,OACE,aAAa,QACb,aAAa,WACZ,aAAa,QAAQ,aAAa,QAEnC,QAAO;AAET,UAAO;EACT,KAAK,kBACH,QAAO;EACT,KAAK,iBACH,QAAO;EACT,KAAK,mBACH,QAAO;EACT,KAAK,qBACH,QAAO;EACT,QACE,QAAO,WAAW,UAAU,QAAQ,MAAM,IAAI;;;AAIpD,SAAS,YAAY,YAAuE;AAC1F,KAAI,CAAC,WAAY,QAAO;AACxB,KAAI;AACF,SAAO,KAAK,MAAM,WAAW;SACvB;AACN,SAAO;;;AAIX,SAAgB,oBACd,UACA,YACe;CACf,MAAMA,SAAwB,EAAE;AAEhC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,SAAS,QAAQ,iBAAiB;EACxC,MAAM,YAAY,QAAQ;AAE1B,MAAI,QAAQ,cAAc,UAAU;AAClC,UAAO,KAAK;IACV,IAAI,GAAG,QAAQ,GAAG;IAClB;IACA;IACA,SAAS;IACV,CAAC;AACF;;AAGF,MAAI,QAAQ,cAAc,UAAU;GAClC,MAAM,YAAY,YAAY,QAAQ,WAAW;GACjD,MAAM,YAAY,YAAY,QAAQ,OAAO;AAE7C,OAAI,CAAC,aAAa,CAAC,UAAW;AAE9B,QAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,UAAU,EAAE;AAC7D,QAAI,YAAY,IAAI,UAAU,CAAE;IAEhC,MAAM,WAAW,UAAU;AAE3B,QAAI,aAAa,UAAU;KACzB,MAAM,eACJ,aAAa,QAAQ,aAAa,SAC9B,iBAAiB,WAAW,UAAU,MAAM,WAAW,GACvD;KACN,MAAM,eACJ,aAAa,QAAQ,aAAa,SAC9B,iBAAiB,WAAW,UAAU,MAAM,WAAW,GACvD;AAEN,YAAO,KAAK;MACV,IAAI,GAAG,QAAQ,GAAG,GAAG;MACrB;MACA;MACA,SAAS,sBAAsB,WAAW,UAAU,SAAS;MAC7D,UAAU,gBAAgB;MAC1B,UAAU,gBAAgB;MAC1B;MACD,CAAC;;;;;AAMV,QAAO,MAAM,GAAG,MAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC;AACxF,QAAO;;;;;;;;;;;;;;;;;;;EC9KT,MAAM,QAAQ;EAEd,MAAM,QAAQ,UAAU;EAExB,MAAM,qBAAqB,eAAe;AAQxC,UAP0C;IACxC,SAAS;IACT,SAAS;IACT,OAAO;IACP,MAAM;IACN,SAAS;IACV,CACU,MAAM;IACjB;EAEF,MAAM,aAAa,eAAe;GAChC,MAAM,cAAc,MAAM;AAC1B,OAAI,CAAC,YAAa,QAAO;AAEzB,UAAO,CAAC,CADO,aAAa,EACX;IACjB;EAEF,MAAM,gBAAgB,eAAe;AACnC,OAAI,CAAC,MAAM,KAAM,QAAO;AA+ExB,UA9Ec;IACZ,YACE,EACE,OACA;KACE,OAAO;KACP,MAAM;KACN,SAAS;KACT,gBAAgB;KAChB,QAAQ;KACR,OAAO;KACR,EACD,CACE,EAAE,QAAQ;KACR,kBAAkB;KAClB,mBAAmB;KACnB,GAAG;KACJ,CAAC,CACH,CACF;IACH,aACE,EACE,OACA;KACE,OAAO;KACP,MAAM;KACN,SAAS;KACT,gBAAgB;KAChB,QAAQ;KACR,OAAO;KACR,EACD,CACE,EAAE,QAAQ;KACR,kBAAkB;KAClB,mBAAmB;KACnB,GAAG;KACJ,CAAC,CACH,CACF;IACH,YACE,EACE,OACA;KACE,OAAO;KACP,MAAM;KACN,SAAS;KACT,gBAAgB;KAChB,QAAQ;KACR,OAAO;KACR,EACD,CACE,EAAE,QAAQ;KACR,kBAAkB;KAClB,mBAAmB;KACnB,GAAG;KACJ,CAAC,CACH,CACF;IACH,eACE,EACE,OACA;KACE,OAAO;KACP,MAAM;KACN,SAAS;KACT,gBAAgB;KAChB,QAAQ;KACR,OAAO;KACR,EACD,CACE,EAAE,QAAQ;KACR,kBAAkB;KAClB,mBAAmB;KACnB,GAAG;KACJ,CAAC,CACH,CACF;IACJ,CACY,MAAM,SAAS;IAC5B;;uBA7IA,mBAwBM,OAAA;IAvBJ,MAAK;IACJ,OAAK,eAAA,CAAA,gFAAgG,mBAAA,MAAA,CAAA;OAKtG,mBAAA,oEAAwE,EACxE,mBAeM,OAfN,cAeM,CAZJ,mBAKM,OALN,cAKM,CAJiC,QAAA,QAAA,WAAA,EAArC,YAAwF,wBAAxE,cAAA,MAAa,EAAA;;IAAc,OAAM;2CACjD,mBAEO,QAFP,cAEO,CADL,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,CAAA,CAAA,EAIJ,WAAA,SAAA,WAAA,EADR,mBAKM,OALN,cAKM,CADJ,WAAuB,KAAA,QAAA,UAAA,CAAA,CAAA,IAAA,mBAAA,QAAA,KAAA,CAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;ECkB/B,MAAM,QAAQ;EAId,MAAM,QAAQ,UAAU;EACxB,MAAM,WAAW,IAA4B,KAAK;EAClD,MAAM,SAAS,IAAI,MAAM;EACzB,IAAIE,gBAAsD;EAE1D,MAAM,aAAa,eAAe;GAChC,MAAM,cAAc,MAAM;AAC1B,OAAI,CAAC,YAAa,QAAO;GACzB,MAAM,SAAS,aAAa;AAC5B,OAAI,CAAC,UAAU,CAAC,MAAM,QAAQ,OAAO,CAAE,QAAO;AAC9C,UAAO,OAAO,MAAM,MAAM,EAAE,SAAS,QAAQ;IAC7C;EAEF,eAAe,aAAa;AAC1B,OAAI,CAAC,MAAM,SAAU;GACrB,MAAM,OAAO,SAAS,OAAO,aAAa,MAAM;AAChD,OAAI,CAAC,KAAM;AACX,OAAI;AACF,UAAM,UAAU,UAAU,UAAU,KAAK;AACzC,WAAO,QAAQ;AACf,QAAI,cAAe,cAAa,cAAc;AAC9C,oBAAgB,iBAAiB;AAC/B,YAAO,QAAQ;AACf,qBAAgB;OACf,KAAK;WACF;;;uBApER,mBA2BM,OA3BN,cA2BM,CA1BJ,mBAEO,QAFP,cAEO,gBADF,QAAA,MAAK,EAAA,EAAA,EAEM,WAAA,SAAA,WAAA,EAAhB,mBAiBW,UAAA,EAAA,KAAA,GAAA,EAAA,CAfD,QAAA,YAAA,WAAA,EADR,mBAYO,QAAA;;aAVD;IAAJ,KAAI;IACJ,MAAK;IACL,UAAS;IACT,OAAM;IACL,SAAO;IACP,WAAO,CAAA,SAAQ,YAAU,CAAA,QAAA,CAAA,EAAA,SAAA,cACF,YAAU,CAAA,UAAA,CAAA,EAAA,CAAA,QAAA,CAAA,CAAA;uCAE/B,OAAA,QAAM,YAAe,OAAS,GAAG,KACpC,EAAA,EAAA,CAAiB,OAAA,QAAQ,WAAQ,KAAA,QAAA,WAAA,EAAA,KAAA,GAAA,CAAA,GAAA,mBAAA,QAAA,KAAA,CAAA,EAAA,IAAA,aAAA,KAAA,WAAA,EAEnC,mBAEO,QAAA,cAAA,CADL,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA,EAAA,SAIV,WAEO,KAAA,QAAA,SAAA,EAAA,KAAA,GAAA,QAAA,CAAA,OAAA,OAAA,OAAA,KADL,mBAAgE,QAAA,EAA1D,OAAM,uCAAqC,EAAC,WAAO,GAAA,EAAA,CAAA,CAAA,CAAA;;;;;;;;;ACrBjE,MAAM,2BAA2B,EAAE,OAAO;CACxC,MAAM,EAAE,QAAQ,CAAC,IAAI,GAAG,sBAAsB,CAAC,MAAM;CACrD,aAAa,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,MAAM;CACnD,CAAC;AAEF,MAAa,6BAA6B,aACxC,0BACA,0BACA;CACE,MAAM;EACJ,OAAO;EACP,aAAa;EACb,WAAW;EACZ;CACD,aAAa;EACX,OAAO;EACP,UAAU;EACX;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECsED,MAAM,QAAQ;EACd,MAAM,iBAAiB,IAAwB,KAAK;EAEpD,MAAM,OAAO;EAIb,MAAM,EAAE,MAAM,OAAO,WAAW,mBAAmB,wBAAwB,oBACzE,QAAQ,4BAA4B;GAClC,WAAW;GACX,uBAAuB;GACvB,aAAa;GACb,WAAW,aAAa;IACtB,MAAM;IACN,aAAa,MAAM,aAAa;IACjC;GACF,CAAC;AAGJ,cACQ,MAAM,WACX,aAAa;AACZ,OAAI,aAAa,OACf,MAAK,SAAS,eAAe,aAAa,WAAW;KAGzD,EAAE,WAAW,MAAM,CACpB;AAGD,cACQ,KAAK,OAAO,cACjB,eAAe;AACd,OAAI,MAAM,eACR,MAAK,mBAAmB,aAAa,aAAa,WAAW;IAGlE;EAED,SAAS,cAAc,GAAkB;AACvC,QAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,SAAS;AACjD,MAAE,gBAAgB;AAElB,KADa,eAAe,OAAO,QAAQ,OAAO,GAC5C,eAAe;;;EAIzB,eAAe,aAAa,UAAkD;AAC5E,SAAM,MAAM,SAAS;IACnB,UAAU,SAAS,QAAQ,IAAI,MAAM;IACrC,UAAU,MAAM,kBAAkB,SAAS,cAAc,aAAa;IACvE,CAAC;;EAGJ,SAAS,gBAAgB;AACvB,oBAAiB;AAChB,YAAS,eAA+B,MAAM;;EAGjD,SAAS,YAAY,QAAyB;EAI9C,SAAS,QAAQ;AACf,oBAAiB;;AAGnB,WAAa,EAAE,OAAO,CAAC;;uBA/JrB,mBA2EM,OA3EN,YA2EM,CA1EY,QAAA,YAAA,WAAA,EACd,mBAkBM,OAlBN,YAkBM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAjBJ,mBAgBO,QAAA,EAhBD,OAAM,iEAA+D,EAAA,CACzE,mBAaM,OAAA;IAZJ,OAAM;IACN,MAAK;IACL,SAAQ;IACR,gBAAa;IACb,QAAO;IACP,OAAM;OAEN,mBAIE,QAAA;IAHA,kBAAe;IACf,mBAAgB;IAChB,GAAE;yBAEA,iEAER,CAAA,2BAGJ,YAoDY,MAAA,UAAA,EAAA;;IAlDT,gBAAe;IACf,WAAS;IACT,SAAO;IACR,OAAM;IACN,UAAS;;2BA6CH,CA3CN,mBA2CM,OAAA;cA3CG;KAAJ,KAAI;KAAiB,OAAM;KAAiC,WAAS;;KAEhE,QAAA,kBAAA,WAAA,EADR,mBAUI,KAAA;;MARF,OAAK,eAAA,CAAC,8BACE,MAAA,KAAI,CAAC,OAAO,cAAW,iBAAA,YAAA,CAAA;wBAG7B,MAAA,KAAI,CAAC,OAAO,cAAA,0CAAA,sBAAA;KAKhB,mBAEM,OAFN,YAEM,CADJ,YAA2C,MAAA,MAAA,CAAA,WAAA,EAA1B,OAAM,mBAAiB,CAAA,CAAA,CAAA;KAE1C,mBA2BM,OA3BN,YA2BM,CA1BO,QAAA,kBAAA,WAAA,EAAX,mBAuBM,OAvBN,YAuBM,CAtBJ,mBAUS,UAAA;MATP,MAAK;MACJ,OAAK,eAAA,CAAA,wBAAA,CAA6D,MAAA,KAAI,CAAC,OAAO,cAAW,wBAAA,GAAA,CAAA;MAIzF,UAAU,MAAA,KAAI,CAAC;MACf,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,KAAI,CAAC,SAAQ,eAAA,MAAA;QACtB,mBAED,IAAA,WAAA,EACA,mBAUS,UAAA;MATP,MAAK;MACJ,OAAK,eAAA,CAAA,wBAA4D,MAAA,KAAI,CAAC,OAAO,cAAW,2BAAA,GAAA,CAAA;MAIxF,UAAU,MAAA,KAAI,CAAC;MACf,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,MAAA,KAAI,CAAC,SAAQ,eAAA,KAAA;QACtB,mBAED,IAAA,WAAA,CAAA,CAAA,KAAA,WAAA,EAEF,mBAAkB,OAAA,WAAA,GAClB,YAAqE,MAAA,kBAAA,EAAA;MAAlD,YAAW;MAAU,gBAAe"}