@servicetitan/anvil2 2.8.0 → 2.9.1

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 (243) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/{AiMark-Cwc9KoyE.js → AiMark-DR-w6Nbm.js} +4 -4
  3. package/dist/{AiMark-Cwc9KoyE.js.map → AiMark-DR-w6Nbm.js.map} +1 -1
  4. package/dist/AiMark.js +1 -1
  5. package/dist/{Alert-5qhkSUN3.js → Alert-Dj61Bq8h.js} +3 -3
  6. package/dist/{Alert-5qhkSUN3.js.map → Alert-Dj61Bq8h.js.map} +1 -1
  7. package/dist/Alert.js +1 -1
  8. package/dist/{Announcement-fQmFNysn.js → Announcement-B9zm-_1S.js} +2 -2
  9. package/dist/{Announcement-fQmFNysn.js.map → Announcement-B9zm-_1S.js.map} +1 -1
  10. package/dist/Announcement.js +1 -1
  11. package/dist/{AnvilProvider-ClfmLl_6.js → AnvilProvider-DUPYyMc7.js} +2 -2
  12. package/dist/{AnvilProvider-ClfmLl_6.js.map → AnvilProvider-DUPYyMc7.js.map} +1 -1
  13. package/dist/AnvilProvider.js +1 -1
  14. package/dist/{Breadcrumbs-BXo2FO2n.js → Breadcrumbs-ojgYVZwe.js} +2 -2
  15. package/dist/{Breadcrumbs-BXo2FO2n.js.map → Breadcrumbs-ojgYVZwe.js.map} +1 -1
  16. package/dist/Breadcrumbs.js +1 -1
  17. package/dist/Button-BdrrhBTI.js +2185 -0
  18. package/dist/Button-BdrrhBTI.js.map +1 -0
  19. package/dist/Button.js +1 -1
  20. package/dist/{ButtonToggle-CmY77gUp.js → ButtonToggle-DaFQ3DBG.js} +2 -2
  21. package/dist/{ButtonToggle-CmY77gUp.js.map → ButtonToggle-DaFQ3DBG.js.map} +1 -1
  22. package/dist/ButtonToggle.js +1 -1
  23. package/dist/{Calendar-d2owsYe9.js → Calendar-Cka4unyi.js} +2 -2
  24. package/dist/{Calendar-d2owsYe9.js.map → Calendar-Cka4unyi.js.map} +1 -1
  25. package/dist/{Calendar-Bd_WELZC.js → Calendar-Dxl9QnfP.js} +3 -3
  26. package/dist/{Calendar-Bd_WELZC.js.map → Calendar-Dxl9QnfP.js.map} +1 -1
  27. package/dist/Calendar.js +2 -2
  28. package/dist/{Checkbox-BlFc6ZWy.js → Checkbox-B-XTVPbX.js} +3 -3
  29. package/dist/{Checkbox-BlFc6ZWy.js.map → Checkbox-B-XTVPbX.js.map} +1 -1
  30. package/dist/{Checkbox-DbaZrUE2.js → Checkbox-Cw1-KFvq.js} +2 -2
  31. package/dist/{Checkbox-DbaZrUE2.js.map → Checkbox-Cw1-KFvq.js.map} +1 -1
  32. package/dist/Checkbox.js +1 -1
  33. package/dist/{Chip-BnofwIUN.js → Chip-Ce0WGKAc.js} +2 -2
  34. package/dist/{Chip-BnofwIUN.js.map → Chip-Ce0WGKAc.js.map} +1 -1
  35. package/dist/Chip.js +1 -1
  36. package/dist/{Combobox-BOxAzG9v.js → Combobox-CNQUROyr.js} +4 -4
  37. package/dist/{Combobox-BOxAzG9v.js.map → Combobox-CNQUROyr.js.map} +1 -1
  38. package/dist/Combobox.js +1 -1
  39. package/dist/{DataTable-DK9xRjnq.js → DataTable-JRxu2yTP.js} +862 -497
  40. package/dist/DataTable-JRxu2yTP.js.map +1 -0
  41. package/dist/DataTable.css +185 -109
  42. package/dist/{DateFieldRange-5Jrz6dLl.js → DateFieldRange-D2hnF50O.js} +4 -4
  43. package/dist/{DateFieldRange-5Jrz6dLl.js.map → DateFieldRange-D2hnF50O.js.map} +1 -1
  44. package/dist/DateFieldRange.js +1 -1
  45. package/dist/{DateFieldSingle-DWFr6Ew4.js → DateFieldSingle-BuaB7RDr.js} +4 -4
  46. package/dist/{DateFieldSingle-DWFr6Ew4.js.map → DateFieldSingle-BuaB7RDr.js.map} +1 -1
  47. package/dist/DateFieldSingle.js +1 -1
  48. package/dist/{DateFieldYearless-UU22A5-E.js → DateFieldYearless-DLeMEutt.js} +4 -4
  49. package/dist/{DateFieldYearless-UU22A5-E.js.map → DateFieldYearless-DLeMEutt.js.map} +1 -1
  50. package/dist/DateFieldYearless.js +1 -1
  51. package/dist/{DateFieldYearlessRange-BoPLxm6t.js → DateFieldYearlessRange-BfPuYKKC.js} +3 -3
  52. package/dist/{DateFieldYearlessRange-BoPLxm6t.js.map → DateFieldYearlessRange-BfPuYKKC.js.map} +1 -1
  53. package/dist/DateFieldYearlessRange.js +1 -1
  54. package/dist/{DaysOfTheWeek-4cfTmjzm.js → DaysOfTheWeek-BW1T8sTU.js} +3 -3
  55. package/dist/{DaysOfTheWeek-4cfTmjzm.js.map → DaysOfTheWeek-BW1T8sTU.js.map} +1 -1
  56. package/dist/DaysOfTheWeek.js +1 -1
  57. package/dist/{Dialog-Dn836WQM.js → Dialog-Cewu2pd_.js} +38 -10
  58. package/dist/Dialog-Cewu2pd_.js.map +1 -0
  59. package/dist/Dialog.js +1 -1
  60. package/dist/{DialogCancelButton-B-jfihJr.js → DialogCancelButton-Czz4Wpse.js} +2 -2
  61. package/dist/{DialogCancelButton-B-jfihJr.js.map → DialogCancelButton-Czz4Wpse.js.map} +1 -1
  62. package/dist/{Drawer-CdDWt_Ba.js → Drawer-Cb5asXWf.js} +38 -10
  63. package/dist/Drawer-Cb5asXWf.js.map +1 -0
  64. package/dist/Drawer.js +1 -1
  65. package/dist/DrillDown.js +1 -1
  66. package/dist/DrillDown.module-C8VOhzaF.js.map +1 -1
  67. package/dist/{EditCard-CZibhEfS.js → EditCard-DlJE3LXN.js} +3 -3
  68. package/dist/{EditCard-CZibhEfS.js.map → EditCard-DlJE3LXN.js.map} +1 -1
  69. package/dist/EditCard.js +1 -1
  70. package/dist/{FieldLabel-Dr41PRxH.js → FieldLabel-HO2VP-4B.js} +2 -2
  71. package/dist/{FieldLabel-Dr41PRxH.js.map → FieldLabel-HO2VP-4B.js.map} +1 -1
  72. package/dist/FieldLabel.js +1 -1
  73. package/dist/{InputMask-CcXqzqdx.js → InputMask-CLLTehFI.js} +3 -3
  74. package/dist/{InputMask-CcXqzqdx.js.map → InputMask-CLLTehFI.js.map} +1 -1
  75. package/dist/InputMask.js +1 -1
  76. package/dist/{ListView-D9cZUVer.js → ListView-CPi-qG2w.js} +2 -2
  77. package/dist/{ListView-D9cZUVer.js.map → ListView-CPi-qG2w.js.map} +1 -1
  78. package/dist/ListView.js +1 -1
  79. package/dist/{Listbox-CgDwzRfz.js → Listbox-Bp4hqIpH.js} +2 -2
  80. package/dist/{Listbox-CgDwzRfz.js.map → Listbox-Bp4hqIpH.js.map} +1 -1
  81. package/dist/Listbox.js +1 -1
  82. package/dist/{Menu-CPbuIsqC.js → Menu-CCavGohP.js} +91 -93
  83. package/dist/Menu-CCavGohP.js.map +1 -0
  84. package/dist/Menu.js +1 -1
  85. package/dist/MultiSelectField.js +1 -1
  86. package/dist/{MultiSelectFieldSync-Ei7DXzvs.js → MultiSelectFieldSync-ChZCW4M9.js} +7 -7
  87. package/dist/{MultiSelectFieldSync-Ei7DXzvs.js.map → MultiSelectFieldSync-ChZCW4M9.js.map} +1 -1
  88. package/dist/MultiSelectMenu.js +1 -1
  89. package/dist/{MultiSelectMenuSync-B_mXpTEe.js → MultiSelectMenuSync-7C1wW4oO.js} +3 -3
  90. package/dist/{MultiSelectMenuSync-B_mXpTEe.js.map → MultiSelectMenuSync-7C1wW4oO.js.map} +1 -1
  91. package/dist/{NumberField-C5t47Obp.js → NumberField-CZSTHBeO.js} +4 -4
  92. package/dist/{NumberField-C5t47Obp.js.map → NumberField-CZSTHBeO.js.map} +1 -1
  93. package/dist/NumberField.js +1 -1
  94. package/dist/{Page-2hbQxUj6.js → Page-BHdvTlfE.js} +111 -62
  95. package/dist/Page-BHdvTlfE.js.map +1 -0
  96. package/dist/Page.css +76 -76
  97. package/dist/Page.js +1 -1
  98. package/dist/{Pagination-CjGmJ_rU.js → Pagination-B5jqHYG3.js} +7 -7
  99. package/dist/{Pagination-CjGmJ_rU.js.map → Pagination-B5jqHYG3.js.map} +1 -1
  100. package/dist/Pagination.css +7 -6
  101. package/dist/Pagination.js +1 -1
  102. package/dist/{Popover-CpU9VAcb.js → Popover-BbqTZw-1.js} +3 -3
  103. package/dist/{Popover-CpU9VAcb.js.map → Popover-BbqTZw-1.js.map} +1 -1
  104. package/dist/Popover.js +1 -1
  105. package/dist/{ProgressBar-FMuK8viJ.js → ProgressBar-CZcxkdX6.js} +2 -2
  106. package/dist/{ProgressBar-FMuK8viJ.js.map → ProgressBar-CZcxkdX6.js.map} +1 -1
  107. package/dist/ProgressBar.js +1 -1
  108. package/dist/{Radio-DmtVWAmN.js → Radio-BFr8AdHc.js} +2 -2
  109. package/dist/{Radio-DmtVWAmN.js.map → Radio-BFr8AdHc.js.map} +1 -1
  110. package/dist/{Radio-CZZd8phn.js → Radio-DJZVMCv0.js} +3 -3
  111. package/dist/{Radio-CZZd8phn.js.map → Radio-DJZVMCv0.js.map} +1 -1
  112. package/dist/Radio.js +1 -1
  113. package/dist/{SelectCard-8OmIDl1m.js → SelectCard-DVcWJRbX.js} +3 -3
  114. package/dist/{SelectCard-8OmIDl1m.js.map → SelectCard-DVcWJRbX.js.map} +1 -1
  115. package/dist/SelectCard.js +1 -1
  116. package/dist/SelectField.js +1 -1
  117. package/dist/{SelectFieldLabel-C8PrXxDU.js → SelectFieldLabel-kEBS8L4l.js} +2 -2
  118. package/dist/{SelectFieldLabel-C8PrXxDU.js.map → SelectFieldLabel-kEBS8L4l.js.map} +1 -1
  119. package/dist/{SelectFieldSync-DGK8F2G9.js → SelectFieldSync-o1Cp9UYC.js} +6 -6
  120. package/dist/{SelectFieldSync-DGK8F2G9.js.map → SelectFieldSync-o1Cp9UYC.js.map} +1 -1
  121. package/dist/SelectMenu.js +1 -1
  122. package/dist/{SelectMenuSync-CuZp9mnt.js → SelectMenuSync-DXrwecFt.js} +3 -3
  123. package/dist/{SelectMenuSync-CuZp9mnt.js.map → SelectMenuSync-DXrwecFt.js.map} +1 -1
  124. package/dist/{SelectOptions-CmElsiTd.js → SelectOptions-Dy2OWqxn.js} +2 -2
  125. package/dist/{SelectOptions-CmElsiTd.js.map → SelectOptions-Dy2OWqxn.js.map} +1 -1
  126. package/dist/{SelectTrigger-KF8w6Ynk.js → SelectTrigger-DhKYzEAr.js} +2 -2
  127. package/dist/{SelectTrigger-KF8w6Ynk.js.map → SelectTrigger-DhKYzEAr.js.map} +1 -1
  128. package/dist/SelectTrigger.js +1 -1
  129. package/dist/{SelectTriggerBase-Bxmv6oXk.js → SelectTriggerBase-Ni8WqeUx.js} +76 -63
  130. package/dist/SelectTriggerBase-Ni8WqeUx.js.map +1 -0
  131. package/dist/SelectTriggerBase.css +83 -66
  132. package/dist/SelectTriggerBase.module-CKoq6qzX.js +38 -0
  133. package/dist/SelectTriggerBase.module-CKoq6qzX.js.map +1 -0
  134. package/dist/{Stepper-_27Lmm2K.js → Stepper-Dt2xAXth.js} +2 -2
  135. package/dist/{Stepper-_27Lmm2K.js.map → Stepper-Dt2xAXth.js.map} +1 -1
  136. package/dist/Stepper.js +1 -1
  137. package/dist/{Switch-DPGz7wC_.js → Switch-C84MBChG.js} +2 -2
  138. package/dist/{Switch-DPGz7wC_.js.map → Switch-C84MBChG.js.map} +1 -1
  139. package/dist/Switch.js +1 -1
  140. package/dist/Table.js +1 -1
  141. package/dist/{Text-MVxRo6yx.js → Text-WiS8UZkY.js} +2 -2
  142. package/dist/{Text-MVxRo6yx.js.map → Text-WiS8UZkY.js.map} +1 -1
  143. package/dist/Text.js +1 -1
  144. package/dist/{TextField-BpSxZa0z.js → TextField-Bul_uln5.js} +3 -3
  145. package/dist/{TextField-BpSxZa0z.js.map → TextField-Bul_uln5.js.map} +1 -1
  146. package/dist/{TextField-D93iv_pk.js → TextField-OznkTx4e.js} +2 -2
  147. package/dist/{TextField-D93iv_pk.js.map → TextField-OznkTx4e.js.map} +1 -1
  148. package/dist/TextField.js +1 -1
  149. package/dist/{Textarea-1u2fSMTh.js → Textarea-CCYLsJ1x.js} +3 -3
  150. package/dist/{Textarea-1u2fSMTh.js.map → Textarea-CCYLsJ1x.js.map} +1 -1
  151. package/dist/Textarea.js +1 -1
  152. package/dist/{TimeField-B4gLlBQJ.js → TimeField-BPvPbD8H.js} +4 -4
  153. package/dist/{TimeField-B4gLlBQJ.js.map → TimeField-BPvPbD8H.js.map} +1 -1
  154. package/dist/TimeField.js +1 -1
  155. package/dist/Toast.js +2 -2
  156. package/dist/{Toaster-DbWYnF_t.js → Toaster-CIaIvwH6.js} +2 -2
  157. package/dist/{Toaster-DbWYnF_t.js.map → Toaster-CIaIvwH6.js.map} +1 -1
  158. package/dist/{Toaster-CSJfSOHx.js → Toaster-DYJm06Vb.js} +4 -4
  159. package/dist/{Toaster-CSJfSOHx.js.map → Toaster-DYJm06Vb.js.map} +1 -1
  160. package/dist/{Toolbar-CWRk523l.js → Toolbar-ByyI7SqG.js} +14 -14
  161. package/dist/{Toolbar-CWRk523l.js.map → Toolbar-ByyI7SqG.js.map} +1 -1
  162. package/dist/Toolbar.js +1 -1
  163. package/dist/{YearlessDateInputWithPicker-BSl5z2zo.js → YearlessDateInputWithPicker-C_twiQW5.js} +2 -2
  164. package/dist/{YearlessDateInputWithPicker-BSl5z2zo.js.map → YearlessDateInputWithPicker-C_twiQW5.js.map} +1 -1
  165. package/dist/assets/icons/st/unsorted.svg +1 -0
  166. package/dist/assets/icons/st.ts +1 -0
  167. package/dist/beta/components/Table/DataTable/DataTable.d.ts +28 -3
  168. package/dist/beta/components/Table/DataTable/internal/DataTableBody.d.ts +19 -4
  169. package/dist/beta/components/Table/DataTable/internal/DataTableBodyRow.d.ts +18 -1
  170. package/dist/beta/components/Table/DataTable/internal/DataTableFooter.d.ts +5 -5
  171. package/dist/beta/components/Table/DataTable/internal/DataTableHeader.d.ts +4 -2
  172. package/dist/beta/components/Table/DataTable/internal/cells/DataTableBodyCell.d.ts +0 -2
  173. package/dist/beta/components/Table/DataTable/internal/cells/DataTableBodyImmutableCell.d.ts +0 -5
  174. package/dist/beta/components/Table/DataTable/internal/cells/DataTableBodyMutableCell.d.ts +0 -5
  175. package/dist/beta/components/Table/DataTable/internal/cells/DataTableHeaderCell.d.ts +4 -4
  176. package/dist/beta/components/Table/DataTable/internal/cells/useCellFocusListener.d.ts +10 -0
  177. package/dist/beta/components/Table/DataTable/internal/context/focus/DTFocusProvider.d.ts +4 -1
  178. package/dist/beta/components/Table/DataTable/internal/editable-cells/DataTableEditableMultiselectAsyncCell.d.ts +0 -1
  179. package/dist/beta/components/Table/DataTable/internal/editable-cells/DataTableEditableMultiselectCell.d.ts +0 -1
  180. package/dist/beta/components/Table/DataTable/internal/editable-cells/types.d.ts +0 -4
  181. package/dist/beta/components/Table/DataTable/internal/editable-cells/useEditableMenuCell.d.ts +3 -6
  182. package/dist/beta/components/Table/DataTable/internal/useDataTableVirtualizer.d.ts +29 -0
  183. package/dist/beta/components/Table/DataTable/internal/util/getTanStackColumnDef.d.ts +13 -2
  184. package/dist/beta/components/Table/DataTable/internal/util/shallowSortingEqual.d.ts +2 -0
  185. package/dist/beta/components/Table/DataTable/stories/DataTable.story-data.d.ts +1 -0
  186. package/dist/beta/components/Table/base/cells/TableHeaderCell.d.ts +4 -0
  187. package/dist/beta/components/Table/createColumnHelper.d.ts +36 -12
  188. package/dist/beta/components/Table/formatters/htmlFormatter.d.ts +13 -0
  189. package/dist/beta/components/Table/formatters/htmlToMarkdown.d.ts +11 -0
  190. package/dist/beta/components/Table/formatters/index.d.ts +2 -0
  191. package/dist/beta/components/Table/formatters/markdownFormatter.d.ts +11 -0
  192. package/dist/beta/components/Table/types.d.ts +64 -10
  193. package/dist/beta.js +9 -9
  194. package/dist/components/DrillDown/internal/DrillDownContext.d.ts +4 -0
  195. package/dist/components/DrillDown/internal/useDrillDownContextState.d.ts +4 -0
  196. package/dist/index.js +43 -44
  197. package/dist/index.js.map +1 -1
  198. package/dist/internal/flubber/a2c.d.ts +16 -0
  199. package/dist/internal/flubber/add.d.ts +3 -0
  200. package/dist/internal/flubber/arc.d.ts +26 -0
  201. package/dist/internal/flubber/bezier.d.ts +32 -0
  202. package/dist/internal/flubber/errors.d.ts +5 -0
  203. package/dist/internal/flubber/index.d.ts +6 -0
  204. package/dist/internal/flubber/interpolate.d.ts +7 -0
  205. package/dist/internal/flubber/linear.d.ts +27 -0
  206. package/dist/internal/flubber/math.d.ts +10 -0
  207. package/dist/internal/flubber/normalize.d.ts +4 -0
  208. package/dist/internal/flubber/parse.d.ts +7 -0
  209. package/dist/internal/flubber/path-properties.d.ts +23 -0
  210. package/dist/internal/flubber/rotate.d.ts +2 -0
  211. package/dist/internal/flubber/svg.d.ts +9 -0
  212. package/dist/internal/index.d.ts +1 -0
  213. package/dist/{stripInlineMarkdown-DyqLAQnf.js → stripInlineMarkdown-Cg1qlNwL.js} +2 -2
  214. package/dist/{stripInlineMarkdown-DyqLAQnf.js.map → stripInlineMarkdown-Cg1qlNwL.js.map} +1 -1
  215. package/dist/{syncFilterUtils-CsbCnI1-.js → syncFilterUtils-UR5Vgqkh.js} +7 -8
  216. package/dist/{syncFilterUtils-CsbCnI1-.js.map → syncFilterUtils-UR5Vgqkh.js.map} +1 -1
  217. package/dist/{useDrilldown-C7eMBl68.js → useDrilldown-D6VZNSCX.js} +46 -20
  218. package/dist/{useDrilldown-C7eMBl68.js.map → useDrilldown-D6VZNSCX.js.map} +1 -1
  219. package/dist/{useInitialFocus-DbaB-x5T.js → useInitialFocus-BUxEDMEG.js} +65 -23
  220. package/dist/useInitialFocus-BUxEDMEG.js.map +1 -0
  221. package/dist/{usePopoverTransitionStates-B1opfxxn.js → usePopoverTransitionStates-CDXCdyKa.js} +2 -1
  222. package/dist/{usePopoverTransitionStates-B1opfxxn.js.map → usePopoverTransitionStates-CDXCdyKa.js.map} +1 -1
  223. package/dist/{useToggleSelection-BM8asdFj.js → useToggleSelection-BBdrIVWs.js} +2 -2
  224. package/dist/{useToggleSelection-BM8asdFj.js.map → useToggleSelection-BBdrIVWs.js.map} +1 -1
  225. package/package.json +1 -3
  226. package/dist/Button-a_D7tUgM.js +0 -4517
  227. package/dist/Button-a_D7tUgM.js.map +0 -1
  228. package/dist/DataTable-DK9xRjnq.js.map +0 -1
  229. package/dist/Dialog-Dn836WQM.js.map +0 -1
  230. package/dist/Drawer-CdDWt_Ba.js.map +0 -1
  231. package/dist/Menu-CPbuIsqC.js.map +0 -1
  232. package/dist/Page-2hbQxUj6.js.map +0 -1
  233. package/dist/SelectTriggerBase-Bxmv6oXk.js.map +0 -1
  234. package/dist/SelectTriggerBase.module-B0NFRlQP.js +0 -36
  235. package/dist/SelectTriggerBase.module-B0NFRlQP.js.map +0 -1
  236. package/dist/beta/components/Table/DataTable/internal/cells/CellFocusContext.d.ts +0 -16
  237. package/dist/beta/components/Table/DataTable/internal/context/hover/DTHoverContext.d.ts +0 -31
  238. package/dist/beta/components/Table/DataTable/internal/context/hover/DTHoverProvider.d.ts +0 -3
  239. package/dist/beta/components/Table/DataTable/internal/context/hover/useDTHoverDispatchContext.d.ts +0 -1
  240. package/dist/beta/components/Table/DataTable/internal/context/hover/useDTHoverStateContext.d.ts +0 -4
  241. package/dist/beta/components/Table/internal/getColSpanWidth.d.ts +0 -7
  242. package/dist/useInitialFocus-DbaB-x5T.js.map +0 -1
  243. /package/dist/{anvil-fonts.css → AnvilProvider.css} +0 -0
@@ -1,4517 +0,0 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import { useContext, useState, useEffect, useMemo, memo, forwardRef, useCallback } from 'react';
4
- import { I as Icon } from './Icon-DuIlne4x.js';
5
- import { S as Spinner } from './Spinner-BqmcE2pb.js';
6
- import { w as warnOnce } from './warnOnce-Y9PRHcU4.js';
7
- import { g as getDefaultExportFromCjs, c as cx } from './index-De1g9FRV.js';
8
- import { u as usePrefersReducedMotion } from './usePrefersReducedMotion-DR9B_D6w.js';
9
- import { u as useTheme } from './useTheme-B4i6a3bM.js';
10
- import { d as isEasingArray, e as interpolate$1, u as useConstant, f as motionValue, M as MotionConfigContext, c as useIsomorphicLayoutEffect, g as frame, j as cancelFrame, k as collectMotionValues, r as resolveElements, l as mixNumber, n as removeItem, o as isMotionValue, q as defaultOffset, s as createGeneratorEasing, t as fillOffset, v as isGenerator, x as secondsToMilliseconds, y as invariant, z as progress, V as VisualElement, A as createBox, B as isSVGElement, C as isSVGSVGElement, S as SVGVisualElement, H as HTMLVisualElement, D as visualElementStore, E as animateSingleValue, F as animateTarget, G as spring, m as motion } from './proxy-DEehATlA.js';
11
- import { s as styles } from './Button.module-wCtFYGVD.js';
12
- import { u as useLayoutPropsUtil } from './useLayoutPropsUtil-DMDdfIah.js';
13
- import { c as childrenToString } from './childrenToString-Bz9MqbHb.js';
14
- import { useTrackingId } from './useTrackingId.js';
15
-
16
- const wrap = (min, max, v) => {
17
- const rangeSize = max - min;
18
- return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
19
- };
20
-
21
- function getEasingForSegment(easing, i) {
22
- return isEasingArray(easing) ? easing[wrap(0, easing.length, i)] : easing;
23
- }
24
-
25
- class GroupAnimation {
26
- constructor(animations) {
27
- // Bound to accomadate common `return animation.stop` pattern
28
- this.stop = () => this.runAll("stop");
29
- this.animations = animations.filter(Boolean);
30
- }
31
- get finished() {
32
- return Promise.all(this.animations.map((animation) => animation.finished));
33
- }
34
- /**
35
- * TODO: Filter out cancelled or stopped animations before returning
36
- */
37
- getAll(propName) {
38
- return this.animations[0][propName];
39
- }
40
- setAll(propName, newValue) {
41
- for (let i = 0; i < this.animations.length; i++) {
42
- this.animations[i][propName] = newValue;
43
- }
44
- }
45
- attachTimeline(timeline) {
46
- const subscriptions = this.animations.map((animation) => animation.attachTimeline(timeline));
47
- return () => {
48
- subscriptions.forEach((cancel, i) => {
49
- cancel && cancel();
50
- this.animations[i].stop();
51
- });
52
- };
53
- }
54
- get time() {
55
- return this.getAll("time");
56
- }
57
- set time(time) {
58
- this.setAll("time", time);
59
- }
60
- get speed() {
61
- return this.getAll("speed");
62
- }
63
- set speed(speed) {
64
- this.setAll("speed", speed);
65
- }
66
- get state() {
67
- return this.getAll("state");
68
- }
69
- get startTime() {
70
- return this.getAll("startTime");
71
- }
72
- get duration() {
73
- let max = 0;
74
- for (let i = 0; i < this.animations.length; i++) {
75
- max = Math.max(max, this.animations[i].duration);
76
- }
77
- return max;
78
- }
79
- runAll(methodName) {
80
- this.animations.forEach((controls) => controls[methodName]());
81
- }
82
- play() {
83
- this.runAll("play");
84
- }
85
- pause() {
86
- this.runAll("pause");
87
- }
88
- cancel() {
89
- this.runAll("cancel");
90
- }
91
- complete() {
92
- this.runAll("complete");
93
- }
94
- }
95
-
96
- class GroupAnimationWithThen extends GroupAnimation {
97
- then(onResolve, _onReject) {
98
- return this.finished.finally(onResolve).then(() => { });
99
- }
100
- }
101
-
102
- function transform(...args) {
103
- const useImmediate = !Array.isArray(args[0]);
104
- const argOffset = useImmediate ? 0 : -1;
105
- const inputValue = args[0 + argOffset];
106
- const inputRange = args[1 + argOffset];
107
- const outputRange = args[2 + argOffset];
108
- const options = args[3 + argOffset];
109
- const interpolator = interpolate$1(inputRange, outputRange, options);
110
- return useImmediate ? interpolator(inputValue) : interpolator;
111
- }
112
-
113
- /**
114
- * Creates a `MotionValue` to track the state and velocity of a value.
115
- *
116
- * Usually, these are created automatically. For advanced use-cases, like use with `useTransform`, you can create `MotionValue`s externally and pass them into the animated component via the `style` prop.
117
- *
118
- * ```jsx
119
- * export const MyComponent = () => {
120
- * const scale = useMotionValue(1)
121
- *
122
- * return <motion.div style={{ scale }} />
123
- * }
124
- * ```
125
- *
126
- * @param initial - The initial state.
127
- *
128
- * @public
129
- */
130
- function useMotionValue(initial) {
131
- const value = useConstant(() => motionValue(initial));
132
- /**
133
- * If this motion value is being used in static mode, like on
134
- * the Framer canvas, force components to rerender when the motion
135
- * value is updated.
136
- */
137
- const { isStatic } = useContext(MotionConfigContext);
138
- if (isStatic) {
139
- const [, setLatest] = useState(initial);
140
- useEffect(() => value.on("change", setLatest), []);
141
- }
142
- return value;
143
- }
144
-
145
- function useCombineMotionValues(values, combineValues) {
146
- /**
147
- * Initialise the returned motion value. This remains the same between renders.
148
- */
149
- const value = useMotionValue(combineValues());
150
- /**
151
- * Create a function that will update the template motion value with the latest values.
152
- * This is pre-bound so whenever a motion value updates it can schedule its
153
- * execution in Framesync. If it's already been scheduled it won't be fired twice
154
- * in a single frame.
155
- */
156
- const updateValue = () => value.set(combineValues());
157
- /**
158
- * Synchronously update the motion value with the latest values during the render.
159
- * This ensures that within a React render, the styles applied to the DOM are up-to-date.
160
- */
161
- updateValue();
162
- /**
163
- * Subscribe to all motion values found within the template. Whenever any of them change,
164
- * schedule an update.
165
- */
166
- useIsomorphicLayoutEffect(() => {
167
- const scheduleUpdate = () => frame.preRender(updateValue, false, true);
168
- const subscriptions = values.map((v) => v.on("change", scheduleUpdate));
169
- return () => {
170
- subscriptions.forEach((unsubscribe) => unsubscribe());
171
- cancelFrame(updateValue);
172
- };
173
- });
174
- return value;
175
- }
176
-
177
- function useComputed(compute) {
178
- /**
179
- * Open session of collectMotionValues. Any MotionValue that calls get()
180
- * will be saved into this array.
181
- */
182
- collectMotionValues.current = [];
183
- compute();
184
- const value = useCombineMotionValues(collectMotionValues.current, compute);
185
- /**
186
- * Synchronously close session of collectMotionValues.
187
- */
188
- collectMotionValues.current = undefined;
189
- return value;
190
- }
191
-
192
- function useTransform(input, inputRangeOrTransformer, outputRange, options) {
193
- if (typeof input === "function") {
194
- return useComputed(input);
195
- }
196
- const transformer = typeof inputRangeOrTransformer === "function"
197
- ? inputRangeOrTransformer
198
- : transform(inputRangeOrTransformer, outputRange, options);
199
- return Array.isArray(input)
200
- ? useListTransform(input, transformer)
201
- : useListTransform([input], ([latest]) => transformer(latest));
202
- }
203
- function useListTransform(values, transformer) {
204
- const latest = useConstant(() => []);
205
- return useCombineMotionValues(values, () => {
206
- latest.length = 0;
207
- const numValues = values.length;
208
- for (let i = 0; i < numValues; i++) {
209
- latest[i] = values[i].get();
210
- }
211
- return transformer(latest);
212
- });
213
- }
214
-
215
- function isDOMKeyframes(keyframes) {
216
- return typeof keyframes === "object" && !Array.isArray(keyframes);
217
- }
218
-
219
- function resolveSubjects(subject, keyframes, scope, selectorCache) {
220
- if (typeof subject === "string" && isDOMKeyframes(keyframes)) {
221
- return resolveElements(subject, scope, selectorCache);
222
- }
223
- else if (subject instanceof NodeList) {
224
- return Array.from(subject);
225
- }
226
- else if (Array.isArray(subject)) {
227
- return subject;
228
- }
229
- else {
230
- return [subject];
231
- }
232
- }
233
-
234
- function calculateRepeatDuration(duration, repeat, _repeatDelay) {
235
- return duration * (repeat + 1);
236
- }
237
-
238
- /**
239
- * Given a absolute or relative time definition and current/prev time state of the sequence,
240
- * calculate an absolute time for the next keyframes.
241
- */
242
- function calcNextTime(current, next, prev, labels) {
243
- if (typeof next === "number") {
244
- return next;
245
- }
246
- else if (next.startsWith("-") || next.startsWith("+")) {
247
- return Math.max(0, current + parseFloat(next));
248
- }
249
- else if (next === "<") {
250
- return prev;
251
- }
252
- else if (next.startsWith("<")) {
253
- return Math.max(0, prev + parseFloat(next.slice(1)));
254
- }
255
- else {
256
- return labels.get(next) ?? current;
257
- }
258
- }
259
-
260
- function eraseKeyframes(sequence, startTime, endTime) {
261
- for (let i = 0; i < sequence.length; i++) {
262
- const keyframe = sequence[i];
263
- if (keyframe.at > startTime && keyframe.at < endTime) {
264
- removeItem(sequence, keyframe);
265
- // If we remove this item we have to push the pointer back one
266
- i--;
267
- }
268
- }
269
- }
270
- function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
271
- /**
272
- * Erase every existing value between currentTime and targetTime,
273
- * this will essentially splice this timeline into any currently
274
- * defined ones.
275
- */
276
- eraseKeyframes(sequence, startTime, endTime);
277
- for (let i = 0; i < keyframes.length; i++) {
278
- sequence.push({
279
- value: keyframes[i],
280
- at: mixNumber(startTime, endTime, offset[i]),
281
- easing: getEasingForSegment(easing, i),
282
- });
283
- }
284
- }
285
-
286
- /**
287
- * Take an array of times that represent repeated keyframes. For instance
288
- * if we have original times of [0, 0.5, 1] then our repeated times will
289
- * be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back
290
- * down to a 0-1 scale.
291
- */
292
- function normalizeTimes(times, repeat) {
293
- for (let i = 0; i < times.length; i++) {
294
- times[i] = times[i] / (repeat + 1);
295
- }
296
- }
297
-
298
- function compareByTime(a, b) {
299
- if (a.at === b.at) {
300
- if (a.value === null)
301
- return 1;
302
- if (b.value === null)
303
- return -1;
304
- return 0;
305
- }
306
- else {
307
- return a.at - b.at;
308
- }
309
- }
310
-
311
- const defaultSegmentEasing = "easeInOut";
312
- const MAX_REPEAT = 20;
313
- function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators) {
314
- const defaultDuration = defaultTransition.duration || 0.3;
315
- const animationDefinitions = new Map();
316
- const sequences = new Map();
317
- const elementCache = {};
318
- const timeLabels = new Map();
319
- let prevTime = 0;
320
- let currentTime = 0;
321
- let totalDuration = 0;
322
- /**
323
- * Build the timeline by mapping over the sequence array and converting
324
- * the definitions into keyframes and offsets with absolute time values.
325
- * These will later get converted into relative offsets in a second pass.
326
- */
327
- for (let i = 0; i < sequence.length; i++) {
328
- const segment = sequence[i];
329
- /**
330
- * If this is a timeline label, mark it and skip the rest of this iteration.
331
- */
332
- if (typeof segment === "string") {
333
- timeLabels.set(segment, currentTime);
334
- continue;
335
- }
336
- else if (!Array.isArray(segment)) {
337
- timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
338
- continue;
339
- }
340
- let [subject, keyframes, transition = {}] = segment;
341
- /**
342
- * If a relative or absolute time value has been specified we need to resolve
343
- * it in relation to the currentTime.
344
- */
345
- if (transition.at !== undefined) {
346
- currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
347
- }
348
- /**
349
- * Keep track of the maximum duration in this definition. This will be
350
- * applied to currentTime once the definition has been parsed.
351
- */
352
- let maxDuration = 0;
353
- const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
354
- const valueKeyframesAsList = keyframesAsList(valueKeyframes);
355
- const { delay = 0, times = defaultOffset(valueKeyframesAsList), type = "keyframes", repeat, repeatType, repeatDelay = 0, ...remainingTransition } = valueTransition;
356
- let { ease = defaultTransition.ease || "easeOut", duration } = valueTransition;
357
- /**
358
- * Resolve stagger() if defined.
359
- */
360
- const calculatedDelay = typeof delay === "function"
361
- ? delay(elementIndex, numSubjects)
362
- : delay;
363
- /**
364
- * If this animation should and can use a spring, generate a spring easing function.
365
- */
366
- const numKeyframes = valueKeyframesAsList.length;
367
- const createGenerator = isGenerator(type)
368
- ? type
369
- : generators?.[type || "keyframes"];
370
- if (numKeyframes <= 2 && createGenerator) {
371
- /**
372
- * As we're creating an easing function from a spring,
373
- * ideally we want to generate it using the real distance
374
- * between the two keyframes. However this isn't always
375
- * possible - in these situations we use 0-100.
376
- */
377
- let absoluteDelta = 100;
378
- if (numKeyframes === 2 &&
379
- isNumberKeyframesArray(valueKeyframesAsList)) {
380
- const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
381
- absoluteDelta = Math.abs(delta);
382
- }
383
- const springTransition = { ...remainingTransition };
384
- if (duration !== undefined) {
385
- springTransition.duration = secondsToMilliseconds(duration);
386
- }
387
- const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
388
- ease = springEasing.ease;
389
- duration = springEasing.duration;
390
- }
391
- duration ?? (duration = defaultDuration);
392
- const startTime = currentTime + calculatedDelay;
393
- /**
394
- * If there's only one time offset of 0, fill in a second with length 1
395
- */
396
- if (times.length === 1 && times[0] === 0) {
397
- times[1] = 1;
398
- }
399
- /**
400
- * Fill out if offset if fewer offsets than keyframes
401
- */
402
- const remainder = times.length - valueKeyframesAsList.length;
403
- remainder > 0 && fillOffset(times, remainder);
404
- /**
405
- * If only one value has been set, ie [1], push a null to the start of
406
- * the keyframe array. This will let us mark a keyframe at this point
407
- * that will later be hydrated with the previous value.
408
- */
409
- valueKeyframesAsList.length === 1 &&
410
- valueKeyframesAsList.unshift(null);
411
- /**
412
- * Handle repeat options
413
- */
414
- if (repeat) {
415
- invariant(repeat < MAX_REPEAT, "Repeat count too high, must be less than 20", "repeat-count-high");
416
- duration = calculateRepeatDuration(duration, repeat);
417
- const originalKeyframes = [...valueKeyframesAsList];
418
- const originalTimes = [...times];
419
- ease = Array.isArray(ease) ? [...ease] : [ease];
420
- const originalEase = [...ease];
421
- for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
422
- valueKeyframesAsList.push(...originalKeyframes);
423
- for (let keyframeIndex = 0; keyframeIndex < originalKeyframes.length; keyframeIndex++) {
424
- times.push(originalTimes[keyframeIndex] + (repeatIndex + 1));
425
- ease.push(keyframeIndex === 0
426
- ? "linear"
427
- : getEasingForSegment(originalEase, keyframeIndex - 1));
428
- }
429
- }
430
- normalizeTimes(times, repeat);
431
- }
432
- const targetTime = startTime + duration;
433
- /**
434
- * Add keyframes, mapping offsets to absolute time.
435
- */
436
- addKeyframes(valueSequence, valueKeyframesAsList, ease, times, startTime, targetTime);
437
- maxDuration = Math.max(calculatedDelay + duration, maxDuration);
438
- totalDuration = Math.max(targetTime, totalDuration);
439
- };
440
- if (isMotionValue(subject)) {
441
- const subjectSequence = getSubjectSequence(subject, sequences);
442
- resolveValueSequence(keyframes, transition, getValueSequence("default", subjectSequence));
443
- }
444
- else {
445
- const subjects = resolveSubjects(subject, keyframes, scope, elementCache);
446
- const numSubjects = subjects.length;
447
- /**
448
- * For every element in this segment, process the defined values.
449
- */
450
- for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
451
- /**
452
- * Cast necessary, but we know these are of this type
453
- */
454
- keyframes = keyframes;
455
- transition = transition;
456
- const thisSubject = subjects[subjectIndex];
457
- const subjectSequence = getSubjectSequence(thisSubject, sequences);
458
- for (const key in keyframes) {
459
- resolveValueSequence(keyframes[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
460
- }
461
- }
462
- }
463
- prevTime = currentTime;
464
- currentTime += maxDuration;
465
- }
466
- /**
467
- * For every element and value combination create a new animation.
468
- */
469
- sequences.forEach((valueSequences, element) => {
470
- for (const key in valueSequences) {
471
- const valueSequence = valueSequences[key];
472
- /**
473
- * Arrange all the keyframes in ascending time order.
474
- */
475
- valueSequence.sort(compareByTime);
476
- const keyframes = [];
477
- const valueOffset = [];
478
- const valueEasing = [];
479
- /**
480
- * For each keyframe, translate absolute times into
481
- * relative offsets based on the total duration of the timeline.
482
- */
483
- for (let i = 0; i < valueSequence.length; i++) {
484
- const { at, value, easing } = valueSequence[i];
485
- keyframes.push(value);
486
- valueOffset.push(progress(0, totalDuration, at));
487
- valueEasing.push(easing || "easeOut");
488
- }
489
- /**
490
- * If the first keyframe doesn't land on offset: 0
491
- * provide one by duplicating the initial keyframe. This ensures
492
- * it snaps to the first keyframe when the animation starts.
493
- */
494
- if (valueOffset[0] !== 0) {
495
- valueOffset.unshift(0);
496
- keyframes.unshift(keyframes[0]);
497
- valueEasing.unshift(defaultSegmentEasing);
498
- }
499
- /**
500
- * If the last keyframe doesn't land on offset: 1
501
- * provide one with a null wildcard value. This will ensure it
502
- * stays static until the end of the animation.
503
- */
504
- if (valueOffset[valueOffset.length - 1] !== 1) {
505
- valueOffset.push(1);
506
- keyframes.push(null);
507
- }
508
- if (!animationDefinitions.has(element)) {
509
- animationDefinitions.set(element, {
510
- keyframes: {},
511
- transition: {},
512
- });
513
- }
514
- const definition = animationDefinitions.get(element);
515
- definition.keyframes[key] = keyframes;
516
- definition.transition[key] = {
517
- ...defaultTransition,
518
- duration: totalDuration,
519
- ease: valueEasing,
520
- times: valueOffset,
521
- ...sequenceTransition,
522
- };
523
- }
524
- });
525
- return animationDefinitions;
526
- }
527
- function getSubjectSequence(subject, sequences) {
528
- !sequences.has(subject) && sequences.set(subject, {});
529
- return sequences.get(subject);
530
- }
531
- function getValueSequence(name, sequences) {
532
- if (!sequences[name])
533
- sequences[name] = [];
534
- return sequences[name];
535
- }
536
- function keyframesAsList(keyframes) {
537
- return Array.isArray(keyframes) ? keyframes : [keyframes];
538
- }
539
- function getValueTransition(transition, key) {
540
- return transition && transition[key]
541
- ? {
542
- ...transition,
543
- ...transition[key],
544
- }
545
- : { ...transition };
546
- }
547
- const isNumber = (keyframe) => typeof keyframe === "number";
548
- const isNumberKeyframesArray = (keyframes) => keyframes.every(isNumber);
549
-
550
- function isObjectKey(key, object) {
551
- return key in object;
552
- }
553
- class ObjectVisualElement extends VisualElement {
554
- constructor() {
555
- super(...arguments);
556
- this.type = "object";
557
- }
558
- readValueFromInstance(instance, key) {
559
- if (isObjectKey(key, instance)) {
560
- const value = instance[key];
561
- if (typeof value === "string" || typeof value === "number") {
562
- return value;
563
- }
564
- }
565
- return undefined;
566
- }
567
- getBaseTargetFromProps() {
568
- return undefined;
569
- }
570
- removeValueFromRenderState(key, renderState) {
571
- delete renderState.output[key];
572
- }
573
- measureInstanceViewportBox() {
574
- return createBox();
575
- }
576
- build(renderState, latestValues) {
577
- Object.assign(renderState.output, latestValues);
578
- }
579
- renderInstance(instance, { output }) {
580
- Object.assign(instance, output);
581
- }
582
- sortInstanceNodePosition() {
583
- return 0;
584
- }
585
- }
586
-
587
- function createDOMVisualElement(element) {
588
- const options = {
589
- presenceContext: null,
590
- props: {},
591
- visualState: {
592
- renderState: {
593
- transform: {},
594
- transformOrigin: {},
595
- style: {},
596
- vars: {},
597
- attrs: {},
598
- },
599
- latestValues: {},
600
- },
601
- };
602
- const node = isSVGElement(element) && !isSVGSVGElement(element)
603
- ? new SVGVisualElement(options)
604
- : new HTMLVisualElement(options);
605
- node.mount(element);
606
- visualElementStore.set(element, node);
607
- }
608
- function createObjectVisualElement(subject) {
609
- const options = {
610
- presenceContext: null,
611
- props: {},
612
- visualState: {
613
- renderState: {
614
- output: {},
615
- },
616
- latestValues: {},
617
- },
618
- };
619
- const node = new ObjectVisualElement(options);
620
- node.mount(subject);
621
- visualElementStore.set(subject, node);
622
- }
623
-
624
- function isSingleValue(subject, keyframes) {
625
- return (isMotionValue(subject) ||
626
- typeof subject === "number" ||
627
- (typeof subject === "string" && !isDOMKeyframes(keyframes)));
628
- }
629
- /**
630
- * Implementation
631
- */
632
- function animateSubject(subject, keyframes, options, scope) {
633
- const animations = [];
634
- if (isSingleValue(subject, keyframes)) {
635
- animations.push(animateSingleValue(subject, isDOMKeyframes(keyframes)
636
- ? keyframes.default || keyframes
637
- : keyframes, options ? options.default || options : options));
638
- }
639
- else {
640
- const subjects = resolveSubjects(subject, keyframes, scope);
641
- const numSubjects = subjects.length;
642
- invariant(Boolean(numSubjects), "No valid elements provided.", "no-valid-elements");
643
- for (let i = 0; i < numSubjects; i++) {
644
- const thisSubject = subjects[i];
645
- invariant(thisSubject !== null, "You're trying to perform an animation on null. Ensure that selectors are correctly finding elements and refs are correctly hydrated.", "animate-null");
646
- const createVisualElement = thisSubject instanceof Element
647
- ? createDOMVisualElement
648
- : createObjectVisualElement;
649
- if (!visualElementStore.has(thisSubject)) {
650
- createVisualElement(thisSubject);
651
- }
652
- const visualElement = visualElementStore.get(thisSubject);
653
- const transition = { ...options };
654
- /**
655
- * Resolve stagger function if provided.
656
- */
657
- if ("delay" in transition &&
658
- typeof transition.delay === "function") {
659
- transition.delay = transition.delay(i, numSubjects);
660
- }
661
- animations.push(...animateTarget(visualElement, { ...keyframes, transition }, {}));
662
- }
663
- }
664
- return animations;
665
- }
666
-
667
- function animateSequence(sequence, options, scope) {
668
- const animations = [];
669
- const animationDefinitions = createAnimationsFromSequence(sequence, options, scope, { spring });
670
- animationDefinitions.forEach(({ keyframes, transition }, subject) => {
671
- animations.push(...animateSubject(subject, keyframes, transition));
672
- });
673
- return animations;
674
- }
675
-
676
- function isSequence(value) {
677
- return Array.isArray(value) && value.some(Array.isArray);
678
- }
679
- /**
680
- * Creates an animation function that is optionally scoped
681
- * to a specific element.
682
- */
683
- function createScopedAnimate(scope) {
684
- /**
685
- * Implementation
686
- */
687
- function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
688
- let animations = [];
689
- if (isSequence(subjectOrSequence)) {
690
- animations = animateSequence(subjectOrSequence, optionsOrKeyframes, scope);
691
- }
692
- else {
693
- animations = animateSubject(subjectOrSequence, optionsOrKeyframes, options, scope);
694
- }
695
- const animation = new GroupAnimationWithThen(animations);
696
- return animation;
697
- }
698
- return scopedAnimate;
699
- }
700
- const animate = createScopedAnimate();
701
-
702
- function polygonArea(polygon) {
703
- var i = -1,
704
- n = polygon.length,
705
- a,
706
- b = polygon[n - 1],
707
- area = 0;
708
-
709
- while (++i < n) {
710
- a = b;
711
- b = polygon[i];
712
- area += a[1] * b[0] - a[0] * b[1];
713
- }
714
-
715
- return area / 2;
716
- }
717
-
718
- function polygonLength(polygon) {
719
- var i = -1,
720
- n = polygon.length,
721
- b = polygon[n - 1],
722
- xa,
723
- ya,
724
- xb = b[0],
725
- yb = b[1],
726
- perimeter = 0;
727
-
728
- while (++i < n) {
729
- xa = xb;
730
- ya = yb;
731
- b = polygon[i];
732
- xb = b[0];
733
- yb = b[1];
734
- xa -= xb;
735
- ya -= yb;
736
- perimeter += Math.sqrt(xa * xa + ya * ya);
737
- }
738
-
739
- return perimeter;
740
- }
741
-
742
- var path_parse;
743
- var hasRequiredPath_parse;
744
-
745
- function requirePath_parse () {
746
- if (hasRequiredPath_parse) return path_parse;
747
- hasRequiredPath_parse = 1;
748
-
749
-
750
- var paramCounts = { a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0 };
751
-
752
- var SPECIAL_SPACES = [
753
- 0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006,
754
- 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF
755
- ];
756
-
757
- function isSpace(ch) {
758
- return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029) || // Line terminators
759
- // White spaces
760
- (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
761
- (ch >= 0x1680 && SPECIAL_SPACES.indexOf(ch) >= 0);
762
- }
763
-
764
- function isCommand(code) {
765
- /*eslint-disable no-bitwise*/
766
- switch (code | 0x20) {
767
- case 0x6D/* m */:
768
- case 0x7A/* z */:
769
- case 0x6C/* l */:
770
- case 0x68/* h */:
771
- case 0x76/* v */:
772
- case 0x63/* c */:
773
- case 0x73/* s */:
774
- case 0x71/* q */:
775
- case 0x74/* t */:
776
- case 0x61/* a */:
777
- case 0x72/* r */:
778
- return true;
779
- }
780
- return false;
781
- }
782
-
783
- function isArc(code) {
784
- return (code | 0x20) === 0x61;
785
- }
786
-
787
- function isDigit(code) {
788
- return (code >= 48 && code <= 57); // 0..9
789
- }
790
-
791
- function isDigitStart(code) {
792
- return (code >= 48 && code <= 57) || /* 0..9 */
793
- code === 0x2B || /* + */
794
- code === 0x2D || /* - */
795
- code === 0x2E; /* . */
796
- }
797
-
798
-
799
- function State(path) {
800
- this.index = 0;
801
- this.path = path;
802
- this.max = path.length;
803
- this.result = [];
804
- this.param = 0.0;
805
- this.err = '';
806
- this.segmentStart = 0;
807
- this.data = [];
808
- }
809
-
810
- function skipSpaces(state) {
811
- while (state.index < state.max && isSpace(state.path.charCodeAt(state.index))) {
812
- state.index++;
813
- }
814
- }
815
-
816
-
817
- function scanFlag(state) {
818
- var ch = state.path.charCodeAt(state.index);
819
-
820
- if (ch === 0x30/* 0 */) {
821
- state.param = 0;
822
- state.index++;
823
- return;
824
- }
825
-
826
- if (ch === 0x31/* 1 */) {
827
- state.param = 1;
828
- state.index++;
829
- return;
830
- }
831
-
832
- state.err = 'SvgPath: arc flag can be 0 or 1 only (at pos ' + state.index + ')';
833
- }
834
-
835
-
836
- function scanParam(state) {
837
- var start = state.index,
838
- index = start,
839
- max = state.max,
840
- zeroFirst = false,
841
- hasCeiling = false,
842
- hasDecimal = false,
843
- hasDot = false,
844
- ch;
845
-
846
- if (index >= max) {
847
- state.err = 'SvgPath: missed param (at pos ' + index + ')';
848
- return;
849
- }
850
- ch = state.path.charCodeAt(index);
851
-
852
- if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
853
- index++;
854
- ch = (index < max) ? state.path.charCodeAt(index) : 0;
855
- }
856
-
857
- // This logic is shamelessly borrowed from Esprima
858
- // https://github.com/ariya/esprimas
859
- //
860
- if (!isDigit(ch) && ch !== 0x2E/* . */) {
861
- state.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')';
862
- return;
863
- }
864
-
865
- if (ch !== 0x2E/* . */) {
866
- zeroFirst = (ch === 0x30/* 0 */);
867
- index++;
868
-
869
- ch = (index < max) ? state.path.charCodeAt(index) : 0;
870
-
871
- if (zeroFirst && index < max) {
872
- // decimal number starts with '0' such as '09' is illegal.
873
- if (ch && isDigit(ch)) {
874
- state.err = 'SvgPath: numbers started with `0` such as `09` are illegal (at pos ' + start + ')';
875
- return;
876
- }
877
- }
878
-
879
- while (index < max && isDigit(state.path.charCodeAt(index))) {
880
- index++;
881
- hasCeiling = true;
882
- }
883
- ch = (index < max) ? state.path.charCodeAt(index) : 0;
884
- }
885
-
886
- if (ch === 0x2E/* . */) {
887
- hasDot = true;
888
- index++;
889
- while (isDigit(state.path.charCodeAt(index))) {
890
- index++;
891
- hasDecimal = true;
892
- }
893
- ch = (index < max) ? state.path.charCodeAt(index) : 0;
894
- }
895
-
896
- if (ch === 0x65/* e */ || ch === 0x45/* E */) {
897
- if (hasDot && !hasCeiling && !hasDecimal) {
898
- state.err = 'SvgPath: invalid float exponent (at pos ' + index + ')';
899
- return;
900
- }
901
-
902
- index++;
903
-
904
- ch = (index < max) ? state.path.charCodeAt(index) : 0;
905
- if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
906
- index++;
907
- }
908
- if (index < max && isDigit(state.path.charCodeAt(index))) {
909
- while (index < max && isDigit(state.path.charCodeAt(index))) {
910
- index++;
911
- }
912
- } else {
913
- state.err = 'SvgPath: invalid float exponent (at pos ' + index + ')';
914
- return;
915
- }
916
- }
917
-
918
- state.index = index;
919
- state.param = parseFloat(state.path.slice(start, index)) + 0.0;
920
- }
921
-
922
-
923
- function finalizeSegment(state) {
924
- var cmd, cmdLC;
925
-
926
- // Process duplicated commands (without comand name)
927
-
928
- // This logic is shamelessly borrowed from Raphael
929
- // https://github.com/DmitryBaranovskiy/raphael/
930
- //
931
- cmd = state.path[state.segmentStart];
932
- cmdLC = cmd.toLowerCase();
933
-
934
- var params = state.data;
935
-
936
- if (cmdLC === 'm' && params.length > 2) {
937
- state.result.push([ cmd, params[0], params[1] ]);
938
- params = params.slice(2);
939
- cmdLC = 'l';
940
- cmd = (cmd === 'm') ? 'l' : 'L';
941
- }
942
-
943
- if (cmdLC === 'r') {
944
- state.result.push([ cmd ].concat(params));
945
- } else {
946
-
947
- while (params.length >= paramCounts[cmdLC]) {
948
- state.result.push([ cmd ].concat(params.splice(0, paramCounts[cmdLC])));
949
- if (!paramCounts[cmdLC]) {
950
- break;
951
- }
952
- }
953
- }
954
- }
955
-
956
-
957
- function scanSegment(state) {
958
- var max = state.max,
959
- cmdCode, is_arc, comma_found, need_params, i;
960
-
961
- state.segmentStart = state.index;
962
- cmdCode = state.path.charCodeAt(state.index);
963
- is_arc = isArc(cmdCode);
964
-
965
- if (!isCommand(cmdCode)) {
966
- state.err = 'SvgPath: bad command ' + state.path[state.index] + ' (at pos ' + state.index + ')';
967
- return;
968
- }
969
-
970
- need_params = paramCounts[state.path[state.index].toLowerCase()];
971
-
972
- state.index++;
973
- skipSpaces(state);
974
-
975
- state.data = [];
976
-
977
- if (!need_params) {
978
- // Z
979
- finalizeSegment(state);
980
- return;
981
- }
982
-
983
- comma_found = false;
984
-
985
- for (;;) {
986
- for (i = need_params; i > 0; i--) {
987
- if (is_arc && (i === 3 || i === 4)) scanFlag(state);
988
- else scanParam(state);
989
-
990
- if (state.err.length) {
991
- finalizeSegment(state);
992
- return;
993
- }
994
- state.data.push(state.param);
995
-
996
- skipSpaces(state);
997
- comma_found = false;
998
-
999
- if (state.index < max && state.path.charCodeAt(state.index) === 0x2C/* , */) {
1000
- state.index++;
1001
- skipSpaces(state);
1002
- comma_found = true;
1003
- }
1004
- }
1005
-
1006
- // after ',' param is mandatory
1007
- if (comma_found) {
1008
- continue;
1009
- }
1010
-
1011
- if (state.index >= state.max) {
1012
- break;
1013
- }
1014
-
1015
- // Stop on next segment
1016
- if (!isDigitStart(state.path.charCodeAt(state.index))) {
1017
- break;
1018
- }
1019
- }
1020
-
1021
- finalizeSegment(state);
1022
- }
1023
-
1024
-
1025
- /* Returns array of segments:
1026
- *
1027
- * [
1028
- * [ command, coord1, coord2, ... ]
1029
- * ]
1030
- */
1031
- path_parse = function pathParse(svgPath) {
1032
- var state = new State(svgPath);
1033
- var max = state.max;
1034
-
1035
- skipSpaces(state);
1036
-
1037
- while (state.index < max && !state.err.length) {
1038
- scanSegment(state);
1039
- }
1040
-
1041
- if (state.result.length) {
1042
- if ('mM'.indexOf(state.result[0][0]) < 0) {
1043
- state.err = 'SvgPath: string should start with `M` or `m`';
1044
- state.result = [];
1045
- } else {
1046
- state.result[0][0] = 'M';
1047
- }
1048
- }
1049
-
1050
- return {
1051
- err: state.err,
1052
- segments: state.result
1053
- };
1054
- };
1055
- return path_parse;
1056
- }
1057
-
1058
- var matrix;
1059
- var hasRequiredMatrix;
1060
-
1061
- function requireMatrix () {
1062
- if (hasRequiredMatrix) return matrix;
1063
- hasRequiredMatrix = 1;
1064
-
1065
- // combine 2 matrixes
1066
- // m1, m2 - [a, b, c, d, e, g]
1067
- //
1068
- function combine(m1, m2) {
1069
- return [
1070
- m1[0] * m2[0] + m1[2] * m2[1],
1071
- m1[1] * m2[0] + m1[3] * m2[1],
1072
- m1[0] * m2[2] + m1[2] * m2[3],
1073
- m1[1] * m2[2] + m1[3] * m2[3],
1074
- m1[0] * m2[4] + m1[2] * m2[5] + m1[4],
1075
- m1[1] * m2[4] + m1[3] * m2[5] + m1[5]
1076
- ];
1077
- }
1078
-
1079
-
1080
- function Matrix() {
1081
- if (!(this instanceof Matrix)) { return new Matrix(); }
1082
- this.queue = []; // list of matrixes to apply
1083
- this.cache = null; // combined matrix cache
1084
- }
1085
-
1086
-
1087
- Matrix.prototype.matrix = function (m) {
1088
- if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1 && m[4] === 0 && m[5] === 0) {
1089
- return this;
1090
- }
1091
- this.cache = null;
1092
- this.queue.push(m);
1093
- return this;
1094
- };
1095
-
1096
-
1097
- Matrix.prototype.translate = function (tx, ty) {
1098
- if (tx !== 0 || ty !== 0) {
1099
- this.cache = null;
1100
- this.queue.push([ 1, 0, 0, 1, tx, ty ]);
1101
- }
1102
- return this;
1103
- };
1104
-
1105
-
1106
- Matrix.prototype.scale = function (sx, sy) {
1107
- if (sx !== 1 || sy !== 1) {
1108
- this.cache = null;
1109
- this.queue.push([ sx, 0, 0, sy, 0, 0 ]);
1110
- }
1111
- return this;
1112
- };
1113
-
1114
-
1115
- Matrix.prototype.rotate = function (angle, rx, ry) {
1116
- var rad, cos, sin;
1117
-
1118
- if (angle !== 0) {
1119
- this.translate(rx, ry);
1120
-
1121
- rad = angle * Math.PI / 180;
1122
- cos = Math.cos(rad);
1123
- sin = Math.sin(rad);
1124
-
1125
- this.queue.push([ cos, sin, -sin, cos, 0, 0 ]);
1126
- this.cache = null;
1127
-
1128
- this.translate(-rx, -ry);
1129
- }
1130
- return this;
1131
- };
1132
-
1133
-
1134
- Matrix.prototype.skewX = function (angle) {
1135
- if (angle !== 0) {
1136
- this.cache = null;
1137
- this.queue.push([ 1, 0, Math.tan(angle * Math.PI / 180), 1, 0, 0 ]);
1138
- }
1139
- return this;
1140
- };
1141
-
1142
-
1143
- Matrix.prototype.skewY = function (angle) {
1144
- if (angle !== 0) {
1145
- this.cache = null;
1146
- this.queue.push([ 1, Math.tan(angle * Math.PI / 180), 0, 1, 0, 0 ]);
1147
- }
1148
- return this;
1149
- };
1150
-
1151
-
1152
- // Flatten queue
1153
- //
1154
- Matrix.prototype.toArray = function () {
1155
- if (this.cache) {
1156
- return this.cache;
1157
- }
1158
-
1159
- if (!this.queue.length) {
1160
- this.cache = [ 1, 0, 0, 1, 0, 0 ];
1161
- return this.cache;
1162
- }
1163
-
1164
- this.cache = this.queue[0];
1165
-
1166
- if (this.queue.length === 1) {
1167
- return this.cache;
1168
- }
1169
-
1170
- for (var i = 1; i < this.queue.length; i++) {
1171
- this.cache = combine(this.cache, this.queue[i]);
1172
- }
1173
-
1174
- return this.cache;
1175
- };
1176
-
1177
-
1178
- // Apply list of matrixes to (x,y) point.
1179
- // If `isRelative` set, `translate` component of matrix will be skipped
1180
- //
1181
- Matrix.prototype.calc = function (x, y, isRelative) {
1182
- var m;
1183
-
1184
- // Don't change point on empty transforms queue
1185
- if (!this.queue.length) { return [ x, y ]; }
1186
-
1187
- // Calculate final matrix, if not exists
1188
- //
1189
- // NB. if you deside to apply transforms to point one-by-one,
1190
- // they should be taken in reverse order
1191
-
1192
- if (!this.cache) {
1193
- this.cache = this.toArray();
1194
- }
1195
-
1196
- m = this.cache;
1197
-
1198
- // Apply matrix to point
1199
- return [
1200
- x * m[0] + y * m[2] + (isRelative ? 0 : m[4]),
1201
- x * m[1] + y * m[3] + (isRelative ? 0 : m[5])
1202
- ];
1203
- };
1204
-
1205
-
1206
- matrix = Matrix;
1207
- return matrix;
1208
- }
1209
-
1210
- var transform_parse;
1211
- var hasRequiredTransform_parse;
1212
-
1213
- function requireTransform_parse () {
1214
- if (hasRequiredTransform_parse) return transform_parse;
1215
- hasRequiredTransform_parse = 1;
1216
-
1217
-
1218
- var Matrix = requireMatrix();
1219
-
1220
- var operations = {
1221
- matrix: true,
1222
- scale: true,
1223
- rotate: true,
1224
- translate: true,
1225
- skewX: true,
1226
- skewY: true
1227
- };
1228
-
1229
- var CMD_SPLIT_RE = /\s*(matrix|translate|scale|rotate|skewX|skewY)\s*\(\s*(.+?)\s*\)[\s,]*/;
1230
- var PARAMS_SPLIT_RE = /[\s,]+/;
1231
-
1232
-
1233
- transform_parse = function transformParse(transformString) {
1234
- var matrix = new Matrix();
1235
- var cmd, params;
1236
-
1237
- // Split value into ['', 'translate', '10 50', '', 'scale', '2', '', 'rotate', '-45', '']
1238
- transformString.split(CMD_SPLIT_RE).forEach(function (item) {
1239
-
1240
- // Skip empty elements
1241
- if (!item.length) { return; }
1242
-
1243
- // remember operation
1244
- if (typeof operations[item] !== 'undefined') {
1245
- cmd = item;
1246
- return;
1247
- }
1248
-
1249
- // extract params & att operation to matrix
1250
- params = item.split(PARAMS_SPLIT_RE).map(function (i) {
1251
- return +i || 0;
1252
- });
1253
-
1254
- // If params count is not correct - ignore command
1255
- switch (cmd) {
1256
- case 'matrix':
1257
- if (params.length === 6) {
1258
- matrix.matrix(params);
1259
- }
1260
- return;
1261
-
1262
- case 'scale':
1263
- if (params.length === 1) {
1264
- matrix.scale(params[0], params[0]);
1265
- } else if (params.length === 2) {
1266
- matrix.scale(params[0], params[1]);
1267
- }
1268
- return;
1269
-
1270
- case 'rotate':
1271
- if (params.length === 1) {
1272
- matrix.rotate(params[0], 0, 0);
1273
- } else if (params.length === 3) {
1274
- matrix.rotate(params[0], params[1], params[2]);
1275
- }
1276
- return;
1277
-
1278
- case 'translate':
1279
- if (params.length === 1) {
1280
- matrix.translate(params[0], 0);
1281
- } else if (params.length === 2) {
1282
- matrix.translate(params[0], params[1]);
1283
- }
1284
- return;
1285
-
1286
- case 'skewX':
1287
- if (params.length === 1) {
1288
- matrix.skewX(params[0]);
1289
- }
1290
- return;
1291
-
1292
- case 'skewY':
1293
- if (params.length === 1) {
1294
- matrix.skewY(params[0]);
1295
- }
1296
- return;
1297
- }
1298
- });
1299
-
1300
- return matrix;
1301
- };
1302
- return transform_parse;
1303
- }
1304
-
1305
- var a2c$1;
1306
- var hasRequiredA2c;
1307
-
1308
- function requireA2c () {
1309
- if (hasRequiredA2c) return a2c$1;
1310
- hasRequiredA2c = 1;
1311
-
1312
-
1313
- var TAU = Math.PI * 2;
1314
-
1315
-
1316
- /* eslint-disable space-infix-ops */
1317
-
1318
- // Calculate an angle between two unit vectors
1319
- //
1320
- // Since we measure angle between radii of circular arcs,
1321
- // we can use simplified math (without length normalization)
1322
- //
1323
- function unit_vector_angle(ux, uy, vx, vy) {
1324
- var sign = (ux * vy - uy * vx < 0) ? -1 : 1;
1325
- var dot = ux * vx + uy * vy;
1326
-
1327
- // Add this to work with arbitrary vectors:
1328
- // dot /= Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
1329
-
1330
- // rounding errors, e.g. -1.0000000000000002 can screw up this
1331
- if (dot > 1.0) { dot = 1.0; }
1332
- if (dot < -1) { dot = -1; }
1333
-
1334
- return sign * Math.acos(dot);
1335
- }
1336
-
1337
-
1338
- // Convert from endpoint to center parameterization,
1339
- // see http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
1340
- //
1341
- // Return [cx, cy, theta1, delta_theta]
1342
- //
1343
- function get_arc_center(x1, y1, x2, y2, fa, fs, rx, ry, sin_phi, cos_phi) {
1344
- // Step 1.
1345
- //
1346
- // Moving an ellipse so origin will be the middlepoint between our two
1347
- // points. After that, rotate it to line up ellipse axes with coordinate
1348
- // axes.
1349
- //
1350
- var x1p = cos_phi*(x1-x2)/2 + sin_phi*(y1-y2)/2;
1351
- var y1p = -sin_phi*(x1-x2)/2 + cos_phi*(y1-y2)/2;
1352
-
1353
- var rx_sq = rx * rx;
1354
- var ry_sq = ry * ry;
1355
- var x1p_sq = x1p * x1p;
1356
- var y1p_sq = y1p * y1p;
1357
-
1358
- // Step 2.
1359
- //
1360
- // Compute coordinates of the centre of this ellipse (cx', cy')
1361
- // in the new coordinate system.
1362
- //
1363
- var radicant = (rx_sq * ry_sq) - (rx_sq * y1p_sq) - (ry_sq * x1p_sq);
1364
-
1365
- if (radicant < 0) {
1366
- // due to rounding errors it might be e.g. -1.3877787807814457e-17
1367
- radicant = 0;
1368
- }
1369
-
1370
- radicant /= (rx_sq * y1p_sq) + (ry_sq * x1p_sq);
1371
- radicant = Math.sqrt(radicant) * (fa === fs ? -1 : 1);
1372
-
1373
- var cxp = radicant * rx/ry * y1p;
1374
- var cyp = radicant * -ry/rx * x1p;
1375
-
1376
- // Step 3.
1377
- //
1378
- // Transform back to get centre coordinates (cx, cy) in the original
1379
- // coordinate system.
1380
- //
1381
- var cx = cos_phi*cxp - sin_phi*cyp + (x1+x2)/2;
1382
- var cy = sin_phi*cxp + cos_phi*cyp + (y1+y2)/2;
1383
-
1384
- // Step 4.
1385
- //
1386
- // Compute angles (theta1, delta_theta).
1387
- //
1388
- var v1x = (x1p - cxp) / rx;
1389
- var v1y = (y1p - cyp) / ry;
1390
- var v2x = (-x1p - cxp) / rx;
1391
- var v2y = (-y1p - cyp) / ry;
1392
-
1393
- var theta1 = unit_vector_angle(1, 0, v1x, v1y);
1394
- var delta_theta = unit_vector_angle(v1x, v1y, v2x, v2y);
1395
-
1396
- if (fs === 0 && delta_theta > 0) {
1397
- delta_theta -= TAU;
1398
- }
1399
- if (fs === 1 && delta_theta < 0) {
1400
- delta_theta += TAU;
1401
- }
1402
-
1403
- return [ cx, cy, theta1, delta_theta ];
1404
- }
1405
-
1406
- //
1407
- // Approximate one unit arc segment with bézier curves,
1408
- // see http://math.stackexchange.com/questions/873224
1409
- //
1410
- function approximate_unit_arc(theta1, delta_theta) {
1411
- var alpha = 4/3 * Math.tan(delta_theta/4);
1412
-
1413
- var x1 = Math.cos(theta1);
1414
- var y1 = Math.sin(theta1);
1415
- var x2 = Math.cos(theta1 + delta_theta);
1416
- var y2 = Math.sin(theta1 + delta_theta);
1417
-
1418
- return [ x1, y1, x1 - y1*alpha, y1 + x1*alpha, x2 + y2*alpha, y2 - x2*alpha, x2, y2 ];
1419
- }
1420
-
1421
- a2c$1 = function a2c(x1, y1, x2, y2, fa, fs, rx, ry, phi) {
1422
- var sin_phi = Math.sin(phi * TAU / 360);
1423
- var cos_phi = Math.cos(phi * TAU / 360);
1424
-
1425
- // Make sure radii are valid
1426
- //
1427
- var x1p = cos_phi*(x1-x2)/2 + sin_phi*(y1-y2)/2;
1428
- var y1p = -sin_phi*(x1-x2)/2 + cos_phi*(y1-y2)/2;
1429
-
1430
- if (x1p === 0 && y1p === 0) {
1431
- // we're asked to draw line to itself
1432
- return [];
1433
- }
1434
-
1435
- if (rx === 0 || ry === 0) {
1436
- // one of the radii is zero
1437
- return [];
1438
- }
1439
-
1440
-
1441
- // Compensate out-of-range radii
1442
- //
1443
- rx = Math.abs(rx);
1444
- ry = Math.abs(ry);
1445
-
1446
- var lambda = (x1p * x1p) / (rx * rx) + (y1p * y1p) / (ry * ry);
1447
- if (lambda > 1) {
1448
- rx *= Math.sqrt(lambda);
1449
- ry *= Math.sqrt(lambda);
1450
- }
1451
-
1452
-
1453
- // Get center parameters (cx, cy, theta1, delta_theta)
1454
- //
1455
- var cc = get_arc_center(x1, y1, x2, y2, fa, fs, rx, ry, sin_phi, cos_phi);
1456
-
1457
- var result = [];
1458
- var theta1 = cc[2];
1459
- var delta_theta = cc[3];
1460
-
1461
- // Split an arc to multiple segments, so each segment
1462
- // will be less than τ/4 (= 90°)
1463
- //
1464
- var segments = Math.max(Math.ceil(Math.abs(delta_theta) / (TAU / 4)), 1);
1465
- delta_theta /= segments;
1466
-
1467
- for (var i = 0; i < segments; i++) {
1468
- result.push(approximate_unit_arc(theta1, delta_theta));
1469
- theta1 += delta_theta;
1470
- }
1471
-
1472
- // We have a bezier approximation of a unit circle,
1473
- // now need to transform back to the original ellipse
1474
- //
1475
- return result.map(function (curve) {
1476
- for (var i = 0; i < curve.length; i += 2) {
1477
- var x = curve[i + 0];
1478
- var y = curve[i + 1];
1479
-
1480
- // scale
1481
- x *= rx;
1482
- y *= ry;
1483
-
1484
- // rotate
1485
- var xp = cos_phi*x - sin_phi*y;
1486
- var yp = sin_phi*x + cos_phi*y;
1487
-
1488
- // translate
1489
- curve[i + 0] = xp + cc[0];
1490
- curve[i + 1] = yp + cc[1];
1491
- }
1492
-
1493
- return curve;
1494
- });
1495
- };
1496
- return a2c$1;
1497
- }
1498
-
1499
- var ellipse;
1500
- var hasRequiredEllipse;
1501
-
1502
- function requireEllipse () {
1503
- if (hasRequiredEllipse) return ellipse;
1504
- hasRequiredEllipse = 1;
1505
-
1506
- /* eslint-disable space-infix-ops */
1507
-
1508
- // The precision used to consider an ellipse as a circle
1509
- //
1510
- var epsilon = 0.0000000001;
1511
-
1512
- // To convert degree in radians
1513
- //
1514
- var torad = Math.PI / 180;
1515
-
1516
- // Class constructor :
1517
- // an ellipse centred at 0 with radii rx,ry and x - axis - angle ax.
1518
- //
1519
- function Ellipse(rx, ry, ax) {
1520
- if (!(this instanceof Ellipse)) { return new Ellipse(rx, ry, ax); }
1521
- this.rx = rx;
1522
- this.ry = ry;
1523
- this.ax = ax;
1524
- }
1525
-
1526
- // Apply a linear transform m to the ellipse
1527
- // m is an array representing a matrix :
1528
- // - -
1529
- // | m[0] m[2] |
1530
- // | m[1] m[3] |
1531
- // - -
1532
- //
1533
- Ellipse.prototype.transform = function (m) {
1534
- // We consider the current ellipse as image of the unit circle
1535
- // by first scale(rx,ry) and then rotate(ax) ...
1536
- // So we apply ma = m x rotate(ax) x scale(rx,ry) to the unit circle.
1537
- var c = Math.cos(this.ax * torad), s = Math.sin(this.ax * torad);
1538
- var ma = [
1539
- this.rx * (m[0]*c + m[2]*s),
1540
- this.rx * (m[1]*c + m[3]*s),
1541
- this.ry * (-m[0]*s + m[2]*c),
1542
- this.ry * (-m[1]*s + m[3]*c)
1543
- ];
1544
-
1545
- // ma * transpose(ma) = [ J L ]
1546
- // [ L K ]
1547
- // L is calculated later (if the image is not a circle)
1548
- var J = ma[0]*ma[0] + ma[2]*ma[2],
1549
- K = ma[1]*ma[1] + ma[3]*ma[3];
1550
-
1551
- // the discriminant of the characteristic polynomial of ma * transpose(ma)
1552
- var D = ((ma[0]-ma[3])*(ma[0]-ma[3]) + (ma[2]+ma[1])*(ma[2]+ma[1])) *
1553
- ((ma[0]+ma[3])*(ma[0]+ma[3]) + (ma[2]-ma[1])*(ma[2]-ma[1]));
1554
-
1555
- // the "mean eigenvalue"
1556
- var JK = (J + K) / 2;
1557
-
1558
- // check if the image is (almost) a circle
1559
- if (D < epsilon * JK) {
1560
- // if it is
1561
- this.rx = this.ry = Math.sqrt(JK);
1562
- this.ax = 0;
1563
- return this;
1564
- }
1565
-
1566
- // if it is not a circle
1567
- var L = ma[0]*ma[1] + ma[2]*ma[3];
1568
-
1569
- D = Math.sqrt(D);
1570
-
1571
- // {l1,l2} = the two eigen values of ma * transpose(ma)
1572
- var l1 = JK + D/2,
1573
- l2 = JK - D/2;
1574
- // the x - axis - rotation angle is the argument of the l1 - eigenvector
1575
- /*eslint-disable indent*/
1576
- this.ax = (Math.abs(L) < epsilon && Math.abs(l1 - K) < epsilon) ?
1577
- 90
1578
- :
1579
- Math.atan(Math.abs(L) > Math.abs(l1 - K) ?
1580
- (l1 - J) / L
1581
- :
1582
- L / (l1 - K)
1583
- ) * 180 / Math.PI;
1584
- /*eslint-enable indent*/
1585
-
1586
- // if ax > 0 => rx = sqrt(l1), ry = sqrt(l2), else exchange axes and ax += 90
1587
- if (this.ax >= 0) {
1588
- // if ax in [0,90]
1589
- this.rx = Math.sqrt(l1);
1590
- this.ry = Math.sqrt(l2);
1591
- } else {
1592
- // if ax in ]-90,0[ => exchange axes
1593
- this.ax += 90;
1594
- this.rx = Math.sqrt(l2);
1595
- this.ry = Math.sqrt(l1);
1596
- }
1597
-
1598
- return this;
1599
- };
1600
-
1601
- // Check if the ellipse is (almost) degenerate, i.e. rx = 0 or ry = 0
1602
- //
1603
- Ellipse.prototype.isDegenerate = function () {
1604
- return (this.rx < epsilon * this.ry || this.ry < epsilon * this.rx);
1605
- };
1606
-
1607
- ellipse = Ellipse;
1608
- return ellipse;
1609
- }
1610
-
1611
- var svgpath$1;
1612
- var hasRequiredSvgpath$1;
1613
-
1614
- function requireSvgpath$1 () {
1615
- if (hasRequiredSvgpath$1) return svgpath$1;
1616
- hasRequiredSvgpath$1 = 1;
1617
-
1618
-
1619
- var pathParse = requirePath_parse();
1620
- var transformParse = requireTransform_parse();
1621
- var matrix = requireMatrix();
1622
- var a2c = requireA2c();
1623
- var ellipse = requireEllipse();
1624
-
1625
-
1626
- // Class constructor
1627
- //
1628
- function SvgPath(path) {
1629
- if (!(this instanceof SvgPath)) { return new SvgPath(path); }
1630
-
1631
- var pstate = pathParse(path);
1632
-
1633
- // Array of path segments.
1634
- // Each segment is array [command, param1, param2, ...]
1635
- this.segments = pstate.segments;
1636
-
1637
- // Error message on parse error.
1638
- this.err = pstate.err;
1639
-
1640
- // Transforms stack for lazy evaluation
1641
- this.__stack = [];
1642
- }
1643
-
1644
- SvgPath.from = function (src) {
1645
- if (typeof src === 'string') return new SvgPath(src);
1646
-
1647
- if (src instanceof SvgPath) {
1648
- // Create empty object
1649
- var s = new SvgPath('');
1650
-
1651
- // Clone properies
1652
- s.err = src.err;
1653
- s.segments = src.segments.map(function (sgm) { return sgm.slice(); });
1654
- s.__stack = src.__stack.map(function (m) {
1655
- return matrix().matrix(m.toArray());
1656
- });
1657
-
1658
- return s;
1659
- }
1660
-
1661
- throw new Error('SvgPath.from: invalid param type ' + src);
1662
- };
1663
-
1664
-
1665
- SvgPath.prototype.__matrix = function (m) {
1666
- var self = this, i;
1667
-
1668
- // Quick leave for empty matrix
1669
- if (!m.queue.length) { return; }
1670
-
1671
- this.iterate(function (s, index, x, y) {
1672
- var p, result, name, isRelative;
1673
-
1674
- switch (s[0]) {
1675
-
1676
- // Process 'assymetric' commands separately
1677
- case 'v':
1678
- p = m.calc(0, s[1], true);
1679
- result = (p[0] === 0) ? [ 'v', p[1] ] : [ 'l', p[0], p[1] ];
1680
- break;
1681
-
1682
- case 'V':
1683
- p = m.calc(x, s[1], false);
1684
- result = (p[0] === m.calc(x, y, false)[0]) ? [ 'V', p[1] ] : [ 'L', p[0], p[1] ];
1685
- break;
1686
-
1687
- case 'h':
1688
- p = m.calc(s[1], 0, true);
1689
- result = (p[1] === 0) ? [ 'h', p[0] ] : [ 'l', p[0], p[1] ];
1690
- break;
1691
-
1692
- case 'H':
1693
- p = m.calc(s[1], y, false);
1694
- result = (p[1] === m.calc(x, y, false)[1]) ? [ 'H', p[0] ] : [ 'L', p[0], p[1] ];
1695
- break;
1696
-
1697
- case 'a':
1698
- case 'A':
1699
- // ARC is: ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
1700
-
1701
- // Drop segment if arc is empty (end point === start point)
1702
- /*if ((s[0] === 'A' && s[6] === x && s[7] === y) ||
1703
- (s[0] === 'a' && s[6] === 0 && s[7] === 0)) {
1704
- return [];
1705
- }*/
1706
-
1707
- // Transform rx, ry and the x-axis-rotation
1708
- var ma = m.toArray();
1709
- var e = ellipse(s[1], s[2], s[3]).transform(ma);
1710
-
1711
- // flip sweep-flag if matrix is not orientation-preserving
1712
- if (ma[0] * ma[3] - ma[1] * ma[2] < 0) {
1713
- s[5] = s[5] ? '0' : '1';
1714
- }
1715
-
1716
- // Transform end point as usual (without translation for relative notation)
1717
- p = m.calc(s[6], s[7], s[0] === 'a');
1718
-
1719
- // Empty arcs can be ignored by renderer, but should not be dropped
1720
- // to avoid collisions with `S A S` and so on. Replace with empty line.
1721
- if ((s[0] === 'A' && s[6] === x && s[7] === y) ||
1722
- (s[0] === 'a' && s[6] === 0 && s[7] === 0)) {
1723
- result = [ s[0] === 'a' ? 'l' : 'L', p[0], p[1] ];
1724
- break;
1725
- }
1726
-
1727
- // if the resulting ellipse is (almost) a segment ...
1728
- if (e.isDegenerate()) {
1729
- // replace the arc by a line
1730
- result = [ s[0] === 'a' ? 'l' : 'L', p[0], p[1] ];
1731
- } else {
1732
- // if it is a real ellipse
1733
- // s[0], s[4] and s[5] are not modified
1734
- result = [ s[0], e.rx, e.ry, e.ax, s[4], s[5], p[0], p[1] ];
1735
- }
1736
-
1737
- break;
1738
-
1739
- case 'm':
1740
- // Edge case. The very first `m` should be processed as absolute, if happens.
1741
- // Make sense for coord shift transforms.
1742
- isRelative = index > 0;
1743
-
1744
- p = m.calc(s[1], s[2], isRelative);
1745
- result = [ 'm', p[0], p[1] ];
1746
- break;
1747
-
1748
- default:
1749
- name = s[0];
1750
- result = [ name ];
1751
- isRelative = (name.toLowerCase() === name);
1752
-
1753
- // Apply transformations to the segment
1754
- for (i = 1; i < s.length; i += 2) {
1755
- p = m.calc(s[i], s[i + 1], isRelative);
1756
- result.push(p[0], p[1]);
1757
- }
1758
- }
1759
-
1760
- self.segments[index] = result;
1761
- }, true);
1762
- };
1763
-
1764
-
1765
- // Apply stacked commands
1766
- //
1767
- SvgPath.prototype.__evaluateStack = function () {
1768
- var m, i;
1769
-
1770
- if (!this.__stack.length) { return; }
1771
-
1772
- if (this.__stack.length === 1) {
1773
- this.__matrix(this.__stack[0]);
1774
- this.__stack = [];
1775
- return;
1776
- }
1777
-
1778
- m = matrix();
1779
- i = this.__stack.length;
1780
-
1781
- while (--i >= 0) {
1782
- m.matrix(this.__stack[i].toArray());
1783
- }
1784
-
1785
- this.__matrix(m);
1786
- this.__stack = [];
1787
- };
1788
-
1789
-
1790
- // Convert processed SVG Path back to string
1791
- //
1792
- SvgPath.prototype.toString = function () {
1793
- var result = '', prevCmd = '', cmdSkipped = false;
1794
-
1795
- this.__evaluateStack();
1796
-
1797
- for (var i = 0, len = this.segments.length; i < len; i++) {
1798
- var segment = this.segments[i];
1799
- var cmd = segment[0];
1800
-
1801
- // Command not repeating => store
1802
- if (cmd !== prevCmd || cmd === 'm' || cmd === 'M') {
1803
- // workaround for FontForge SVG importing bug, keep space between "z m".
1804
- if (cmd === 'm' && prevCmd === 'z') result += ' ';
1805
- result += cmd;
1806
-
1807
- cmdSkipped = false;
1808
- } else {
1809
- cmdSkipped = true;
1810
- }
1811
-
1812
- // Store segment params
1813
- for (var pos = 1; pos < segment.length; pos++) {
1814
- var val = segment[pos];
1815
- // Space can be skipped
1816
- // 1. After command (always)
1817
- // 2. For negative value (with '-' at start)
1818
- if (pos === 1) {
1819
- if (cmdSkipped && val >= 0) result += ' ';
1820
- } else if (val >= 0) result += ' ';
1821
-
1822
- result += val;
1823
- }
1824
-
1825
- prevCmd = cmd;
1826
- }
1827
-
1828
- return result;
1829
- };
1830
-
1831
-
1832
- // Translate path to (x [, y])
1833
- //
1834
- SvgPath.prototype.translate = function (x, y) {
1835
- this.__stack.push(matrix().translate(x, y || 0));
1836
- return this;
1837
- };
1838
-
1839
-
1840
- // Scale path to (sx [, sy])
1841
- // sy = sx if not defined
1842
- //
1843
- SvgPath.prototype.scale = function (sx, sy) {
1844
- this.__stack.push(matrix().scale(sx, (!sy && (sy !== 0)) ? sx : sy));
1845
- return this;
1846
- };
1847
-
1848
-
1849
- // Rotate path around point (sx [, sy])
1850
- // sy = sx if not defined
1851
- //
1852
- SvgPath.prototype.rotate = function (angle, rx, ry) {
1853
- this.__stack.push(matrix().rotate(angle, rx || 0, ry || 0));
1854
- return this;
1855
- };
1856
-
1857
-
1858
- // Skew path along the X axis by `degrees` angle
1859
- //
1860
- SvgPath.prototype.skewX = function (degrees) {
1861
- this.__stack.push(matrix().skewX(degrees));
1862
- return this;
1863
- };
1864
-
1865
-
1866
- // Skew path along the Y axis by `degrees` angle
1867
- //
1868
- SvgPath.prototype.skewY = function (degrees) {
1869
- this.__stack.push(matrix().skewY(degrees));
1870
- return this;
1871
- };
1872
-
1873
-
1874
- // Apply matrix transform (array of 6 elements)
1875
- //
1876
- SvgPath.prototype.matrix = function (m) {
1877
- this.__stack.push(matrix().matrix(m));
1878
- return this;
1879
- };
1880
-
1881
-
1882
- // Transform path according to "transform" attr of SVG spec
1883
- //
1884
- SvgPath.prototype.transform = function (transformString) {
1885
- if (!transformString.trim()) {
1886
- return this;
1887
- }
1888
- this.__stack.push(transformParse(transformString));
1889
- return this;
1890
- };
1891
-
1892
-
1893
- // Round coords with given decimal precition.
1894
- // 0 by default (to integers)
1895
- //
1896
- SvgPath.prototype.round = function (d) {
1897
- var contourStartDeltaX = 0, contourStartDeltaY = 0, deltaX = 0, deltaY = 0, l;
1898
-
1899
- d = d || 0;
1900
-
1901
- this.__evaluateStack();
1902
-
1903
- this.segments.forEach(function (s) {
1904
- var isRelative = (s[0].toLowerCase() === s[0]);
1905
-
1906
- switch (s[0]) {
1907
- case 'H':
1908
- case 'h':
1909
- if (isRelative) { s[1] += deltaX; }
1910
- deltaX = s[1] - s[1].toFixed(d);
1911
- s[1] = +s[1].toFixed(d);
1912
- return;
1913
-
1914
- case 'V':
1915
- case 'v':
1916
- if (isRelative) { s[1] += deltaY; }
1917
- deltaY = s[1] - s[1].toFixed(d);
1918
- s[1] = +s[1].toFixed(d);
1919
- return;
1920
-
1921
- case 'Z':
1922
- case 'z':
1923
- deltaX = contourStartDeltaX;
1924
- deltaY = contourStartDeltaY;
1925
- return;
1926
-
1927
- case 'M':
1928
- case 'm':
1929
- if (isRelative) {
1930
- s[1] += deltaX;
1931
- s[2] += deltaY;
1932
- }
1933
-
1934
- deltaX = s[1] - s[1].toFixed(d);
1935
- deltaY = s[2] - s[2].toFixed(d);
1936
-
1937
- contourStartDeltaX = deltaX;
1938
- contourStartDeltaY = deltaY;
1939
-
1940
- s[1] = +s[1].toFixed(d);
1941
- s[2] = +s[2].toFixed(d);
1942
- return;
1943
-
1944
- case 'A':
1945
- case 'a':
1946
- // [cmd, rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
1947
- if (isRelative) {
1948
- s[6] += deltaX;
1949
- s[7] += deltaY;
1950
- }
1951
-
1952
- deltaX = s[6] - s[6].toFixed(d);
1953
- deltaY = s[7] - s[7].toFixed(d);
1954
-
1955
- s[1] = +s[1].toFixed(d);
1956
- s[2] = +s[2].toFixed(d);
1957
- s[3] = +s[3].toFixed(d + 2); // better precision for rotation
1958
- s[6] = +s[6].toFixed(d);
1959
- s[7] = +s[7].toFixed(d);
1960
- return;
1961
-
1962
- default:
1963
- // a c l q s t
1964
- l = s.length;
1965
-
1966
- if (isRelative) {
1967
- s[l - 2] += deltaX;
1968
- s[l - 1] += deltaY;
1969
- }
1970
-
1971
- deltaX = s[l - 2] - s[l - 2].toFixed(d);
1972
- deltaY = s[l - 1] - s[l - 1].toFixed(d);
1973
-
1974
- s.forEach(function (val, i) {
1975
- if (!i) { return; }
1976
- s[i] = +s[i].toFixed(d);
1977
- });
1978
- return;
1979
- }
1980
- });
1981
-
1982
- return this;
1983
- };
1984
-
1985
-
1986
- // Apply iterator function to all segments. If function returns result,
1987
- // current segment will be replaced to array of returned segments.
1988
- // If empty array is returned, current regment will be deleted.
1989
- //
1990
- SvgPath.prototype.iterate = function (iterator, keepLazyStack) {
1991
- var segments = this.segments,
1992
- replacements = {},
1993
- needReplace = false,
1994
- lastX = 0,
1995
- lastY = 0,
1996
- countourStartX = 0,
1997
- countourStartY = 0;
1998
- var i, j, newSegments;
1999
-
2000
- if (!keepLazyStack) {
2001
- this.__evaluateStack();
2002
- }
2003
-
2004
- segments.forEach(function (s, index) {
2005
-
2006
- var res = iterator(s, index, lastX, lastY);
2007
-
2008
- if (Array.isArray(res)) {
2009
- replacements[index] = res;
2010
- needReplace = true;
2011
- }
2012
-
2013
- var isRelative = (s[0] === s[0].toLowerCase());
2014
-
2015
- // calculate absolute X and Y
2016
- switch (s[0]) {
2017
- case 'm':
2018
- case 'M':
2019
- lastX = s[1] + (isRelative ? lastX : 0);
2020
- lastY = s[2] + (isRelative ? lastY : 0);
2021
- countourStartX = lastX;
2022
- countourStartY = lastY;
2023
- return;
2024
-
2025
- case 'h':
2026
- case 'H':
2027
- lastX = s[1] + (isRelative ? lastX : 0);
2028
- return;
2029
-
2030
- case 'v':
2031
- case 'V':
2032
- lastY = s[1] + (isRelative ? lastY : 0);
2033
- return;
2034
-
2035
- case 'z':
2036
- case 'Z':
2037
- // That make sence for multiple contours
2038
- lastX = countourStartX;
2039
- lastY = countourStartY;
2040
- return;
2041
-
2042
- default:
2043
- lastX = s[s.length - 2] + (isRelative ? lastX : 0);
2044
- lastY = s[s.length - 1] + (isRelative ? lastY : 0);
2045
- }
2046
- });
2047
-
2048
- // Replace segments if iterator return results
2049
-
2050
- if (!needReplace) { return this; }
2051
-
2052
- newSegments = [];
2053
-
2054
- for (i = 0; i < segments.length; i++) {
2055
- if (typeof replacements[i] !== 'undefined') {
2056
- for (j = 0; j < replacements[i].length; j++) {
2057
- newSegments.push(replacements[i][j]);
2058
- }
2059
- } else {
2060
- newSegments.push(segments[i]);
2061
- }
2062
- }
2063
-
2064
- this.segments = newSegments;
2065
-
2066
- return this;
2067
- };
2068
-
2069
-
2070
- // Converts segments from relative to absolute
2071
- //
2072
- SvgPath.prototype.abs = function () {
2073
-
2074
- this.iterate(function (s, index, x, y) {
2075
- var name = s[0],
2076
- nameUC = name.toUpperCase(),
2077
- i;
2078
-
2079
- // Skip absolute commands
2080
- if (name === nameUC) { return; }
2081
-
2082
- s[0] = nameUC;
2083
-
2084
- switch (name) {
2085
- case 'v':
2086
- // v has shifted coords parity
2087
- s[1] += y;
2088
- return;
2089
-
2090
- case 'a':
2091
- // ARC is: ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
2092
- // touch x, y only
2093
- s[6] += x;
2094
- s[7] += y;
2095
- return;
2096
-
2097
- default:
2098
- for (i = 1; i < s.length; i++) {
2099
- s[i] += i % 2 ? x : y; // odd values are X, even - Y
2100
- }
2101
- }
2102
- }, true);
2103
-
2104
- return this;
2105
- };
2106
-
2107
-
2108
- // Converts segments from absolute to relative
2109
- //
2110
- SvgPath.prototype.rel = function () {
2111
-
2112
- this.iterate(function (s, index, x, y) {
2113
- var name = s[0],
2114
- nameLC = name.toLowerCase(),
2115
- i;
2116
-
2117
- // Skip relative commands
2118
- if (name === nameLC) { return; }
2119
-
2120
- // Don't touch the first M to avoid potential confusions.
2121
- if (index === 0 && name === 'M') { return; }
2122
-
2123
- s[0] = nameLC;
2124
-
2125
- switch (name) {
2126
- case 'V':
2127
- // V has shifted coords parity
2128
- s[1] -= y;
2129
- return;
2130
-
2131
- case 'A':
2132
- // ARC is: ['A', rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y]
2133
- // touch x, y only
2134
- s[6] -= x;
2135
- s[7] -= y;
2136
- return;
2137
-
2138
- default:
2139
- for (i = 1; i < s.length; i++) {
2140
- s[i] -= i % 2 ? x : y; // odd values are X, even - Y
2141
- }
2142
- }
2143
- }, true);
2144
-
2145
- return this;
2146
- };
2147
-
2148
-
2149
- // Converts arcs to cubic bézier curves
2150
- //
2151
- SvgPath.prototype.unarc = function () {
2152
- this.iterate(function (s, index, x, y) {
2153
- var new_segments, nextX, nextY, result = [], name = s[0];
2154
-
2155
- // Skip anything except arcs
2156
- if (name !== 'A' && name !== 'a') { return null; }
2157
-
2158
- if (name === 'a') {
2159
- // convert relative arc coordinates to absolute
2160
- nextX = x + s[6];
2161
- nextY = y + s[7];
2162
- } else {
2163
- nextX = s[6];
2164
- nextY = s[7];
2165
- }
2166
-
2167
- new_segments = a2c(x, y, nextX, nextY, s[4], s[5], s[1], s[2], s[3]);
2168
-
2169
- // Degenerated arcs can be ignored by renderer, but should not be dropped
2170
- // to avoid collisions with `S A S` and so on. Replace with empty line.
2171
- if (new_segments.length === 0) {
2172
- return [ [ s[0] === 'a' ? 'l' : 'L', s[6], s[7] ] ];
2173
- }
2174
-
2175
- new_segments.forEach(function (s) {
2176
- result.push([ 'C', s[2], s[3], s[4], s[5], s[6], s[7] ]);
2177
- });
2178
-
2179
- return result;
2180
- });
2181
-
2182
- return this;
2183
- };
2184
-
2185
-
2186
- // Converts smooth curves (with missed control point) to generic curves
2187
- //
2188
- SvgPath.prototype.unshort = function () {
2189
- var segments = this.segments;
2190
- var prevControlX, prevControlY, prevSegment;
2191
- var curControlX, curControlY;
2192
-
2193
- // TODO: add lazy evaluation flag when relative commands supported
2194
-
2195
- this.iterate(function (s, idx, x, y) {
2196
- var name = s[0], nameUC = name.toUpperCase(), isRelative;
2197
-
2198
- // First command MUST be M|m, it's safe to skip.
2199
- // Protect from access to [-1] for sure.
2200
- if (!idx) { return; }
2201
-
2202
- if (nameUC === 'T') { // quadratic curve
2203
- isRelative = (name === 't');
2204
-
2205
- prevSegment = segments[idx - 1];
2206
-
2207
- if (prevSegment[0] === 'Q') {
2208
- prevControlX = prevSegment[1] - x;
2209
- prevControlY = prevSegment[2] - y;
2210
- } else if (prevSegment[0] === 'q') {
2211
- prevControlX = prevSegment[1] - prevSegment[3];
2212
- prevControlY = prevSegment[2] - prevSegment[4];
2213
- } else {
2214
- prevControlX = 0;
2215
- prevControlY = 0;
2216
- }
2217
-
2218
- curControlX = -prevControlX;
2219
- curControlY = -prevControlY;
2220
-
2221
- if (!isRelative) {
2222
- curControlX += x;
2223
- curControlY += y;
2224
- }
2225
-
2226
- segments[idx] = [
2227
- isRelative ? 'q' : 'Q',
2228
- curControlX, curControlY,
2229
- s[1], s[2]
2230
- ];
2231
-
2232
- } else if (nameUC === 'S') { // cubic curve
2233
- isRelative = (name === 's');
2234
-
2235
- prevSegment = segments[idx - 1];
2236
-
2237
- if (prevSegment[0] === 'C') {
2238
- prevControlX = prevSegment[3] - x;
2239
- prevControlY = prevSegment[4] - y;
2240
- } else if (prevSegment[0] === 'c') {
2241
- prevControlX = prevSegment[3] - prevSegment[5];
2242
- prevControlY = prevSegment[4] - prevSegment[6];
2243
- } else {
2244
- prevControlX = 0;
2245
- prevControlY = 0;
2246
- }
2247
-
2248
- curControlX = -prevControlX;
2249
- curControlY = -prevControlY;
2250
-
2251
- if (!isRelative) {
2252
- curControlX += x;
2253
- curControlY += y;
2254
- }
2255
-
2256
- segments[idx] = [
2257
- isRelative ? 'c' : 'C',
2258
- curControlX, curControlY,
2259
- s[1], s[2], s[3], s[4]
2260
- ];
2261
- }
2262
- });
2263
-
2264
- return this;
2265
- };
2266
-
2267
-
2268
- svgpath$1 = SvgPath;
2269
- return svgpath$1;
2270
- }
2271
-
2272
- var svgpath;
2273
- var hasRequiredSvgpath;
2274
-
2275
- function requireSvgpath () {
2276
- if (hasRequiredSvgpath) return svgpath;
2277
- hasRequiredSvgpath = 1;
2278
-
2279
- svgpath = requireSvgpath$1();
2280
- return svgpath;
2281
- }
2282
-
2283
- var svgpathExports = requireSvgpath();
2284
- const Path = /*@__PURE__*/getDefaultExportFromCjs(svgpathExports);
2285
-
2286
- //Parses an SVG path into an object.
2287
- //Taken from https://github.com/jkroso/parse-svg-path
2288
- //Re-written so it can be used with rollup
2289
- var length = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0};
2290
- var segment = /([astvzqmhlc])([^astvzqmhlc]*)/ig;
2291
-
2292
- function parse$1(path) {
2293
- var data = [];
2294
- path.replace(segment, function(_, command, args){
2295
- var type = command.toLowerCase();
2296
- args = parseValues(args);
2297
-
2298
- // overloaded moveTo
2299
- if (type === 'm' && args.length > 2) {
2300
- data.push([command].concat(args.splice(0, 2)));
2301
- type = 'l';
2302
- command = command === 'm' ? 'l' : 'L';
2303
- }
2304
-
2305
- while (args.length >= 0) {
2306
- if (args.length === length[type]) {
2307
- args.unshift(command);
2308
- return data.push(args);
2309
- }
2310
- if (args.length < length[type]) {
2311
- throw new Error('malformed path data');
2312
- }
2313
- data.push([command].concat(args.splice(0, length[type])));
2314
- }
2315
- });
2316
- return data;
2317
- }
2318
-
2319
- var number = /-?[0-9]*\.?[0-9]+(?:e[-+]?\d+)?/ig;
2320
-
2321
- function parseValues(args) {
2322
- var numbers = args.match(number);
2323
- return numbers ? numbers.map(Number) : [];
2324
- }
2325
-
2326
- //Calculate Bezier curve length and positionAtLength
2327
- //Algorithms taken from http://bl.ocks.org/hnakamur/e7efd0602bfc15f66fc5, https://gist.github.com/tunght13488/6744e77c242cc7a94859 and http://stackoverflow.com/questions/11854907/calculate-the-length-of-a-segment-of-a-quadratic-bezier
2328
-
2329
- function Bezier(ax, ay, bx, by, cx, cy, dx, dy) {
2330
- return new Bezier$1(ax, ay, bx, by, cx, cy, dx, dy);
2331
- }
2332
-
2333
- function Bezier$1(ax, ay, bx, by, cx, cy, dx, dy) {
2334
- this.a = {x:ax, y:ay};
2335
- this.b = {x:bx, y:by};
2336
- this.c = {x:cx, y:cy};
2337
- this.d = {x:dx, y:dy};
2338
-
2339
- if(dx !== null && dx !== undefined && dy !== null && dy !== undefined){
2340
- this.getArcLength = getCubicArcLength;
2341
- this.getPoint = cubicPoint;
2342
- this.getDerivative = cubicDerivative;
2343
- } else {
2344
- this.getArcLength = getQuadraticArcLength;
2345
- this.getPoint = quadraticPoint;
2346
- this.getDerivative = quadraticDerivative;
2347
- }
2348
-
2349
- this.init();
2350
- }
2351
-
2352
- Bezier$1.prototype = {
2353
- constructor: Bezier$1,
2354
- init: function() {
2355
-
2356
- this.length = this.getArcLength([this.a.x, this.b.x, this.c.x, this.d.x],
2357
- [this.a.y, this.b.y, this.c.y, this.d.y]);
2358
- },
2359
-
2360
- getTotalLength: function() {
2361
- return this.length;
2362
- },
2363
- getPointAtLength: function(length) {
2364
- var t = t2length(length, this.length, this.getArcLength,
2365
- [this.a.x, this.b.x, this.c.x, this.d.x],
2366
- [this.a.y, this.b.y, this.c.y, this.d.y]);
2367
-
2368
- return this.getPoint([this.a.x, this.b.x, this.c.x, this.d.x],
2369
- [this.a.y, this.b.y, this.c.y, this.d.y],
2370
- t);
2371
- },
2372
- getTangentAtLength: function(length){
2373
- var t = t2length(length, this.length, this.getArcLength,
2374
- [this.a.x, this.b.x, this.c.x, this.d.x],
2375
- [this.a.y, this.b.y, this.c.y, this.d.y]);
2376
-
2377
- var derivative = this.getDerivative([this.a.x, this.b.x, this.c.x, this.d.x],
2378
- [this.a.y, this.b.y, this.c.y, this.d.y], t);
2379
- var mdl = Math.sqrt(derivative.x * derivative.x + derivative.y * derivative.y);
2380
- var tangent;
2381
- if (mdl > 0){
2382
- tangent = {x: derivative.x/mdl, y: derivative.y/mdl};
2383
- } else {
2384
- tangent = {x: 0, y: 0};
2385
- }
2386
- return tangent;
2387
- },
2388
- getPropertiesAtLength: function(length){
2389
- var t = t2length(length, this.length, this.getArcLength,
2390
- [this.a.x, this.b.x, this.c.x, this.d.x],
2391
- [this.a.y, this.b.y, this.c.y, this.d.y]);
2392
-
2393
- var derivative = this.getDerivative([this.a.x, this.b.x, this.c.x, this.d.x],
2394
- [this.a.y, this.b.y, this.c.y, this.d.y], t);
2395
- var mdl = Math.sqrt(derivative.x * derivative.x + derivative.y * derivative.y);
2396
- var tangent;
2397
- if (mdl > 0){
2398
- tangent = {x: derivative.x/mdl, y: derivative.y/mdl};
2399
- } else {
2400
- tangent = {x: 0, y: 0};
2401
- }
2402
- var point = this.getPoint([this.a.x, this.b.x, this.c.x, this.d.x],
2403
- [this.a.y, this.b.y, this.c.y, this.d.y],
2404
- t);
2405
- return {x: point.x, y: point.y, tangentX: tangent.x, tangentY: tangent.y};
2406
- }
2407
- };
2408
-
2409
- function quadraticDerivative(xs, ys, t){
2410
- return {x: (1 - t) * 2*(xs[1] - xs[0]) +t * 2*(xs[2] - xs[1]),
2411
- y: (1 - t) * 2*(ys[1] - ys[0]) +t * 2*(ys[2] - ys[1])
2412
- };
2413
- }
2414
-
2415
- function cubicDerivative(xs, ys, t){
2416
- var derivative = quadraticPoint(
2417
- [3*(xs[1] - xs[0]), 3*(xs[2] - xs[1]), 3*(xs[3] - xs[2])],
2418
- [3*(ys[1] - ys[0]), 3*(ys[2] - ys[1]), 3*(ys[3] - ys[2])],
2419
- t);
2420
- return derivative;
2421
- }
2422
-
2423
- function t2length(length, total_length, func, xs, ys){
2424
- var error = 1;
2425
- var t = length/total_length;
2426
- var step = (length - func(xs, ys, t))/total_length;
2427
-
2428
- while (error > 0.001){
2429
- var increasedTLength = func(xs, ys, t + step);
2430
- var decreasedTLength = func(xs, ys, t - step);
2431
- var increasedTError = Math.abs(length - increasedTLength)/total_length;
2432
- var decreasedTError = Math.abs(length - decreasedTLength)/total_length;
2433
- if (increasedTError < error) {
2434
- error = increasedTError;
2435
- t += step;
2436
- } else if (decreasedTError < error) {
2437
- error = decreasedTError;
2438
- t -= step;
2439
- } else {
2440
- step /= 2;
2441
- }
2442
- }
2443
-
2444
- return t;
2445
- }
2446
-
2447
- function quadraticPoint(xs, ys, t){
2448
- var x = (1 - t) * (1 - t) * xs[0] + 2 * (1 - t) * t * xs[1] + t * t * xs[2];
2449
- var y = (1 - t) * (1 - t) * ys[0] + 2 * (1 - t) * t * ys[1] + t * t * ys[2];
2450
- return {x: x, y: y};
2451
- }
2452
-
2453
- function cubicPoint(xs, ys, t){
2454
- var x = (1 - t) * (1 - t) * (1 - t) * xs[0] + 3 * (1 - t) * (1 - t) * t * xs[1] +
2455
- 3 * (1 - t) * t * t * xs[2] + t * t * t * xs[3];
2456
- var y = (1 - t) * (1 - t) * (1 - t) * ys[0] + 3 * (1 - t) * (1 - t) * t * ys[1] +
2457
- 3 * (1 - t) * t * t * ys[2] + t * t * t * ys[3];
2458
-
2459
- return {x: x, y: y};
2460
- }
2461
-
2462
- function getQuadraticArcLength(xs, ys, t) {
2463
- if (t === undefined) {
2464
- t = 1;
2465
- }
2466
- var ax = xs[0] - 2 * xs[1] + xs[2];
2467
- var ay = ys[0] - 2 * ys[1] + ys[2];
2468
- var bx = 2 * xs[1] - 2 * xs[0];
2469
- var by = 2 * ys[1] - 2 * ys[0];
2470
-
2471
- var A = 4 * (ax * ax + ay * ay);
2472
- var B = 4 * (ax * bx + ay * by);
2473
- var C = bx * bx + by * by;
2474
-
2475
- if(A === 0){
2476
- return t * Math.sqrt(Math.pow(xs[2] - xs[0], 2) + Math.pow(ys[2] - ys[0], 2));
2477
- }
2478
- var b = B/(2*A);
2479
- var c = C/A;
2480
- var u = t + b;
2481
- var k = c - b*b;
2482
-
2483
- return (Math.sqrt(A)/2)*(
2484
- u*Math.sqrt(u*u+k)-b*Math.sqrt(b*b+k)+
2485
- k*Math.log(Math.abs(
2486
- (u+Math.sqrt(u*u+k))/(b+Math.sqrt(b*b+k))
2487
- ))
2488
- );
2489
-
2490
- }
2491
-
2492
- // Legendre-Gauss abscissae (xi values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
2493
- var tValues = [
2494
- [],
2495
- [],
2496
- [-0.5773502691896257,0.5773502691896257645091487805019574556476],
2497
- [0,-0.7745966692414834,0.7745966692414833770358530799564799221665],
2498
- [-0.33998104358485626,0.3399810435848562648026657591032446872005,-0.8611363115940526,0.8611363115940525752239464888928095050957],
2499
- [0,-0.5384693101056831,0.5384693101056830910363144207002088049672,-0.906179845938664,0.9061798459386639927976268782993929651256],
2500
- [0.6612093864662645136613995950199053470064,-0.6612093864662645,-0.2386191860831969,0.2386191860831969086305017216807119354186,-0.932469514203152,0.9324695142031520278123015544939946091347],
2501
- [0, 0.4058451513773971669066064120769614633473,-0.4058451513773972,-0.7415311855993945,0.7415311855993944398638647732807884070741,-0.9491079123427585,0.9491079123427585245261896840478512624007],
2502
- [-0.1834346424956498,0.1834346424956498049394761423601839806667,-0.525532409916329,0.5255324099163289858177390491892463490419,-0.7966664774136267,0.7966664774136267395915539364758304368371,-0.9602898564975363,0.9602898564975362316835608685694729904282],
2503
- [0,-0.8360311073266358,0.8360311073266357942994297880697348765441,-0.9681602395076261,0.9681602395076260898355762029036728700494,-0.3242534234038089,0.3242534234038089290385380146433366085719,-0.6133714327005904,0.6133714327005903973087020393414741847857],
2504
- [-0.14887433898163122,0.1488743389816312108848260011297199846175,-0.4333953941292472,0.4333953941292471907992659431657841622000,-0.6794095682990244,0.6794095682990244062343273651148735757692,-0.8650633666889845,0.8650633666889845107320966884234930485275,-0.9739065285171717,0.9739065285171717200779640120844520534282],
2505
- [0,-0.26954315595234496,0.2695431559523449723315319854008615246796,-0.5190961292068118,0.5190961292068118159257256694586095544802,-0.7301520055740494,0.7301520055740493240934162520311534580496,-0.8870625997680953,0.8870625997680952990751577693039272666316,-0.978228658146057,0.9782286581460569928039380011228573907714],
2506
- [-0.1252334085114689,0.1252334085114689154724413694638531299833,-0.3678314989981802,0.3678314989981801937526915366437175612563,-0.5873179542866175,0.5873179542866174472967024189405342803690,-0.7699026741943047,0.7699026741943046870368938332128180759849,-0.9041172563704749,0.9041172563704748566784658661190961925375,-0.9815606342467192,0.9815606342467192506905490901492808229601],
2507
- [0,-0.2304583159551348,0.2304583159551347940655281210979888352115,-0.44849275103644687,0.4484927510364468528779128521276398678019,-0.6423493394403402,0.6423493394403402206439846069955156500716,-0.8015780907333099,0.8015780907333099127942064895828598903056,-0.9175983992229779,0.9175983992229779652065478365007195123904,-0.9841830547185881,0.9841830547185881494728294488071096110649],
2508
- [-0.10805494870734367,0.1080549487073436620662446502198347476119,-0.31911236892788974,0.3191123689278897604356718241684754668342,-0.5152486363581541,0.5152486363581540919652907185511886623088,-0.6872929048116855,0.6872929048116854701480198030193341375384,-0.827201315069765,0.8272013150697649931897947426503949610397,-0.9284348836635735,0.9284348836635735173363911393778742644770,-0.9862838086968123,0.9862838086968123388415972667040528016760],
2509
- [0,-0.20119409399743451,0.2011940939974345223006283033945962078128,-0.3941513470775634,0.3941513470775633698972073709810454683627,-0.5709721726085388,0.5709721726085388475372267372539106412383,-0.7244177313601701,0.7244177313601700474161860546139380096308,-0.8482065834104272,0.8482065834104272162006483207742168513662,-0.937273392400706,0.9372733924007059043077589477102094712439,-0.9879925180204854,0.9879925180204854284895657185866125811469],
2510
- [-0.09501250983763744,0.0950125098376374401853193354249580631303,-0.2816035507792589,0.2816035507792589132304605014604961064860,-0.45801677765722737,0.4580167776572273863424194429835775735400,-0.6178762444026438,0.6178762444026437484466717640487910189918,-0.755404408355003,0.7554044083550030338951011948474422683538,-0.8656312023878318,0.8656312023878317438804678977123931323873,-0.9445750230732326,0.9445750230732325760779884155346083450911,-0.9894009349916499,0.9894009349916499325961541734503326274262],
2511
- [0,-0.17848418149584785,0.1784841814958478558506774936540655574754,-0.3512317634538763,0.3512317634538763152971855170953460050405,-0.5126905370864769,0.5126905370864769678862465686295518745829,-0.6576711592166907,0.6576711592166907658503022166430023351478,-0.7815140038968014,0.7815140038968014069252300555204760502239,-0.8802391537269859,0.8802391537269859021229556944881556926234,-0.9506755217687678,0.9506755217687677612227169578958030214433,-0.9905754753144174,0.9905754753144173356754340199406652765077],
2512
- [-0.0847750130417353,0.0847750130417353012422618529357838117333,-0.2518862256915055,0.2518862256915055095889728548779112301628,-0.41175116146284263,0.4117511614628426460359317938330516370789,-0.5597708310739475,0.5597708310739475346078715485253291369276,-0.6916870430603532,0.6916870430603532078748910812888483894522,-0.8037049589725231,0.8037049589725231156824174550145907971032,-0.8926024664975557,0.8926024664975557392060605911271455154078,-0.9558239495713977,0.9558239495713977551811958929297763099728,-0.9915651684209309,0.9915651684209309467300160047061507702525],
2513
- [0,-0.16035864564022537,0.1603586456402253758680961157407435495048,-0.31656409996362983,0.3165640999636298319901173288498449178922,-0.46457074137596094,0.4645707413759609457172671481041023679762,-0.600545304661681,0.6005453046616810234696381649462392798683,-0.7209661773352294,0.7209661773352293786170958608237816296571,-0.8227146565371428,0.8227146565371428249789224867127139017745,-0.9031559036148179,0.9031559036148179016426609285323124878093,-0.96020815213483,0.9602081521348300308527788406876515266150,-0.9924068438435844,0.9924068438435844031890176702532604935893],
2514
- [-0.07652652113349734,0.0765265211334973337546404093988382110047,-0.22778585114164507,0.2277858511416450780804961953685746247430,-0.37370608871541955,0.3737060887154195606725481770249272373957,-0.5108670019508271,0.5108670019508270980043640509552509984254,-0.636053680726515,0.6360536807265150254528366962262859367433,-0.7463319064601508,0.7463319064601507926143050703556415903107,-0.8391169718222188,0.8391169718222188233945290617015206853296,-0.912234428251326,0.9122344282513259058677524412032981130491,-0.9639719272779138,0.9639719272779137912676661311972772219120,-0.9931285991850949,0.9931285991850949247861223884713202782226],
2515
- [0,-0.1455618541608951,0.1455618541608950909370309823386863301163,-0.2880213168024011,0.2880213168024010966007925160646003199090,-0.4243421202074388,0.4243421202074387835736688885437880520964,-0.5516188358872198,0.5516188358872198070590187967243132866220,-0.6671388041974123,0.6671388041974123193059666699903391625970,-0.7684399634756779,0.7684399634756779086158778513062280348209,-0.8533633645833173,0.8533633645833172836472506385875676702761,-0.9200993341504008,0.9200993341504008287901871337149688941591,-0.9672268385663063,0.9672268385663062943166222149076951614246,-0.9937521706203895,0.9937521706203895002602420359379409291933],
2516
- [-0.06973927331972223,0.0697392733197222212138417961186280818222,-0.20786042668822127,0.2078604266882212854788465339195457342156,-0.34193582089208424,0.3419358208920842251581474204273796195591,-0.469355837986757,0.4693558379867570264063307109664063460953,-0.5876404035069116,0.5876404035069115929588769276386473488776,-0.6944872631866827,0.6944872631866827800506898357622567712673,-0.7878168059792081,0.7878168059792081620042779554083515213881,-0.8658125777203002,0.8658125777203001365364256370193787290847,-0.926956772187174,0.9269567721871740005206929392590531966353,-0.9700604978354287,0.9700604978354287271239509867652687108059,-0.9942945854823992,0.9942945854823992920730314211612989803930],
2517
- [0,-0.1332568242984661,0.1332568242984661109317426822417661370104,-0.26413568097034495,0.2641356809703449305338695382833096029790,-0.3903010380302908,0.3903010380302908314214888728806054585780,-0.5095014778460075,0.5095014778460075496897930478668464305448,-0.6196098757636461,0.6196098757636461563850973116495956533871,-0.7186613631319502,0.7186613631319501944616244837486188483299,-0.8048884016188399,0.8048884016188398921511184069967785579414,-0.8767523582704416,0.8767523582704416673781568859341456716389,-0.9329710868260161,0.9329710868260161023491969890384229782357,-0.9725424712181152,0.9725424712181152319560240768207773751816,-0.9947693349975522,0.9947693349975521235239257154455743605736],
2518
- [-0.06405689286260563,0.0640568928626056260850430826247450385909,-0.1911188674736163,0.1911188674736163091586398207570696318404,-0.3150426796961634,0.3150426796961633743867932913198102407864,-0.4337935076260451,0.4337935076260451384870842319133497124524,-0.5454214713888396,0.5454214713888395356583756172183723700107,-0.6480936519369755,0.6480936519369755692524957869107476266696,-0.7401241915785544,0.7401241915785543642438281030999784255232,-0.820001985973903,0.8200019859739029219539498726697452080761,-0.8864155270044011,0.8864155270044010342131543419821967550873,-0.9382745520027328,0.9382745520027327585236490017087214496548,-0.9747285559713095,0.9747285559713094981983919930081690617411,-0.9951872199970213,0.9951872199970213601799974097007368118745]
2519
- ];
2520
-
2521
- // Legendre-Gauss weights (wi values, defined by a function linked to in the Bezier primer article)
2522
- var cValues = [
2523
- [],[],
2524
- [1.0,1.0],
2525
- [0.8888888888888888888888888888888888888888,0.5555555555555555555555555555555555555555,0.5555555555555555555555555555555555555555],
2526
- [0.6521451548625461426269360507780005927646,0.6521451548625461426269360507780005927646,0.3478548451374538573730639492219994072353,0.3478548451374538573730639492219994072353],
2527
- [0.5688888888888888888888888888888888888888,0.4786286704993664680412915148356381929122,0.4786286704993664680412915148356381929122,0.2369268850561890875142640407199173626432,0.2369268850561890875142640407199173626432],
2528
- [0.3607615730481386075698335138377161116615,0.3607615730481386075698335138377161116615,0.4679139345726910473898703439895509948116,0.4679139345726910473898703439895509948116,0.1713244923791703450402961421727328935268,0.1713244923791703450402961421727328935268],
2529
- [0.4179591836734693877551020408163265306122,0.3818300505051189449503697754889751338783,0.3818300505051189449503697754889751338783,0.2797053914892766679014677714237795824869,0.2797053914892766679014677714237795824869,0.1294849661688696932706114326790820183285,0.1294849661688696932706114326790820183285],
2530
- [0.3626837833783619829651504492771956121941,0.3626837833783619829651504492771956121941,0.3137066458778872873379622019866013132603,0.3137066458778872873379622019866013132603,0.2223810344533744705443559944262408844301,0.2223810344533744705443559944262408844301,0.1012285362903762591525313543099621901153,0.1012285362903762591525313543099621901153],
2531
- [0.3302393550012597631645250692869740488788,0.1806481606948574040584720312429128095143,0.1806481606948574040584720312429128095143,0.0812743883615744119718921581105236506756,0.0812743883615744119718921581105236506756,0.3123470770400028400686304065844436655987,0.3123470770400028400686304065844436655987,0.2606106964029354623187428694186328497718,0.2606106964029354623187428694186328497718],
2532
- [0.2955242247147528701738929946513383294210,0.2955242247147528701738929946513383294210,0.2692667193099963550912269215694693528597,0.2692667193099963550912269215694693528597,0.2190863625159820439955349342281631924587,0.2190863625159820439955349342281631924587,0.1494513491505805931457763396576973324025,0.1494513491505805931457763396576973324025,0.0666713443086881375935688098933317928578,0.0666713443086881375935688098933317928578],
2533
- [0.2729250867779006307144835283363421891560,0.2628045445102466621806888698905091953727,0.2628045445102466621806888698905091953727,0.2331937645919904799185237048431751394317,0.2331937645919904799185237048431751394317,0.1862902109277342514260976414316558916912,0.1862902109277342514260976414316558916912,0.1255803694649046246346942992239401001976,0.1255803694649046246346942992239401001976,0.0556685671161736664827537204425485787285,0.0556685671161736664827537204425485787285],
2534
- [0.2491470458134027850005624360429512108304,0.2491470458134027850005624360429512108304,0.2334925365383548087608498989248780562594,0.2334925365383548087608498989248780562594,0.2031674267230659217490644558097983765065,0.2031674267230659217490644558097983765065,0.1600783285433462263346525295433590718720,0.1600783285433462263346525295433590718720,0.1069393259953184309602547181939962242145,0.1069393259953184309602547181939962242145,0.0471753363865118271946159614850170603170,0.0471753363865118271946159614850170603170],
2535
- [0.2325515532308739101945895152688359481566,0.2262831802628972384120901860397766184347,0.2262831802628972384120901860397766184347,0.2078160475368885023125232193060527633865,0.2078160475368885023125232193060527633865,0.1781459807619457382800466919960979955128,0.1781459807619457382800466919960979955128,0.1388735102197872384636017768688714676218,0.1388735102197872384636017768688714676218,0.0921214998377284479144217759537971209236,0.0921214998377284479144217759537971209236,0.0404840047653158795200215922009860600419,0.0404840047653158795200215922009860600419],
2536
- [0.2152638534631577901958764433162600352749,0.2152638534631577901958764433162600352749,0.2051984637212956039659240656612180557103,0.2051984637212956039659240656612180557103,0.1855383974779378137417165901251570362489,0.1855383974779378137417165901251570362489,0.1572031671581935345696019386238421566056,0.1572031671581935345696019386238421566056,0.1215185706879031846894148090724766259566,0.1215185706879031846894148090724766259566,0.0801580871597602098056332770628543095836,0.0801580871597602098056332770628543095836,0.0351194603317518630318328761381917806197,0.0351194603317518630318328761381917806197],
2537
- [0.2025782419255612728806201999675193148386,0.1984314853271115764561183264438393248186,0.1984314853271115764561183264438393248186,0.1861610000155622110268005618664228245062,0.1861610000155622110268005618664228245062,0.1662692058169939335532008604812088111309,0.1662692058169939335532008604812088111309,0.1395706779261543144478047945110283225208,0.1395706779261543144478047945110283225208,0.1071592204671719350118695466858693034155,0.1071592204671719350118695466858693034155,0.0703660474881081247092674164506673384667,0.0703660474881081247092674164506673384667,0.0307532419961172683546283935772044177217,0.0307532419961172683546283935772044177217],
2538
- [0.1894506104550684962853967232082831051469,0.1894506104550684962853967232082831051469,0.1826034150449235888667636679692199393835,0.1826034150449235888667636679692199393835,0.1691565193950025381893120790303599622116,0.1691565193950025381893120790303599622116,0.1495959888165767320815017305474785489704,0.1495959888165767320815017305474785489704,0.1246289712555338720524762821920164201448,0.1246289712555338720524762821920164201448,0.0951585116824927848099251076022462263552,0.0951585116824927848099251076022462263552,0.0622535239386478928628438369943776942749,0.0622535239386478928628438369943776942749,0.0271524594117540948517805724560181035122,0.0271524594117540948517805724560181035122],
2539
- [0.1794464703562065254582656442618856214487,0.1765627053669926463252709901131972391509,0.1765627053669926463252709901131972391509,0.1680041021564500445099706637883231550211,0.1680041021564500445099706637883231550211,0.1540457610768102880814315948019586119404,0.1540457610768102880814315948019586119404,0.1351363684685254732863199817023501973721,0.1351363684685254732863199817023501973721,0.1118838471934039710947883856263559267358,0.1118838471934039710947883856263559267358,0.0850361483171791808835353701910620738504,0.0850361483171791808835353701910620738504,0.0554595293739872011294401653582446605128,0.0554595293739872011294401653582446605128,0.0241483028685479319601100262875653246916,0.0241483028685479319601100262875653246916],
2540
- [0.1691423829631435918406564701349866103341,0.1691423829631435918406564701349866103341,0.1642764837458327229860537764659275904123,0.1642764837458327229860537764659275904123,0.1546846751262652449254180038363747721932,0.1546846751262652449254180038363747721932,0.1406429146706506512047313037519472280955,0.1406429146706506512047313037519472280955,0.1225552067114784601845191268002015552281,0.1225552067114784601845191268002015552281,0.1009420441062871655628139849248346070628,0.1009420441062871655628139849248346070628,0.0764257302548890565291296776166365256053,0.0764257302548890565291296776166365256053,0.0497145488949697964533349462026386416808,0.0497145488949697964533349462026386416808,0.0216160135264833103133427102664524693876,0.0216160135264833103133427102664524693876],
2541
- [0.1610544498487836959791636253209167350399,0.1589688433939543476499564394650472016787,0.1589688433939543476499564394650472016787,0.1527660420658596667788554008976629984610,0.1527660420658596667788554008976629984610,0.1426067021736066117757461094419029724756,0.1426067021736066117757461094419029724756,0.1287539625393362276755157848568771170558,0.1287539625393362276755157848568771170558,0.1115666455473339947160239016817659974813,0.1115666455473339947160239016817659974813,0.0914900216224499994644620941238396526609,0.0914900216224499994644620941238396526609,0.0690445427376412265807082580060130449618,0.0690445427376412265807082580060130449618,0.0448142267656996003328381574019942119517,0.0448142267656996003328381574019942119517,0.0194617882297264770363120414644384357529,0.0194617882297264770363120414644384357529],
2542
- [0.1527533871307258506980843319550975934919,0.1527533871307258506980843319550975934919,0.1491729864726037467878287370019694366926,0.1491729864726037467878287370019694366926,0.1420961093183820513292983250671649330345,0.1420961093183820513292983250671649330345,0.1316886384491766268984944997481631349161,0.1316886384491766268984944997481631349161,0.1181945319615184173123773777113822870050,0.1181945319615184173123773777113822870050,0.1019301198172404350367501354803498761666,0.1019301198172404350367501354803498761666,0.0832767415767047487247581432220462061001,0.0832767415767047487247581432220462061001,0.0626720483341090635695065351870416063516,0.0626720483341090635695065351870416063516,0.0406014298003869413310399522749321098790,0.0406014298003869413310399522749321098790,0.0176140071391521183118619623518528163621,0.0176140071391521183118619623518528163621],
2543
- [0.1460811336496904271919851476833711882448,0.1445244039899700590638271665537525436099,0.1445244039899700590638271665537525436099,0.1398873947910731547221334238675831108927,0.1398873947910731547221334238675831108927,0.1322689386333374617810525744967756043290,0.1322689386333374617810525744967756043290,0.1218314160537285341953671771257335983563,0.1218314160537285341953671771257335983563,0.1087972991671483776634745780701056420336,0.1087972991671483776634745780701056420336,0.0934444234560338615532897411139320884835,0.0934444234560338615532897411139320884835,0.0761001136283793020170516533001831792261,0.0761001136283793020170516533001831792261,0.0571344254268572082836358264724479574912,0.0571344254268572082836358264724479574912,0.0369537897708524937999506682993296661889,0.0369537897708524937999506682993296661889,0.0160172282577743333242246168584710152658,0.0160172282577743333242246168584710152658],
2544
- [0.1392518728556319933754102483418099578739,0.1392518728556319933754102483418099578739,0.1365414983460151713525738312315173965863,0.1365414983460151713525738312315173965863,0.1311735047870623707329649925303074458757,0.1311735047870623707329649925303074458757,0.1232523768105124242855609861548144719594,0.1232523768105124242855609861548144719594,0.1129322960805392183934006074217843191142,0.1129322960805392183934006074217843191142,0.1004141444428809649320788378305362823508,0.1004141444428809649320788378305362823508,0.0859416062170677274144436813727028661891,0.0859416062170677274144436813727028661891,0.0697964684245204880949614189302176573987,0.0697964684245204880949614189302176573987,0.0522933351526832859403120512732112561121,0.0522933351526832859403120512732112561121,0.0337749015848141547933022468659129013491,0.0337749015848141547933022468659129013491,0.0146279952982722006849910980471854451902,0.0146279952982722006849910980471854451902],
2545
- [0.1336545721861061753514571105458443385831,0.1324620394046966173716424647033169258050,0.1324620394046966173716424647033169258050,0.1289057221880821499785953393997936532597,0.1289057221880821499785953393997936532597,0.1230490843067295304675784006720096548158,0.1230490843067295304675784006720096548158,0.1149966402224113649416435129339613014914,0.1149966402224113649416435129339613014914,0.1048920914645414100740861850147438548584,0.1048920914645414100740861850147438548584,0.0929157660600351474770186173697646486034,0.0929157660600351474770186173697646486034,0.0792814117767189549228925247420432269137,0.0792814117767189549228925247420432269137,0.0642324214085258521271696151589109980391,0.0642324214085258521271696151589109980391,0.0480376717310846685716410716320339965612,0.0480376717310846685716410716320339965612,0.0309880058569794443106942196418845053837,0.0309880058569794443106942196418845053837,0.0134118594871417720813094934586150649766,0.0134118594871417720813094934586150649766],
2546
- [0.1279381953467521569740561652246953718517,0.1279381953467521569740561652246953718517,0.1258374563468282961213753825111836887264,0.1258374563468282961213753825111836887264,0.1216704729278033912044631534762624256070,0.1216704729278033912044631534762624256070,0.1155056680537256013533444839067835598622,0.1155056680537256013533444839067835598622,0.1074442701159656347825773424466062227946,0.1074442701159656347825773424466062227946,0.0976186521041138882698806644642471544279,0.0976186521041138882698806644642471544279,0.0861901615319532759171852029837426671850,0.0861901615319532759171852029837426671850,0.0733464814110803057340336152531165181193,0.0733464814110803057340336152531165181193,0.0592985849154367807463677585001085845412,0.0592985849154367807463677585001085845412,0.0442774388174198061686027482113382288593,0.0442774388174198061686027482113382288593,0.0285313886289336631813078159518782864491,0.0285313886289336631813078159518782864491,0.0123412297999871995468056670700372915759,0.0123412297999871995468056670700372915759]
2547
- ];
2548
-
2549
- // LUT for binomial coefficient arrays per curve order 'n'
2550
- var binomialCoefficients = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]];
2551
-
2552
- // Look up what the binomial coefficient is for pair {n,k}
2553
- function binomials(n, k) {
2554
- return binomialCoefficients[n][k];
2555
- }
2556
-
2557
- /**
2558
- * Compute the curve derivative (hodograph) at t.
2559
- */
2560
- function getDerivative(derivative, t, vs) {
2561
- // the derivative of any 't'-less function is zero.
2562
- var n = vs.length - 1,
2563
- _vs,
2564
- value,
2565
- k;
2566
- if (n === 0) {
2567
- return 0;
2568
- }
2569
-
2570
- // direct values? compute!
2571
- if (derivative === 0) {
2572
- value = 0;
2573
- for (k = 0; k <= n; k++) {
2574
- value += binomials(n, k) * Math.pow(1 - t, n - k) * Math.pow(t, k) * vs[k];
2575
- }
2576
- return value;
2577
- } else {
2578
- // Still some derivative? go down one order, then try
2579
- // for the lower order curve's.
2580
- _vs = new Array(n);
2581
- for (k = 0; k < n; k++) {
2582
- _vs[k] = n * (vs[k + 1] - vs[k]);
2583
- }
2584
- return getDerivative(derivative - 1, t, _vs);
2585
- }
2586
- }
2587
-
2588
- function B(xs, ys, t) {
2589
- var xbase = getDerivative(1, t, xs);
2590
- var ybase = getDerivative(1, t, ys);
2591
- var combined = xbase * xbase + ybase * ybase;
2592
- return Math.sqrt(combined);
2593
- }
2594
-
2595
- function getCubicArcLength(xs, ys, t) {
2596
- var z, sum, i, correctedT;
2597
-
2598
- /*if (xs.length >= tValues.length) {
2599
- throw new Error('too high n bezier');
2600
- }*/
2601
-
2602
- if (t === undefined) {
2603
- t = 1;
2604
- }
2605
- var n = 20;
2606
-
2607
- z = t / 2;
2608
- sum = 0;
2609
- for (i = 0; i < n; i++) {
2610
- correctedT = z * tValues[n][i] + z;
2611
- sum += cValues[n][i] * B(xs, ys, correctedT);
2612
- }
2613
- return z * sum;
2614
- }
2615
-
2616
- //This file is taken from the following project: https://github.com/fontello/svgpath
2617
- // Convert an arc to a sequence of cubic bézier curves
2618
- //
2619
-
2620
-
2621
- var TAU = Math.PI * 2;
2622
-
2623
-
2624
- /* eslint-disable space-infix-ops */
2625
-
2626
- // Calculate an angle between two unit vectors
2627
- //
2628
- // Since we measure angle between radii of circular arcs,
2629
- // we can use simplified math (without length normalization)
2630
- //
2631
- function unit_vector_angle(ux, uy, vx, vy) {
2632
- var sign = (ux * vy - uy * vx < 0) ? -1 : 1;
2633
- var dot = ux * vx + uy * vy;
2634
-
2635
- // Add this to work with arbitrary vectors:
2636
- // dot /= Math.sqrt(ux * ux + uy * uy) * Math.sqrt(vx * vx + vy * vy);
2637
-
2638
- // rounding errors, e.g. -1.0000000000000002 can screw up this
2639
- if (dot > 1.0) { dot = 1.0; }
2640
- if (dot < -1) { dot = -1; }
2641
-
2642
- return sign * Math.acos(dot);
2643
- }
2644
-
2645
-
2646
- // Convert from endpoint to center parameterization,
2647
- // see http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
2648
- //
2649
- // Return [cx, cy, theta1, delta_theta]
2650
- //
2651
- function get_arc_center(x1, y1, x2, y2, fa, fs, rx, ry, sin_phi, cos_phi) {
2652
- // Step 1.
2653
- //
2654
- // Moving an ellipse so origin will be the middlepoint between our two
2655
- // points. After that, rotate it to line up ellipse axes with coordinate
2656
- // axes.
2657
- //
2658
- var x1p = cos_phi*(x1-x2)/2 + sin_phi*(y1-y2)/2;
2659
- var y1p = -sin_phi*(x1-x2)/2 + cos_phi*(y1-y2)/2;
2660
-
2661
- var rx_sq = rx * rx;
2662
- var ry_sq = ry * ry;
2663
- var x1p_sq = x1p * x1p;
2664
- var y1p_sq = y1p * y1p;
2665
-
2666
- // Step 2.
2667
- //
2668
- // Compute coordinates of the centre of this ellipse (cx', cy')
2669
- // in the new coordinate system.
2670
- //
2671
- var radicant = (rx_sq * ry_sq) - (rx_sq * y1p_sq) - (ry_sq * x1p_sq);
2672
-
2673
- if (radicant < 0) {
2674
- // due to rounding errors it might be e.g. -1.3877787807814457e-17
2675
- radicant = 0;
2676
- }
2677
-
2678
- radicant /= (rx_sq * y1p_sq) + (ry_sq * x1p_sq);
2679
- radicant = Math.sqrt(radicant) * (fa === fs ? -1 : 1);
2680
-
2681
- var cxp = radicant * rx/ry * y1p;
2682
- var cyp = radicant * -ry/rx * x1p;
2683
-
2684
- // Step 3.
2685
- //
2686
- // Transform back to get centre coordinates (cx, cy) in the original
2687
- // coordinate system.
2688
- //
2689
- var cx = cos_phi*cxp - sin_phi*cyp + (x1+x2)/2;
2690
- var cy = sin_phi*cxp + cos_phi*cyp + (y1+y2)/2;
2691
-
2692
- // Step 4.
2693
- //
2694
- // Compute angles (theta1, delta_theta).
2695
- //
2696
- var v1x = (x1p - cxp) / rx;
2697
- var v1y = (y1p - cyp) / ry;
2698
- var v2x = (-x1p - cxp) / rx;
2699
- var v2y = (-y1p - cyp) / ry;
2700
-
2701
- var theta1 = unit_vector_angle(1, 0, v1x, v1y);
2702
- var delta_theta = unit_vector_angle(v1x, v1y, v2x, v2y);
2703
-
2704
- if (fs === 0 && delta_theta > 0) {
2705
- delta_theta -= TAU;
2706
- }
2707
- if (fs === 1 && delta_theta < 0) {
2708
- delta_theta += TAU;
2709
- }
2710
-
2711
- return [ cx, cy, theta1, delta_theta ];
2712
- }
2713
-
2714
- //
2715
- // Approximate one unit arc segment with bézier curves,
2716
- // see http://math.stackexchange.com/questions/873224
2717
- //
2718
- function approximate_unit_arc(theta1, delta_theta) {
2719
- var alpha = 4/3 * Math.tan(delta_theta/4);
2720
-
2721
- var x1 = Math.cos(theta1);
2722
- var y1 = Math.sin(theta1);
2723
- var x2 = Math.cos(theta1 + delta_theta);
2724
- var y2 = Math.sin(theta1 + delta_theta);
2725
-
2726
- return [ x1, y1, x1 - y1*alpha, y1 + x1*alpha, x2 + y2*alpha, y2 - x2*alpha, x2, y2 ];
2727
- }
2728
-
2729
- function a2c(x1, y1, rx, ry, phi, fa, fs, x2, y2) {
2730
- var sin_phi = Math.sin(phi * TAU / 360);
2731
- var cos_phi = Math.cos(phi * TAU / 360);
2732
-
2733
- // Make sure radii are valid
2734
- //
2735
- var x1p = cos_phi*(x1-x2)/2 + sin_phi*(y1-y2)/2;
2736
- var y1p = -sin_phi*(x1-x2)/2 + cos_phi*(y1-y2)/2;
2737
-
2738
- if (x1p === 0 && y1p === 0) {
2739
- // we're asked to draw line to itself
2740
- return [];
2741
- }
2742
-
2743
- if (rx === 0 || ry === 0) {
2744
- // one of the radii is zero
2745
- return [];
2746
- }
2747
-
2748
-
2749
- // Compensate out-of-range radii
2750
- //
2751
- rx = Math.abs(rx);
2752
- ry = Math.abs(ry);
2753
-
2754
- var lambda = (x1p * x1p) / (rx * rx) + (y1p * y1p) / (ry * ry);
2755
- if (lambda > 1) {
2756
- rx *= Math.sqrt(lambda);
2757
- ry *= Math.sqrt(lambda);
2758
- }
2759
-
2760
-
2761
- // Get center parameters (cx, cy, theta1, delta_theta)
2762
- //
2763
- var cc = get_arc_center(x1, y1, x2, y2, fa, fs, rx, ry, sin_phi, cos_phi);
2764
-
2765
- var result = [];
2766
- var theta1 = cc[2];
2767
- var delta_theta = cc[3];
2768
-
2769
- // Split an arc to multiple segments, so each segment
2770
- // will be less than τ/4 (= 90°)
2771
- //
2772
- var segments = Math.max(Math.ceil(Math.abs(delta_theta) / (TAU / 4)), 1);
2773
- delta_theta /= segments;
2774
-
2775
- for (var i = 0; i < segments; i++) {
2776
- result.push(approximate_unit_arc(theta1, delta_theta));
2777
- theta1 += delta_theta;
2778
- }
2779
-
2780
- // We have a bezier approximation of a unit circle,
2781
- // now need to transform back to the original ellipse
2782
- //
2783
- return result.map(function (curve) {
2784
- for (var i = 0; i < curve.length; i += 2) {
2785
- var x = curve[i + 0];
2786
- var y = curve[i + 1];
2787
-
2788
- // scale
2789
- x *= rx;
2790
- y *= ry;
2791
-
2792
- // rotate
2793
- var xp = cos_phi*x - sin_phi*y;
2794
- var yp = sin_phi*x + cos_phi*y;
2795
-
2796
- // translate
2797
- curve[i + 0] = xp + cc[0];
2798
- curve[i + 1] = yp + cc[1];
2799
- }
2800
-
2801
- return curve;
2802
- });
2803
- }
2804
-
2805
- //Calculate ans Arc curve length and positionAtLength
2806
- //Definitions taken from https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
2807
-
2808
-
2809
- function Arc(x0, y0, rx,ry, xAxisRotate, LargeArcFlag,SweepFlag, x,y) {
2810
- return new Arc$1(x0, y0, rx,ry, xAxisRotate, LargeArcFlag,SweepFlag, x,y);
2811
- }
2812
-
2813
- function Arc$1(x0, y0,rx,ry, xAxisRotate, LargeArcFlag,SweepFlag,x,y) {
2814
- var length = 0;
2815
- var partialLengths = [];
2816
- var curves = [];
2817
- var res = a2c(x0, y0,rx,ry, xAxisRotate, LargeArcFlag,SweepFlag,x,y);
2818
- res.forEach(function(d){
2819
- var curve = new Bezier(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);
2820
- var curveLength = curve.getTotalLength();
2821
- length += curveLength;
2822
- partialLengths.push(curveLength);
2823
- curves.push(curve);
2824
- });
2825
- this.length = length;
2826
- this.partialLengths = partialLengths;
2827
- this.curves = curves;
2828
- }
2829
-
2830
- Arc$1.prototype = {
2831
- constructor: Arc$1,
2832
- init: function() {
2833
-
2834
-
2835
- },
2836
-
2837
- getTotalLength: function() {
2838
- return this.length;
2839
- },
2840
- getPointAtLength: function(fractionLength) {
2841
-
2842
- if(fractionLength < 0){
2843
- fractionLength = 0;
2844
- } else if(fractionLength > this.length){
2845
- fractionLength = this.length;
2846
- }
2847
- var i = this.partialLengths.length - 1;
2848
-
2849
- while(this.partialLengths[i] >= fractionLength && this.partialLengths[i] > 0){
2850
- i--;
2851
- }
2852
- if(i<this.partialLengths.length-1){
2853
- i++;
2854
- }
2855
-
2856
- var lengthOffset = 0;
2857
- for(var j=0; j<i; j++){
2858
- lengthOffset += this.partialLengths[j];
2859
- }
2860
-
2861
- return this.curves[i].getPointAtLength(fractionLength - lengthOffset);
2862
- },
2863
- getTangentAtLength: function(fractionLength) {
2864
- if(fractionLength < 0){
2865
- fractionLength = 0;
2866
- } else if(fractionLength > this.length){
2867
- fractionLength = this.length;
2868
- }
2869
- var i = this.partialLengths.length - 1;
2870
-
2871
- while(this.partialLengths[i] >= fractionLength && this.partialLengths[i] > 0){
2872
- i--;
2873
- }
2874
- if(i<this.partialLengths.length-1){
2875
- i++;
2876
- }
2877
-
2878
- var lengthOffset = 0;
2879
- for(var j=0; j<i; j++){
2880
- lengthOffset += this.partialLengths[j];
2881
- }
2882
-
2883
- return this.curves[i].getTangentAtLength(fractionLength - lengthOffset);
2884
- },
2885
- getPropertiesAtLength: function(fractionLength){
2886
- var tangent = this.getTangentAtLength(fractionLength);
2887
- var point = this.getPointAtLength(fractionLength);
2888
- return {x: point.x, y: point.y, tangentX: tangent.x, tangentY: tangent.y};
2889
- }
2890
- };
2891
-
2892
- function LinearPosition(x0, x1, y0, y1) {
2893
- return new LinearPosition$1(x0, x1, y0, y1);
2894
-
2895
- }
2896
-
2897
- function LinearPosition$1(x0, x1, y0, y1){
2898
- this.x0 = x0;
2899
- this.x1 = x1;
2900
- this.y0 = y0;
2901
- this.y1 = y1;
2902
- }
2903
-
2904
- LinearPosition$1.prototype.getTotalLength = function(){
2905
- return Math.sqrt(Math.pow(this.x0 - this.x1, 2) +
2906
- Math.pow(this.y0 - this.y1, 2));
2907
- };
2908
-
2909
- LinearPosition$1.prototype.getPointAtLength = function(pos){
2910
- var fraction = pos/ (Math.sqrt(Math.pow(this.x0 - this.x1, 2) +
2911
- Math.pow(this.y0 - this.y1, 2)));
2912
-
2913
- var newDeltaX = (this.x1 - this.x0)*fraction;
2914
- var newDeltaY = (this.y1 - this.y0)*fraction;
2915
- return { x: this.x0 + newDeltaX, y: this.y0 + newDeltaY };
2916
- };
2917
- LinearPosition$1.prototype.getTangentAtLength = function(){
2918
- var module = Math.sqrt((this.x1 - this.x0) * (this.x1 - this.x0) +
2919
- (this.y1 - this.y0) * (this.y1 - this.y0));
2920
- return { x: (this.x1 - this.x0)/module, y: (this.y1 - this.y0)/module };
2921
- };
2922
- LinearPosition$1.prototype.getPropertiesAtLength = function(pos){
2923
- var point = this.getPointAtLength(pos);
2924
- var tangent = this.getTangentAtLength();
2925
- return {x: point.x, y: point.y, tangentX: tangent.x, tangentY: tangent.y};
2926
- };
2927
-
2928
- function svgPathProperties(svgString) {
2929
- var length = 0;
2930
- var partial_lengths = [];
2931
- var functions = [];
2932
-
2933
- function svgProperties(string){
2934
- if(!string){return null;}
2935
- var parsed = parse$1(string);
2936
- var cur = [0, 0];
2937
- var prev_point = [0, 0];
2938
- var curve;
2939
- var ringStart;
2940
- for (var i = 0; i < parsed.length; i++){
2941
- //moveTo
2942
- if(parsed[i][0] === "M"){
2943
- cur = [parsed[i][1], parsed[i][2]];
2944
- ringStart = [cur[0], cur[1]];
2945
- functions.push(null);
2946
- } else if(parsed[i][0] === "m"){
2947
- cur = [parsed[i][1] + cur[0], parsed[i][2] + cur[1]];
2948
- ringStart = [cur[0], cur[1]];
2949
- functions.push(null);
2950
- }
2951
- //lineTo
2952
- else if(parsed[i][0] === "L"){
2953
- length = length + Math.sqrt(Math.pow(cur[0] - parsed[i][1], 2) + Math.pow(cur[1] - parsed[i][2], 2));
2954
- functions.push(new LinearPosition(cur[0], parsed[i][1], cur[1], parsed[i][2]));
2955
- cur = [parsed[i][1], parsed[i][2]];
2956
- } else if(parsed[i][0] === "l"){
2957
- length = length + Math.sqrt(Math.pow(parsed[i][1], 2) + Math.pow(parsed[i][2], 2));
2958
- functions.push(new LinearPosition(cur[0], parsed[i][1] + cur[0], cur[1], parsed[i][2] + cur[1]));
2959
- cur = [parsed[i][1] + cur[0], parsed[i][2] + cur[1]];
2960
- } else if(parsed[i][0] === "H"){
2961
- length = length + Math.abs(cur[0] - parsed[i][1]);
2962
- functions.push(new LinearPosition(cur[0], parsed[i][1], cur[1], cur[1]));
2963
- cur[0] = parsed[i][1];
2964
- } else if(parsed[i][0] === "h"){
2965
- length = length + Math.abs(parsed[i][1]);
2966
- functions.push(new LinearPosition(cur[0], cur[0] + parsed[i][1], cur[1], cur[1]));
2967
- cur[0] = parsed[i][1] + cur[0];
2968
- } else if(parsed[i][0] === "V"){
2969
- length = length + Math.abs(cur[1] - parsed[i][1]);
2970
- functions.push(new LinearPosition(cur[0], cur[0], cur[1], parsed[i][1]));
2971
- cur[1] = parsed[i][1];
2972
- } else if(parsed[i][0] === "v"){
2973
- length = length + Math.abs(parsed[i][1]);
2974
- functions.push(new LinearPosition(cur[0], cur[0], cur[1], cur[1] + parsed[i][1]));
2975
- cur[1] = parsed[i][1] + cur[1];
2976
- //Close path
2977
- } else if(parsed[i][0] === "z" || parsed[i][0] === "Z"){
2978
- length = length + Math.sqrt(Math.pow(ringStart[0] - cur[0], 2) + Math.pow(ringStart[1] - cur[1], 2));
2979
- functions.push(new LinearPosition(cur[0], ringStart[0], cur[1], ringStart[1]));
2980
- cur = [ringStart[0], ringStart[1]];
2981
- }
2982
- //Cubic Bezier curves
2983
- else if(parsed[i][0] === "C"){
2984
- curve = new Bezier(cur[0], cur[1] , parsed[i][1], parsed[i][2] , parsed[i][3], parsed[i][4] , parsed[i][5], parsed[i][6]);
2985
- length = length + curve.getTotalLength();
2986
- cur = [parsed[i][5], parsed[i][6]];
2987
- functions.push(curve);
2988
- } else if(parsed[i][0] === "c"){
2989
- curve = new Bezier(cur[0], cur[1] , cur[0] + parsed[i][1], cur[1] + parsed[i][2] , cur[0] + parsed[i][3], cur[1] + parsed[i][4] , cur[0] + parsed[i][5], cur[1] + parsed[i][6]);
2990
- length = length + curve.getTotalLength();
2991
- cur = [parsed[i][5] + cur[0], parsed[i][6] + cur[1]];
2992
- functions.push(curve);
2993
- } else if(parsed[i][0] === "S"){
2994
- if(i>0 && ["C","c","S","s"].indexOf(parsed[i-1][0]) > -1){
2995
- curve = new Bezier(cur[0], cur[1] , 2*cur[0] - parsed[i-1][parsed[i-1].length - 4], 2*cur[1] - parsed[i-1][parsed[i-1].length - 3], parsed[i][1], parsed[i][2] , parsed[i][3], parsed[i][4]);
2996
- } else {
2997
- curve = new Bezier(cur[0], cur[1] , cur[0], cur[1], parsed[i][1], parsed[i][2] , parsed[i][3], parsed[i][4]);
2998
- }
2999
- length = length + curve.getTotalLength();
3000
- cur = [parsed[i][3], parsed[i][4]];
3001
- functions.push(curve);
3002
- } else if(parsed[i][0] === "s"){ //240 225
3003
- if(i>0 && ["C","c","S","s"].indexOf(parsed[i-1][0]) > -1){
3004
- curve = new Bezier(cur[0], cur[1] , cur[0] + curve.d.x - curve.c.x, cur[1] + curve.d.y - curve.c.y, cur[0] + parsed[i][1], cur[1] + parsed[i][2] , cur[0] + parsed[i][3], cur[1] + parsed[i][4]);
3005
- } else {
3006
- curve = new Bezier(cur[0], cur[1] , cur[0], cur[1], cur[0] + parsed[i][1], cur[1] + parsed[i][2] , cur[0] + parsed[i][3], cur[1] + parsed[i][4]);
3007
- }
3008
- length = length + curve.getTotalLength();
3009
- cur = [parsed[i][3] + cur[0], parsed[i][4] + cur[1]];
3010
- functions.push(curve);
3011
- }
3012
- //Quadratic Bezier curves
3013
- else if(parsed[i][0] === "Q"){
3014
- if(cur[0] != parsed[i][1] && cur[1] != parsed[i][2]){
3015
- curve = new Bezier(cur[0], cur[1] , parsed[i][1], parsed[i][2] , parsed[i][3], parsed[i][4]);
3016
- } else {
3017
- curve = new LinearPosition(parsed[i][1], parsed[i][3], parsed[i][2], parsed[i][4]);
3018
- }
3019
- length = length + curve.getTotalLength();
3020
- functions.push(curve);
3021
- cur = [parsed[i][3], parsed[i][4]];
3022
- prev_point = [parsed[i][1], parsed[i][2]];
3023
-
3024
- } else if(parsed[i][0] === "q"){
3025
- if(!(parsed[i][1] == 0 && parsed[i][2] == 0)){
3026
- curve = new Bezier(cur[0], cur[1] , cur[0] + parsed[i][1], cur[1] + parsed[i][2] , cur[0] + parsed[i][3], cur[1] + parsed[i][4]);
3027
- } else {
3028
- curve = new LinearPosition(cur[0] + parsed[i][1], cur[0] + parsed[i][3], cur[1] + parsed[i][2], cur[1] + parsed[i][4]);
3029
- }
3030
- length = length + curve.getTotalLength();
3031
- prev_point = [cur[0] + parsed[i][1], cur[1] + parsed[i][2]];
3032
- cur = [parsed[i][3] + cur[0], parsed[i][4] + cur[1]];
3033
- functions.push(curve);
3034
- } else if(parsed[i][0] === "T"){
3035
- if(i>0 && ["Q","q","T","t"].indexOf(parsed[i-1][0]) > -1){
3036
- curve = new Bezier(cur[0], cur[1] , 2 * cur[0] - prev_point[0] , 2 * cur[1] - prev_point[1] , parsed[i][1], parsed[i][2]);
3037
- } else {
3038
- curve = new LinearPosition(cur[0], parsed[i][1], cur[1], parsed[i][2]);
3039
- }
3040
- functions.push(curve);
3041
- length = length + curve.getTotalLength();
3042
- prev_point = [2 * cur[0] - prev_point[0] , 2 * cur[1] - prev_point[1]];
3043
- cur = [parsed[i][1], parsed[i][2]];
3044
-
3045
- } else if(parsed[i][0] === "t"){
3046
- if(i>0 && ["Q","q","T","t"].indexOf(parsed[i-1][0]) > -1){
3047
- curve = new Bezier(cur[0], cur[1] , 2 * cur[0] - prev_point[0] , 2 * cur[1] - prev_point[1] , cur[0] + parsed[i][1], cur[1] + parsed[i][2]);
3048
- } else {
3049
- curve = new LinearPosition(cur[0], cur[0] + parsed[i][1], cur[1], cur[1] + parsed[i][2]);
3050
- }
3051
- length = length + curve.getTotalLength();
3052
- prev_point = [2 * cur[0] - prev_point[0] , 2 * cur[1] - prev_point[1]];
3053
- cur = [parsed[i][1] + cur[0], parsed[i][2] + cur[0]];
3054
- functions.push(curve);
3055
- } else if(parsed[i][0] === "A"){
3056
- curve = new Arc(cur[0], cur[1], parsed[i][1], parsed[i][2], parsed[i][3], parsed[i][4], parsed[i][5], parsed[i][6], parsed[i][7]);
3057
-
3058
- length = length + curve.getTotalLength();
3059
- cur = [parsed[i][6], parsed[i][7]];
3060
- functions.push(curve);
3061
- } else if(parsed[i][0] === "a"){
3062
- curve = new Arc(cur[0], cur[1], parsed[i][1], parsed[i][2], parsed[i][3], parsed[i][4], parsed[i][5], cur[0] + parsed[i][6], cur[1] + parsed[i][7]);
3063
-
3064
- length = length + curve.getTotalLength();
3065
- cur = [cur[0] + parsed[i][6], cur[1] + parsed[i][7]];
3066
- functions.push(curve);
3067
- }
3068
- partial_lengths.push(length);
3069
-
3070
- }
3071
- return svgProperties;
3072
- }
3073
-
3074
- svgProperties.getTotalLength = function(){
3075
- return length;
3076
- };
3077
-
3078
- svgProperties.getPointAtLength = function(fractionLength){
3079
- var fractionPart = getPartAtLength(fractionLength);
3080
- return functions[fractionPart.i].getPointAtLength(fractionPart.fraction);
3081
- };
3082
-
3083
- svgProperties.getTangentAtLength = function(fractionLength){
3084
- var fractionPart = getPartAtLength(fractionLength);
3085
- return functions[fractionPart.i].getTangentAtLength(fractionPart.fraction);
3086
- };
3087
-
3088
- svgProperties.getPropertiesAtLength = function(fractionLength){
3089
- var fractionPart = getPartAtLength(fractionLength);
3090
- return functions[fractionPart.i].getPropertiesAtLength(fractionPart.fraction);
3091
- };
3092
-
3093
- var getPartAtLength = function(fractionLength){
3094
- if(fractionLength < 0){
3095
- fractionLength = 0;
3096
- } else if(fractionLength > length){
3097
- fractionLength = length;
3098
- }
3099
-
3100
- var i = partial_lengths.length - 1;
3101
-
3102
- while(partial_lengths[i] >= fractionLength && partial_lengths[i] > 0){
3103
- i--;
3104
- }
3105
- i++;
3106
- return {fraction: fractionLength-partial_lengths[i-1], i: i};
3107
- };
3108
-
3109
- return svgProperties(svgString);
3110
- }
3111
-
3112
- function distance(a, b) {
3113
- return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
3114
- }
3115
-
3116
- function pointAlong(a, b, pct) {
3117
- return [a[0] + (b[0] - a[0]) * pct, a[1] + (b[1] - a[1]) * pct];
3118
- }
3119
-
3120
- function samePoint(a, b) {
3121
- return distance(a, b) < 1e-9;
3122
- }
3123
-
3124
- function interpolatePoints(a, b, string) {
3125
- let interpolators = a.map((d, i) => interpolatePoint(d, b[i]));
3126
-
3127
- return function(t) {
3128
- let values = interpolators.map(fn => fn(t));
3129
- return string ? toPathString(values) : values;
3130
- };
3131
- }
3132
-
3133
- function interpolatePoint(a, b) {
3134
- return function(t) {
3135
- return a.map((d, i) => d + t * (b[i] - d));
3136
- };
3137
- }
3138
-
3139
- function isFiniteNumber(number) {
3140
- return typeof number === "number" && isFinite(number);
3141
- }
3142
-
3143
- const INVALID_INPUT = `All shapes must be supplied as arrays of [x, y] points or an SVG path string (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d).
3144
- Example valid ways of supplying a shape would be:
3145
- [[0, 0], [10, 0], [10, 10]]
3146
- "M0,0 L10,0 L10,10Z"
3147
- `;
3148
-
3149
- function parse(str) {
3150
- return new Path(str).abs();
3151
- }
3152
-
3153
- function split(parsed) {
3154
- return parsed
3155
- .toString()
3156
- .split("M")
3157
- .map((d, i) => {
3158
- d = d.trim();
3159
- return i && d ? "M" + d : d;
3160
- })
3161
- .filter(d => d);
3162
- }
3163
-
3164
- function toPathString(ring) {
3165
- return "M" + ring.join("L") + "Z";
3166
- }
3167
-
3168
- function pathStringToRing(str, maxSegmentLength) {
3169
- let parsed = parse(str);
3170
-
3171
- return exactRing(parsed) || approximateRing(parsed, maxSegmentLength);
3172
- }
3173
-
3174
- function exactRing(parsed) {
3175
- let segments = parsed.segments || [],
3176
- ring = [];
3177
-
3178
- if (!segments.length || segments[0][0] !== "M") {
3179
- return false;
3180
- }
3181
-
3182
- for (let i = 0; i < segments.length; i++) {
3183
- let [command, x, y] = segments[i];
3184
- if ((command === "M" && i) || command === "Z") {
3185
- break;
3186
- } else if (command === "M" || command === "L") {
3187
- ring.push([x, y]);
3188
- } else if (command === "H") {
3189
- ring.push([x, ring[ring.length - 1][1]]);
3190
- } else if (command === "V") {
3191
- ring.push([ring[ring.length - 1][0], x]);
3192
- } else {
3193
- return false;
3194
- }
3195
- }
3196
-
3197
- return ring.length ? { ring } : false;
3198
- }
3199
-
3200
- function approximateRing(parsed, maxSegmentLength) {
3201
- let ringPath = split(parsed)[0],
3202
- ring = [],
3203
- len,
3204
- m,
3205
- numPoints = 3;
3206
-
3207
- if (!ringPath) {
3208
- throw new TypeError(INVALID_INPUT);
3209
- }
3210
-
3211
- m = measure(ringPath);
3212
- len = m.getTotalLength();
3213
-
3214
- if (maxSegmentLength && isFiniteNumber(maxSegmentLength) && maxSegmentLength > 0) {
3215
- numPoints = Math.max(numPoints, Math.ceil(len / maxSegmentLength));
3216
- }
3217
-
3218
- for (let i = 0; i < numPoints; i++) {
3219
- let p = m.getPointAtLength(len * i / numPoints);
3220
- ring.push([p.x, p.y]);
3221
- }
3222
-
3223
- return {
3224
- ring,
3225
- skipBisect: true
3226
- };
3227
- }
3228
-
3229
- function measure(d) {
3230
- // Use native browser measurement if running in browser
3231
- if (typeof window !== "undefined" && window && window.document) {
3232
- try {
3233
- let path = window.document.createElementNS("http://www.w3.org/2000/svg", "path");
3234
- path.setAttributeNS(null, "d", d);
3235
- return path;
3236
- } catch (e) {}
3237
- }
3238
- // Fall back to svg-path-properties
3239
- return svgPathProperties(d);
3240
- }
3241
-
3242
- function addPoints(ring, numPoints) {
3243
- const desiredLength = ring.length + numPoints,
3244
- step = polygonLength(ring) / numPoints;
3245
-
3246
- let i = 0,
3247
- cursor = 0,
3248
- insertAt = step / 2;
3249
-
3250
- while (ring.length < desiredLength) {
3251
- let a = ring[i],
3252
- b = ring[(i + 1) % ring.length],
3253
- segment = distance(a, b);
3254
-
3255
- if (insertAt <= cursor + segment) {
3256
- ring.splice(i + 1, 0, segment ? pointAlong(a, b, (insertAt - cursor) / segment) : a.slice(0));
3257
- insertAt += step;
3258
- continue;
3259
- }
3260
-
3261
- cursor += segment;
3262
- i++;
3263
- }
3264
- }
3265
-
3266
- function bisect(ring, maxSegmentLength = Infinity) {
3267
- for (let i = 0; i < ring.length; i++) {
3268
- let a = ring[i],
3269
- b = i === ring.length - 1 ? ring[0] : ring[i + 1];
3270
-
3271
- // Could splice the whole set for a segment instead, but a bit messy
3272
- while (distance(a, b) > maxSegmentLength) {
3273
- b = pointAlong(a, b, 0.5);
3274
- ring.splice(i + 1, 0, b);
3275
- }
3276
- }
3277
- }
3278
-
3279
- function normalizeRing(ring, maxSegmentLength) {
3280
- let points, area, skipBisect;
3281
-
3282
- if (typeof ring === "string") {
3283
- let converted = pathStringToRing(ring, maxSegmentLength);
3284
- ring = converted.ring;
3285
- skipBisect = converted.skipBisect;
3286
- } else if (!Array.isArray(ring)) {
3287
- throw new TypeError(INVALID_INPUT);
3288
- }
3289
-
3290
- points = ring.slice(0);
3291
-
3292
- if (!validRing(points)) {
3293
- throw new TypeError(INVALID_INPUT);
3294
- }
3295
-
3296
- // TODO skip this test to avoid scale issues?
3297
- // Chosen epsilon (1e-6) is problematic for small coordinate range
3298
- if (points.length > 1 && samePoint(points[0], points[points.length - 1])) {
3299
- points.pop();
3300
- }
3301
-
3302
- area = polygonArea(points);
3303
-
3304
- // Make all rings clockwise
3305
- if (area > 0) {
3306
- points.reverse();
3307
- }
3308
-
3309
- if (
3310
- !skipBisect &&
3311
- maxSegmentLength &&
3312
- isFiniteNumber(maxSegmentLength) &&
3313
- maxSegmentLength > 0
3314
- ) {
3315
- bisect(points, maxSegmentLength);
3316
- }
3317
-
3318
- return points;
3319
- }
3320
-
3321
- function validRing(ring) {
3322
- return ring.every(function(point) {
3323
- return (
3324
- Array.isArray(point) &&
3325
- point.length >= 2 &&
3326
- isFiniteNumber(point[0]) &&
3327
- isFiniteNumber(point[1])
3328
- );
3329
- });
3330
- }
3331
-
3332
- function rotate(ring, vs) {
3333
- let len = ring.length,
3334
- min = Infinity,
3335
- bestOffset,
3336
- sumOfSquares,
3337
- spliced;
3338
-
3339
- for (let offset = 0; offset < len; offset++) {
3340
- sumOfSquares = 0;
3341
-
3342
- vs.forEach(function(p, i){
3343
- let d = distance(ring[(offset + i) % len], p);
3344
- sumOfSquares += d * d;
3345
- });
3346
-
3347
- if (sumOfSquares < min) {
3348
- min = sumOfSquares;
3349
- bestOffset = offset;
3350
- }
3351
- }
3352
-
3353
- if (bestOffset) {
3354
- spliced = ring.splice(0, bestOffset);
3355
- ring.splice(ring.length, 0, ...spliced);
3356
- }
3357
- }
3358
-
3359
- function interpolate(fromShape, toShape, { maxSegmentLength = 10, string = true } = {}) {
3360
- let fromRing = normalizeRing(fromShape, maxSegmentLength),
3361
- toRing = normalizeRing(toShape, maxSegmentLength),
3362
- interpolator = interpolateRing(fromRing, toRing, string);
3363
-
3364
- // Extra optimization for near either end with path strings
3365
- if (!string || (typeof fromShape !== "string" && typeof toShape !== "string")) {
3366
- return interpolator;
3367
- }
3368
-
3369
- return t => {
3370
- if (t < 1e-4 && typeof fromShape === "string") {
3371
- return fromShape;
3372
- }
3373
- if (1 - t < 1e-4 && typeof toShape === "string") {
3374
- return toShape;
3375
- }
3376
- return interpolator(t);
3377
- };
3378
- }
3379
-
3380
- function interpolateRing(fromRing, toRing, string) {
3381
- let diff;
3382
-
3383
- diff = fromRing.length - toRing.length;
3384
-
3385
- // TODO bisect and add points in one step?
3386
- addPoints(fromRing, diff < 0 ? diff * -1 : 0);
3387
- addPoints(toRing, diff > 0 ? diff : 0);
3388
-
3389
- rotate(fromRing, toRing);
3390
-
3391
- return interpolatePoints(fromRing, toRing, string);
3392
- }
3393
-
3394
- var earcut = {exports: {}};
3395
-
3396
- var hasRequiredEarcut;
3397
-
3398
- function requireEarcut () {
3399
- if (hasRequiredEarcut) return earcut.exports;
3400
- hasRequiredEarcut = 1;
3401
-
3402
- earcut.exports = earcut$1;
3403
- earcut.exports.default = earcut$1;
3404
-
3405
- function earcut$1(data, holeIndices, dim) {
3406
-
3407
- dim = dim || 2;
3408
-
3409
- var hasHoles = holeIndices && holeIndices.length,
3410
- outerLen = hasHoles ? holeIndices[0] * dim : data.length,
3411
- outerNode = linkedList(data, 0, outerLen, dim, true),
3412
- triangles = [];
3413
-
3414
- if (!outerNode || outerNode.next === outerNode.prev) return triangles;
3415
-
3416
- var minX, minY, maxX, maxY, x, y, invSize;
3417
-
3418
- if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
3419
-
3420
- // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
3421
- if (data.length > 80 * dim) {
3422
- minX = maxX = data[0];
3423
- minY = maxY = data[1];
3424
-
3425
- for (var i = dim; i < outerLen; i += dim) {
3426
- x = data[i];
3427
- y = data[i + 1];
3428
- if (x < minX) minX = x;
3429
- if (y < minY) minY = y;
3430
- if (x > maxX) maxX = x;
3431
- if (y > maxY) maxY = y;
3432
- }
3433
-
3434
- // minX, minY and invSize are later used to transform coords into integers for z-order calculation
3435
- invSize = Math.max(maxX - minX, maxY - minY);
3436
- invSize = invSize !== 0 ? 32767 / invSize : 0;
3437
- }
3438
-
3439
- earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
3440
-
3441
- return triangles;
3442
- }
3443
-
3444
- // create a circular doubly linked list from polygon points in the specified winding order
3445
- function linkedList(data, start, end, dim, clockwise) {
3446
- var i, last;
3447
-
3448
- if (clockwise === (signedArea(data, start, end, dim) > 0)) {
3449
- for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
3450
- } else {
3451
- for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
3452
- }
3453
-
3454
- if (last && equals(last, last.next)) {
3455
- removeNode(last);
3456
- last = last.next;
3457
- }
3458
-
3459
- return last;
3460
- }
3461
-
3462
- // eliminate colinear or duplicate points
3463
- function filterPoints(start, end) {
3464
- if (!start) return start;
3465
- if (!end) end = start;
3466
-
3467
- var p = start,
3468
- again;
3469
- do {
3470
- again = false;
3471
-
3472
- if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
3473
- removeNode(p);
3474
- p = end = p.prev;
3475
- if (p === p.next) break;
3476
- again = true;
3477
-
3478
- } else {
3479
- p = p.next;
3480
- }
3481
- } while (again || p !== end);
3482
-
3483
- return end;
3484
- }
3485
-
3486
- // main ear slicing loop which triangulates a polygon (given as a linked list)
3487
- function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
3488
- if (!ear) return;
3489
-
3490
- // interlink polygon nodes in z-order
3491
- if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
3492
-
3493
- var stop = ear,
3494
- prev, next;
3495
-
3496
- // iterate through ears, slicing them one by one
3497
- while (ear.prev !== ear.next) {
3498
- prev = ear.prev;
3499
- next = ear.next;
3500
-
3501
- if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
3502
- // cut off the triangle
3503
- triangles.push(prev.i / dim | 0);
3504
- triangles.push(ear.i / dim | 0);
3505
- triangles.push(next.i / dim | 0);
3506
-
3507
- removeNode(ear);
3508
-
3509
- // skipping the next vertex leads to less sliver triangles
3510
- ear = next.next;
3511
- stop = next.next;
3512
-
3513
- continue;
3514
- }
3515
-
3516
- ear = next;
3517
-
3518
- // if we looped through the whole remaining polygon and can't find any more ears
3519
- if (ear === stop) {
3520
- // try filtering points and slicing again
3521
- if (!pass) {
3522
- earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
3523
-
3524
- // if this didn't work, try curing all small self-intersections locally
3525
- } else if (pass === 1) {
3526
- ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
3527
- earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
3528
-
3529
- // as a last resort, try splitting the remaining polygon into two
3530
- } else if (pass === 2) {
3531
- splitEarcut(ear, triangles, dim, minX, minY, invSize);
3532
- }
3533
-
3534
- break;
3535
- }
3536
- }
3537
- }
3538
-
3539
- // check whether a polygon node forms a valid ear with adjacent nodes
3540
- function isEar(ear) {
3541
- var a = ear.prev,
3542
- b = ear,
3543
- c = ear.next;
3544
-
3545
- if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
3546
-
3547
- // now make sure we don't have other points inside the potential ear
3548
- var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
3549
-
3550
- // triangle bbox; min & max are calculated like this for speed
3551
- var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
3552
- y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
3553
- x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
3554
- y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
3555
-
3556
- var p = c.next;
3557
- while (p !== a) {
3558
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&
3559
- pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) &&
3560
- area(p.prev, p, p.next) >= 0) return false;
3561
- p = p.next;
3562
- }
3563
-
3564
- return true;
3565
- }
3566
-
3567
- function isEarHashed(ear, minX, minY, invSize) {
3568
- var a = ear.prev,
3569
- b = ear,
3570
- c = ear.next;
3571
-
3572
- if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
3573
-
3574
- var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
3575
-
3576
- // triangle bbox; min & max are calculated like this for speed
3577
- var x0 = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx),
3578
- y0 = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy),
3579
- x1 = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx),
3580
- y1 = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
3581
-
3582
- // z-order range for the current triangle bbox;
3583
- var minZ = zOrder(x0, y0, minX, minY, invSize),
3584
- maxZ = zOrder(x1, y1, minX, minY, invSize);
3585
-
3586
- var p = ear.prevZ,
3587
- n = ear.nextZ;
3588
-
3589
- // look for points inside the triangle in both directions
3590
- while (p && p.z >= minZ && n && n.z <= maxZ) {
3591
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
3592
- pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
3593
- p = p.prevZ;
3594
-
3595
- if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
3596
- pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
3597
- n = n.nextZ;
3598
- }
3599
-
3600
- // look for remaining points in decreasing z-order
3601
- while (p && p.z >= minZ) {
3602
- if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
3603
- pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
3604
- p = p.prevZ;
3605
- }
3606
-
3607
- // look for remaining points in increasing z-order
3608
- while (n && n.z <= maxZ) {
3609
- if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
3610
- pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
3611
- n = n.nextZ;
3612
- }
3613
-
3614
- return true;
3615
- }
3616
-
3617
- // go through all polygon nodes and cure small local self-intersections
3618
- function cureLocalIntersections(start, triangles, dim) {
3619
- var p = start;
3620
- do {
3621
- var a = p.prev,
3622
- b = p.next.next;
3623
-
3624
- if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
3625
-
3626
- triangles.push(a.i / dim | 0);
3627
- triangles.push(p.i / dim | 0);
3628
- triangles.push(b.i / dim | 0);
3629
-
3630
- // remove two nodes involved
3631
- removeNode(p);
3632
- removeNode(p.next);
3633
-
3634
- p = start = b;
3635
- }
3636
- p = p.next;
3637
- } while (p !== start);
3638
-
3639
- return filterPoints(p);
3640
- }
3641
-
3642
- // try splitting polygon into two and triangulate them independently
3643
- function splitEarcut(start, triangles, dim, minX, minY, invSize) {
3644
- // look for a valid diagonal that divides the polygon into two
3645
- var a = start;
3646
- do {
3647
- var b = a.next.next;
3648
- while (b !== a.prev) {
3649
- if (a.i !== b.i && isValidDiagonal(a, b)) {
3650
- // split the polygon in two by the diagonal
3651
- var c = splitPolygon(a, b);
3652
-
3653
- // filter colinear points around the cuts
3654
- a = filterPoints(a, a.next);
3655
- c = filterPoints(c, c.next);
3656
-
3657
- // run earcut on each half
3658
- earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
3659
- earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
3660
- return;
3661
- }
3662
- b = b.next;
3663
- }
3664
- a = a.next;
3665
- } while (a !== start);
3666
- }
3667
-
3668
- // link every hole into the outer loop, producing a single-ring polygon without holes
3669
- function eliminateHoles(data, holeIndices, outerNode, dim) {
3670
- var queue = [],
3671
- i, len, start, end, list;
3672
-
3673
- for (i = 0, len = holeIndices.length; i < len; i++) {
3674
- start = holeIndices[i] * dim;
3675
- end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
3676
- list = linkedList(data, start, end, dim, false);
3677
- if (list === list.next) list.steiner = true;
3678
- queue.push(getLeftmost(list));
3679
- }
3680
-
3681
- queue.sort(compareX);
3682
-
3683
- // process holes from left to right
3684
- for (i = 0; i < queue.length; i++) {
3685
- outerNode = eliminateHole(queue[i], outerNode);
3686
- }
3687
-
3688
- return outerNode;
3689
- }
3690
-
3691
- function compareX(a, b) {
3692
- return a.x - b.x;
3693
- }
3694
-
3695
- // find a bridge between vertices that connects hole with an outer ring and and link it
3696
- function eliminateHole(hole, outerNode) {
3697
- var bridge = findHoleBridge(hole, outerNode);
3698
- if (!bridge) {
3699
- return outerNode;
3700
- }
3701
-
3702
- var bridgeReverse = splitPolygon(bridge, hole);
3703
-
3704
- // filter collinear points around the cuts
3705
- filterPoints(bridgeReverse, bridgeReverse.next);
3706
- return filterPoints(bridge, bridge.next);
3707
- }
3708
-
3709
- // David Eberly's algorithm for finding a bridge between hole and outer polygon
3710
- function findHoleBridge(hole, outerNode) {
3711
- var p = outerNode,
3712
- hx = hole.x,
3713
- hy = hole.y,
3714
- qx = -Infinity,
3715
- m;
3716
-
3717
- // find a segment intersected by a ray from the hole's leftmost point to the left;
3718
- // segment's endpoint with lesser x will be potential connection point
3719
- do {
3720
- if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
3721
- var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
3722
- if (x <= hx && x > qx) {
3723
- qx = x;
3724
- m = p.x < p.next.x ? p : p.next;
3725
- if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint
3726
- }
3727
- }
3728
- p = p.next;
3729
- } while (p !== outerNode);
3730
-
3731
- if (!m) return null;
3732
-
3733
- // look for points inside the triangle of hole point, segment intersection and endpoint;
3734
- // if there are no points found, we have a valid connection;
3735
- // otherwise choose the point of the minimum angle with the ray as connection point
3736
-
3737
- var stop = m,
3738
- mx = m.x,
3739
- my = m.y,
3740
- tanMin = Infinity,
3741
- tan;
3742
-
3743
- p = m;
3744
-
3745
- do {
3746
- if (hx >= p.x && p.x >= mx && hx !== p.x &&
3747
- pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
3748
-
3749
- tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
3750
-
3751
- if (locallyInside(p, hole) &&
3752
- (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {
3753
- m = p;
3754
- tanMin = tan;
3755
- }
3756
- }
3757
-
3758
- p = p.next;
3759
- } while (p !== stop);
3760
-
3761
- return m;
3762
- }
3763
-
3764
- // whether sector in vertex m contains sector in vertex p in the same coordinates
3765
- function sectorContainsSector(m, p) {
3766
- return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
3767
- }
3768
-
3769
- // interlink polygon nodes in z-order
3770
- function indexCurve(start, minX, minY, invSize) {
3771
- var p = start;
3772
- do {
3773
- if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
3774
- p.prevZ = p.prev;
3775
- p.nextZ = p.next;
3776
- p = p.next;
3777
- } while (p !== start);
3778
-
3779
- p.prevZ.nextZ = null;
3780
- p.prevZ = null;
3781
-
3782
- sortLinked(p);
3783
- }
3784
-
3785
- // Simon Tatham's linked list merge sort algorithm
3786
- // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
3787
- function sortLinked(list) {
3788
- var i, p, q, e, tail, numMerges, pSize, qSize,
3789
- inSize = 1;
3790
-
3791
- do {
3792
- p = list;
3793
- list = null;
3794
- tail = null;
3795
- numMerges = 0;
3796
-
3797
- while (p) {
3798
- numMerges++;
3799
- q = p;
3800
- pSize = 0;
3801
- for (i = 0; i < inSize; i++) {
3802
- pSize++;
3803
- q = q.nextZ;
3804
- if (!q) break;
3805
- }
3806
- qSize = inSize;
3807
-
3808
- while (pSize > 0 || (qSize > 0 && q)) {
3809
-
3810
- if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
3811
- e = p;
3812
- p = p.nextZ;
3813
- pSize--;
3814
- } else {
3815
- e = q;
3816
- q = q.nextZ;
3817
- qSize--;
3818
- }
3819
-
3820
- if (tail) tail.nextZ = e;
3821
- else list = e;
3822
-
3823
- e.prevZ = tail;
3824
- tail = e;
3825
- }
3826
-
3827
- p = q;
3828
- }
3829
-
3830
- tail.nextZ = null;
3831
- inSize *= 2;
3832
-
3833
- } while (numMerges > 1);
3834
-
3835
- return list;
3836
- }
3837
-
3838
- // z-order of a point given coords and inverse of the longer side of data bbox
3839
- function zOrder(x, y, minX, minY, invSize) {
3840
- // coords are transformed into non-negative 15-bit integer range
3841
- x = (x - minX) * invSize | 0;
3842
- y = (y - minY) * invSize | 0;
3843
-
3844
- x = (x | (x << 8)) & 0x00FF00FF;
3845
- x = (x | (x << 4)) & 0x0F0F0F0F;
3846
- x = (x | (x << 2)) & 0x33333333;
3847
- x = (x | (x << 1)) & 0x55555555;
3848
-
3849
- y = (y | (y << 8)) & 0x00FF00FF;
3850
- y = (y | (y << 4)) & 0x0F0F0F0F;
3851
- y = (y | (y << 2)) & 0x33333333;
3852
- y = (y | (y << 1)) & 0x55555555;
3853
-
3854
- return x | (y << 1);
3855
- }
3856
-
3857
- // find the leftmost node of a polygon ring
3858
- function getLeftmost(start) {
3859
- var p = start,
3860
- leftmost = start;
3861
- do {
3862
- if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;
3863
- p = p.next;
3864
- } while (p !== start);
3865
-
3866
- return leftmost;
3867
- }
3868
-
3869
- // check if a point lies within a convex triangle
3870
- function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
3871
- return (cx - px) * (ay - py) >= (ax - px) * (cy - py) &&
3872
- (ax - px) * (by - py) >= (bx - px) * (ay - py) &&
3873
- (bx - px) * (cy - py) >= (cx - px) * (by - py);
3874
- }
3875
-
3876
- // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
3877
- function isValidDiagonal(a, b) {
3878
- return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
3879
- (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
3880
- (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
3881
- equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
3882
- }
3883
-
3884
- // signed area of a triangle
3885
- function area(p, q, r) {
3886
- return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
3887
- }
3888
-
3889
- // check if two points are equal
3890
- function equals(p1, p2) {
3891
- return p1.x === p2.x && p1.y === p2.y;
3892
- }
3893
-
3894
- // check if two segments intersect
3895
- function intersects(p1, q1, p2, q2) {
3896
- var o1 = sign(area(p1, q1, p2));
3897
- var o2 = sign(area(p1, q1, q2));
3898
- var o3 = sign(area(p2, q2, p1));
3899
- var o4 = sign(area(p2, q2, q1));
3900
-
3901
- if (o1 !== o2 && o3 !== o4) return true; // general case
3902
-
3903
- if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
3904
- if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
3905
- if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
3906
- if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
3907
-
3908
- return false;
3909
- }
3910
-
3911
- // for collinear points p, q, r, check if point q lies on segment pr
3912
- function onSegment(p, q, r) {
3913
- return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
3914
- }
3915
-
3916
- function sign(num) {
3917
- return num > 0 ? 1 : num < 0 ? -1 : 0;
3918
- }
3919
-
3920
- // check if a polygon diagonal intersects any polygon segments
3921
- function intersectsPolygon(a, b) {
3922
- var p = a;
3923
- do {
3924
- if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
3925
- intersects(p, p.next, a, b)) return true;
3926
- p = p.next;
3927
- } while (p !== a);
3928
-
3929
- return false;
3930
- }
3931
-
3932
- // check if a polygon diagonal is locally inside the polygon
3933
- function locallyInside(a, b) {
3934
- return area(a.prev, a, a.next) < 0 ?
3935
- area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :
3936
- area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
3937
- }
3938
-
3939
- // check if the middle point of a polygon diagonal is inside the polygon
3940
- function middleInside(a, b) {
3941
- var p = a,
3942
- inside = false,
3943
- px = (a.x + b.x) / 2,
3944
- py = (a.y + b.y) / 2;
3945
- do {
3946
- if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&
3947
- (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))
3948
- inside = !inside;
3949
- p = p.next;
3950
- } while (p !== a);
3951
-
3952
- return inside;
3953
- }
3954
-
3955
- // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
3956
- // if one belongs to the outer ring and another to a hole, it merges it into a single ring
3957
- function splitPolygon(a, b) {
3958
- var a2 = new Node(a.i, a.x, a.y),
3959
- b2 = new Node(b.i, b.x, b.y),
3960
- an = a.next,
3961
- bp = b.prev;
3962
-
3963
- a.next = b;
3964
- b.prev = a;
3965
-
3966
- a2.next = an;
3967
- an.prev = a2;
3968
-
3969
- b2.next = a2;
3970
- a2.prev = b2;
3971
-
3972
- bp.next = b2;
3973
- b2.prev = bp;
3974
-
3975
- return b2;
3976
- }
3977
-
3978
- // create a node and optionally link it with previous one (in a circular doubly linked list)
3979
- function insertNode(i, x, y, last) {
3980
- var p = new Node(i, x, y);
3981
-
3982
- if (!last) {
3983
- p.prev = p;
3984
- p.next = p;
3985
-
3986
- } else {
3987
- p.next = last.next;
3988
- p.prev = last;
3989
- last.next.prev = p;
3990
- last.next = p;
3991
- }
3992
- return p;
3993
- }
3994
-
3995
- function removeNode(p) {
3996
- p.next.prev = p.prev;
3997
- p.prev.next = p.next;
3998
-
3999
- if (p.prevZ) p.prevZ.nextZ = p.nextZ;
4000
- if (p.nextZ) p.nextZ.prevZ = p.prevZ;
4001
- }
4002
-
4003
- function Node(i, x, y) {
4004
- // vertex index in coordinates array
4005
- this.i = i;
4006
-
4007
- // vertex coordinates
4008
- this.x = x;
4009
- this.y = y;
4010
-
4011
- // previous and next vertex nodes in a polygon ring
4012
- this.prev = null;
4013
- this.next = null;
4014
-
4015
- // z-order curve value
4016
- this.z = 0;
4017
-
4018
- // previous and next nodes in z-order
4019
- this.prevZ = null;
4020
- this.nextZ = null;
4021
-
4022
- // indicates whether this is a steiner point
4023
- this.steiner = false;
4024
- }
4025
-
4026
- // return a percentage difference between the polygon area and its triangulation area;
4027
- // used to verify correctness of triangulation
4028
- earcut$1.deviation = function (data, holeIndices, dim, triangles) {
4029
- var hasHoles = holeIndices && holeIndices.length;
4030
- var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
4031
-
4032
- var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
4033
- if (hasHoles) {
4034
- for (var i = 0, len = holeIndices.length; i < len; i++) {
4035
- var start = holeIndices[i] * dim;
4036
- var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
4037
- polygonArea -= Math.abs(signedArea(data, start, end, dim));
4038
- }
4039
- }
4040
-
4041
- var trianglesArea = 0;
4042
- for (i = 0; i < triangles.length; i += 3) {
4043
- var a = triangles[i] * dim;
4044
- var b = triangles[i + 1] * dim;
4045
- var c = triangles[i + 2] * dim;
4046
- trianglesArea += Math.abs(
4047
- (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -
4048
- (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
4049
- }
4050
-
4051
- return polygonArea === 0 && trianglesArea === 0 ? 0 :
4052
- Math.abs((trianglesArea - polygonArea) / polygonArea);
4053
- };
4054
-
4055
- function signedArea(data, start, end, dim) {
4056
- var sum = 0;
4057
- for (var i = start, j = end - dim; i < end; i += dim) {
4058
- sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
4059
- j = i;
4060
- }
4061
- return sum;
4062
- }
4063
-
4064
- // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
4065
- earcut$1.flatten = function (data) {
4066
- var dim = data[0][0].length,
4067
- result = {vertices: [], holes: [], dimensions: dim},
4068
- holeIndex = 0;
4069
-
4070
- for (var i = 0; i < data.length; i++) {
4071
- for (var j = 0; j < data[i].length; j++) {
4072
- for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
4073
- }
4074
- if (i > 0) {
4075
- holeIndex += data[i - 1].length;
4076
- result.holes.push(holeIndex);
4077
- }
4078
- }
4079
- return result;
4080
- };
4081
- return earcut.exports;
4082
- }
4083
-
4084
- requireEarcut();
4085
-
4086
- function ascending(a, b) {
4087
- return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
4088
- }
4089
-
4090
- function bisector(compare) {
4091
- if (compare.length === 1) compare = ascendingComparator(compare);
4092
- return {
4093
- left: function(a, x, lo, hi) {
4094
- if (lo == null) lo = 0;
4095
- if (hi == null) hi = a.length;
4096
- while (lo < hi) {
4097
- var mid = lo + hi >>> 1;
4098
- if (compare(a[mid], x) < 0) lo = mid + 1;
4099
- else hi = mid;
4100
- }
4101
- return lo;
4102
- },
4103
- right: function(a, x, lo, hi) {
4104
- if (lo == null) lo = 0;
4105
- if (hi == null) hi = a.length;
4106
- while (lo < hi) {
4107
- var mid = lo + hi >>> 1;
4108
- if (compare(a[mid], x) > 0) hi = mid;
4109
- else lo = mid + 1;
4110
- }
4111
- return lo;
4112
- }
4113
- };
4114
- }
4115
-
4116
- function ascendingComparator(f) {
4117
- return function(d, x) {
4118
- return ascending(f(d), x);
4119
- };
4120
- }
4121
-
4122
- bisector(ascending);
4123
-
4124
- const SHARP_PATH = "m23 12-8.036-3.23L12.006 0 9.047 8.77 1 12l8.047 3.23L12.006 24l2.958-8.77z";
4125
- const ROUND_PATH = "M17.425 13.854c1.665-.675 1.665-3.033 0-3.708l-2.73-1.106-.793-2.37c-.609-1.82-3.184-1.82-3.793 0l-.793 2.37-2.734 1.106c-1.666.674-1.666 3.034 0 3.708l2.734 1.106.793 2.37c.609 1.82 3.184 1.82 3.793 0l.793-2.37z";
4126
- const SVG_STYLE = { width: "100%", height: "100%", display: "block" };
4127
- const GRADIENT_ID = "ai-mark-gradient";
4128
- function SVGMorph({ delay, paths, inheritColor = false }) {
4129
- const [pathIndex, setPathIndex] = useState(0);
4130
- const progress = useMotionValue(0);
4131
- const arrayOfIndex = useMemo(() => paths.map((_, i) => i), [paths]);
4132
- const path = useTransform(progress, arrayOfIndex, paths, {
4133
- mixer: (a, b) => interpolate(a, b, { maxSegmentLength: 1 })
4134
- });
4135
- useEffect(() => {
4136
- const animation = animate(progress, pathIndex, {
4137
- duration: 0.8,
4138
- ease: [0.5, 0, 0.65, 1],
4139
- delay,
4140
- onComplete: () => {
4141
- if (pathIndex === paths.length - 1) {
4142
- progress.set(0);
4143
- setPathIndex(1);
4144
- } else {
4145
- setPathIndex(pathIndex + 1);
4146
- }
4147
- }
4148
- });
4149
- return () => {
4150
- animation.stop();
4151
- };
4152
- }, [pathIndex, paths.length, progress, delay]);
4153
- return /* @__PURE__ */ jsx(
4154
- motion.path,
4155
- {
4156
- fill: inheritColor ? "currentColor" : `url(#${GRADIENT_ID})`,
4157
- d: path
4158
- }
4159
- );
4160
- }
4161
- const AiMarkIconAnimatedSegment = memo(
4162
- ({
4163
- animate: animate2 = false,
4164
- delay,
4165
- className,
4166
- inheritColor = false,
4167
- spin = false
4168
- }) => {
4169
- const fill = inheritColor ? "currentColor" : `url(#${GRADIENT_ID})`;
4170
- const { mode } = useTheme();
4171
- const gradientDef = !inheritColor && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
4172
- "linearGradient",
4173
- {
4174
- id: GRADIENT_ID,
4175
- x1: "0.4962",
4176
- y1: "0.2483",
4177
- x2: "-0.0543",
4178
- y2: "0.4319",
4179
- gradientUnits: "objectBoundingBox",
4180
- children: [
4181
- /* @__PURE__ */ jsx(
4182
- "stop",
4183
- {
4184
- stopColor: mode === "dark" ? "#77C5EA" : "#026EE4",
4185
- style: {
4186
- stopColor: mode === "dark" ? "#77C5EA" : "#026EE4",
4187
- stopOpacity: 1
4188
- }
4189
- }
4190
- ),
4191
- /* @__PURE__ */ jsx(
4192
- "stop",
4193
- {
4194
- offset: "1",
4195
- stopColor: mode === "dark" ? "#D0D8E1" : "#27AEEE",
4196
- style: {
4197
- stopColor: mode === "dark" ? "#D0D8E1" : "#27AEEE",
4198
- stopOpacity: 1
4199
- }
4200
- }
4201
- )
4202
- ]
4203
- }
4204
- ) });
4205
- if (!animate2) {
4206
- return /* @__PURE__ */ jsxs("svg", { className, style: SVG_STYLE, viewBox: "0 0 24 24", children: [
4207
- gradientDef,
4208
- /* @__PURE__ */ jsx("path", { fill, d: SHARP_PATH })
4209
- ] });
4210
- }
4211
- return /* @__PURE__ */ jsxs(
4212
- motion.svg,
4213
- {
4214
- className,
4215
- style: SVG_STYLE,
4216
- viewBox: "0 0 24 24",
4217
- animate: spin ? { rotate: 180 } : {},
4218
- transition: {
4219
- duration: 2,
4220
- type: "spring",
4221
- repeat: 0,
4222
- repeatType: "loop",
4223
- repeatDelay: 1.5,
4224
- delay
4225
- },
4226
- children: [
4227
- gradientDef,
4228
- /* @__PURE__ */ jsx(
4229
- SVGMorph,
4230
- {
4231
- paths: [SHARP_PATH, ROUND_PATH, SHARP_PATH],
4232
- delay,
4233
- inheritColor
4234
- }
4235
- )
4236
- ]
4237
- }
4238
- );
4239
- }
4240
- );
4241
- AiMarkIconAnimatedSegment.displayName = "AiMarkIconAnimatedSegment";
4242
- const AiMarkIconAnimated = ({
4243
- animate: animate2 = false,
4244
- size = 16,
4245
- inheritColor = false,
4246
- spin = false
4247
- }) => {
4248
- const { prefersReducedMotion } = usePrefersReducedMotion();
4249
- const shouldAnimate = animate2 && !prefersReducedMotion;
4250
- const largeSvgSize = size * 0.75;
4251
- const smallSvgSize = size * 6 / 16;
4252
- const containerStyle = useMemo(
4253
- () => ({ position: "relative", width: size, height: size }),
4254
- [size]
4255
- );
4256
- const largeIconStyle = useMemo(
4257
- () => ({
4258
- position: "absolute",
4259
- bottom: size / 16,
4260
- left: size / 16,
4261
- width: largeSvgSize,
4262
- height: largeSvgSize
4263
- }),
4264
- [largeSvgSize, size]
4265
- );
4266
- const smallIconStyle = useMemo(
4267
- () => ({
4268
- position: "absolute",
4269
- top: size / 16,
4270
- right: size / 16,
4271
- width: smallSvgSize,
4272
- height: smallSvgSize
4273
- }),
4274
- [smallSvgSize, size]
4275
- );
4276
- return /* @__PURE__ */ jsxs("div", { style: containerStyle, "data-anv": "ai-mark-icon-animated", children: [
4277
- /* @__PURE__ */ jsx("div", { style: largeIconStyle, children: /* @__PURE__ */ jsx(
4278
- AiMarkIconAnimatedSegment,
4279
- {
4280
- animate: shouldAnimate,
4281
- delay: 0.15,
4282
- inheritColor,
4283
- spin
4284
- }
4285
- ) }),
4286
- /* @__PURE__ */ jsx("div", { style: smallIconStyle, children: /* @__PURE__ */ jsx(
4287
- AiMarkIconAnimatedSegment,
4288
- {
4289
- animate: shouldAnimate,
4290
- inheritColor,
4291
- spin
4292
- }
4293
- ) })
4294
- ] });
4295
- };
4296
-
4297
- const SvgAiChat = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M20.488 7.014A1.51 1.51 0 0 1 22 8.513v8.991a1.51 1.51 0 0 1-1.512 1.499H9.9L6.875 22v-9.975l.757-2.763 6.404-2.248zm-9.831 7.493a.756.756 0 0 0-.757.75c0 .412.34.749.757.749h7.562a.755.755 0 0 0 .756-.75.755.755 0 0 0-.756-.749zm0-2.248a.756.756 0 0 0-.757.75c0 .412.34.749.757.749h7.562a.755.755 0 0 0 .756-.75.755.755 0 0 0-.756-.749zm0-2.248a.756.756 0 0 0-.757.75c0 .412.34.749.757.749h7.562a.755.755 0 0 0 .756-.75.755.755 0 0 0-.756-.749z" }), /* @__PURE__ */ React.createElement("path", { d: "m6.56 5.49 3.811 1.36L6.56 8.213l-1.373 3.776L3.81 8.213 0 6.85l3.81-1.36 1.376-3.778zm3.639-3.607 1.9.685-1.9.687-.692 1.883-.692-1.883-1.901-.687 1.9-.685L9.508 0z" }));
4298
-
4299
- const SvgAiEdit = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M18.655 10.414 7.218 21.844A.5.5 0 0 1 6.85 22H3.666a.52.52 0 0 1-.524-.523V18.29q0-.22.157-.376l11.428-11.43zM6.814 5.756l3.96 1.427-3.96 1.43-1.427 3.958L3.96 8.612 0 7.183l3.959-1.427 1.428-3.96zM18.503 3.14a1.05 1.05 0 0 1 .74.307l2.45 2.45a1.05 1.05 0 0 1 .227 1.14q-.08.19-.227.338l-1.916 1.917-3.928-3.929 1.916-1.916a1.05 1.05 0 0 1 .738-.307m-7.908-1.165 1.975.718-1.975.72-.718 1.975-.72-1.975-1.975-.72 1.975-.718L9.877 0z" }));
4300
-
4301
- const SvgAiForm = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M22 6c1.1 0 2 .9 2 2v14c0 1.1-.9 2-2 2H8c-1.1 0-2-.9-2-2v-9.17c0-.53.21-1.04.59-1.41l4.83-4.83c.37-.38.88-.59 1.41-.59zM11 18c-.55 0-1 .45-1 1s.45 1 1 1h8c.55 0 1-.45 1-1s-.45-1-1-1zm0-4c-.55 0-1 .45-1 1s.45 1 1 1h8c.55 0 1-.45 1-1s-.45-1-1-1zm3-4c-.55 0-1 .45-1 1s.45 1 1 1h5c.55 0 1-.45 1-1s-.45-1-1-1z", clipRule: "evenodd" }), /* @__PURE__ */ React.createElement("path", { d: "m6.505 5.495 3.781 1.363-3.78 1.363L5.142 12 3.78 8.22 0 6.859l3.78-1.363 1.363-3.78zm3.61-3.608L12 2.572l-1.885.686-.687 1.885-.686-1.885-1.885-.686 1.885-.685L9.428 0z" }));
4302
-
4303
- const SvgAiMic = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { d: "M21.513 13.737c.595 0 1.071.554.974 1.17a7.3 7.3 0 0 1-1.958 3.959 6.7 6.7 0 0 1-3.805 1.973v2.134c0 .565-.439 1.027-.975 1.027s-.974-.462-.974-1.027V20.84c-2.945-.441-5.287-2.854-5.765-5.933-.087-.615.381-1.169.976-1.169.232.002.456.09.631.25s.29.38.324.622c.4 2.412 2.4 4.26 4.808 4.26s4.408-1.848 4.808-4.26c.078-.503.479-.872.956-.872" }), /* @__PURE__ */ React.createElement("path", { d: "M15.749 4.5c1.619 0 2.925 1.375 2.925 3.08v6.157c0 1.704-1.306 3.08-2.925 3.08s-2.925-1.376-2.926-3.08V7.58c0-1.703 1.307-3.079 2.926-3.079m-7.743.994 3.78 1.362-3.78 1.364L6.643 12 5.28 8.22 1.5 6.858l3.78-1.362 1.363-3.781zm3.609-3.61 1.885.686-1.885.687-.685 1.885-.688-1.885-1.885-.687 1.885-.686L10.93 0z" }));
4304
-
4305
- const SvgAiSearch = (props) => /* @__PURE__ */ React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", ...props }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M11.757 7.838a6.3 6.3 0 0 1 2.828-.288c2.71.329 4.955 2.476 5.41 5.165a6.28 6.28 0 0 1-1.431 5.165l.27.26h.765l4.104 4.121a1.02 1.02 0 0 1 0 1.442 1.024 1.024 0 0 1-1.443 0l-4.112-4.11v-.765l-.262-.271a6.29 6.29 0 0 1-5.168 1.43c-2.69-.454-4.84-2.698-5.168-5.406a6.29 6.29 0 0 1 4.207-6.743m2.034 1.599a4.35 4.35 0 0 0-4.355 4.352 4.35 4.35 0 0 0 4.355 4.352 4.35 4.35 0 0 0 4.357-4.352 4.35 4.35 0 0 0-4.357-4.352", clipRule: "evenodd" }), /* @__PURE__ */ React.createElement("path", { d: "m6.505 5.495 3.781 1.362-3.78 1.364L5.142 12 3.779 8.22 0 6.858l3.78-1.362 1.363-3.781zm3.61-3.61L12 2.571l-1.885.687-.686 1.885-.687-1.885-1.885-.687 1.885-.686L9.43 0z" }));
4306
-
4307
- const AI_ICON_MAP = {
4308
- chat: SvgAiChat,
4309
- edit: SvgAiEdit,
4310
- form: SvgAiForm,
4311
- mic: SvgAiMic,
4312
- search: SvgAiSearch
4313
- };
4314
- const ICON_ONLY_AI_SIZE_PX = {
4315
- xsmall: 12,
4316
- small: 14,
4317
- medium: 24,
4318
- large: 24
4319
- };
4320
- function iconHasLeadingSlot(icon) {
4321
- if (!icon) {
4322
- return false;
4323
- }
4324
- if (typeof icon !== "object") {
4325
- return true;
4326
- }
4327
- return "before" in icon;
4328
- }
4329
- function aiMarkShowsAnimatedMark(aiMark) {
4330
- return aiMark === true || aiMark === "mark";
4331
- }
4332
-
4333
- const Button = forwardRef(
4334
- (props, ref) => {
4335
- const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
4336
- const {
4337
- aiMark,
4338
- children,
4339
- className,
4340
- appearance = "secondary",
4341
- size = "medium",
4342
- icon,
4343
- loading = false,
4344
- disabled,
4345
- style,
4346
- type = "button",
4347
- onMouseEnter,
4348
- onMouseLeave,
4349
- onFocus,
4350
- onBlur,
4351
- ...rest
4352
- } = componentProps;
4353
- const aiOn = !!aiMark;
4354
- const isIconOnly = !children;
4355
- if (aiOn && icon) {
4356
- if (isIconOnly) {
4357
- warnOnce(
4358
- "[Anvil2 Button] The `icon` prop is ignored when `aiMark` is set on an icon-only button. Only the AI icon is rendered."
4359
- );
4360
- } else if (iconHasLeadingSlot(icon)) {
4361
- warnOnce(
4362
- "[Anvil2 Button] The leading `icon` (plain Svg or `icon.before`) is ignored when `aiMark` is set with button text. Use `icon={{ after: Svg }}` for a trailing icon, or omit `icon`."
4363
- );
4364
- }
4365
- }
4366
- const data = {
4367
- children: childrenToString(props.children),
4368
- appearance,
4369
- icon,
4370
- size,
4371
- type,
4372
- aiMark
4373
- };
4374
- const trackingId = useTrackingId({
4375
- name: "Button",
4376
- data,
4377
- hasOverride: !!props["data-tracking-id"]
4378
- });
4379
- const [isHovered, setIsHovered] = useState(false);
4380
- const [isFocused, setIsFocused] = useState(false);
4381
- const isAnimated = isHovered || isFocused;
4382
- const inheritColorForMark = appearance !== "secondary" && appearance !== "ghost";
4383
- const renderStandardLeading = useCallback(() => {
4384
- if (typeof icon === "object" && icon !== null && "before" in icon) {
4385
- return /* @__PURE__ */ jsx(
4386
- Icon,
4387
- {
4388
- className: styles["icon"],
4389
- inherit: true,
4390
- "aria-hidden": true,
4391
- svg: icon.before
4392
- }
4393
- );
4394
- }
4395
- if (icon && typeof icon !== "object") {
4396
- return /* @__PURE__ */ jsx(
4397
- Icon,
4398
- {
4399
- className: styles["icon"],
4400
- inherit: true,
4401
- "aria-hidden": true,
4402
- svg: icon,
4403
- size: !children && !size.includes("small") ? "large" : "medium"
4404
- }
4405
- );
4406
- }
4407
- return null;
4408
- }, [icon, children, size]);
4409
- const renderAiLeading = useCallback(() => {
4410
- if (aiMarkShowsAnimatedMark(aiMark)) {
4411
- return /* @__PURE__ */ jsx(
4412
- AiMarkIconAnimated,
4413
- {
4414
- animate: isAnimated,
4415
- inheritColor: inheritColorForMark,
4416
- size: isIconOnly ? ICON_ONLY_AI_SIZE_PX[size] : void 0,
4417
- spin: true
4418
- }
4419
- );
4420
- }
4421
- const SvgIcon = AI_ICON_MAP[aiMark];
4422
- return /* @__PURE__ */ jsx(
4423
- Icon,
4424
- {
4425
- className: styles["icon"],
4426
- inherit: true,
4427
- "aria-hidden": true,
4428
- "data-anv": "ai-mark-icon",
4429
- svg: SvgIcon,
4430
- size: isIconOnly && !size.includes("small") ? "large" : "medium"
4431
- }
4432
- );
4433
- }, [aiMark, isAnimated, inheritColorForMark, isIconOnly, size]);
4434
- const leadingContent = useMemo(() => {
4435
- if (loading) {
4436
- return /* @__PURE__ */ jsx(Spinner, { inherit: true, size: "small", className: styles["loading-spinner"] });
4437
- }
4438
- if (aiOn) {
4439
- return renderAiLeading();
4440
- }
4441
- return renderStandardLeading();
4442
- }, [aiOn, loading, renderAiLeading, renderStandardLeading]);
4443
- const trailingAfter = !isIconOnly && typeof icon === "object" && "after" in icon ? /* @__PURE__ */ jsx(Icon, { className: styles["icon"], inherit: true, "aria-hidden": true, svg: icon.after }) : null;
4444
- const buttonClassNames = cx(className, styles["button"], {
4445
- [styles["appearance-primary"]]: appearance === "primary",
4446
- [styles["appearance-secondary"]]: appearance === "secondary",
4447
- [styles["appearance-ghost"]]: appearance === "ghost",
4448
- [styles["danger-secondary"]]: appearance === "danger-secondary",
4449
- [styles["danger-primary"]]: appearance === "danger",
4450
- [styles["size-xsmall"]]: size === "xsmall",
4451
- [styles["size-small"]]: size === "small",
4452
- [styles["size-medium"]]: size === "medium",
4453
- [styles["size-large"]]: size === "large",
4454
- [styles["type-icon"]]: isIconOnly,
4455
- [styles["loading"]]: loading
4456
- });
4457
- const styleCombined = {
4458
- ...style,
4459
- ...layoutStyles
4460
- };
4461
- const handleMouseEnter = useCallback(
4462
- (e) => {
4463
- setIsHovered(true);
4464
- onMouseEnter?.(e);
4465
- },
4466
- [onMouseEnter]
4467
- );
4468
- const handleMouseLeave = useCallback(
4469
- (e) => {
4470
- setIsHovered(false);
4471
- onMouseLeave?.(e);
4472
- },
4473
- [onMouseLeave]
4474
- );
4475
- const handleFocus = useCallback(
4476
- (e) => {
4477
- setIsFocused(true);
4478
- onFocus?.(e);
4479
- },
4480
- [onFocus]
4481
- );
4482
- const handleBlur = useCallback(
4483
- (e) => {
4484
- setIsFocused(false);
4485
- onBlur?.(e);
4486
- },
4487
- [onBlur]
4488
- );
4489
- return /* @__PURE__ */ jsxs(
4490
- "button",
4491
- {
4492
- "data-tracking-id": trackingId,
4493
- className: buttonClassNames,
4494
- type,
4495
- disabled: disabled || loading,
4496
- "aria-busy": loading ? true : void 0,
4497
- "data-anv": "button",
4498
- style: styleCombined,
4499
- ref,
4500
- onMouseEnter: handleMouseEnter,
4501
- onMouseLeave: handleMouseLeave,
4502
- onFocus: handleFocus,
4503
- onBlur: handleBlur,
4504
- ...rest,
4505
- children: [
4506
- leadingContent,
4507
- children,
4508
- trailingAfter
4509
- ]
4510
- }
4511
- );
4512
- }
4513
- );
4514
- Button.displayName = "Button";
4515
-
4516
- export { AiMarkIconAnimated as A, Button as B };
4517
- //# sourceMappingURL=Button-a_D7tUgM.js.map