@tldraw/editor 3.16.0-canary.39bd199a7aa6 → 3.16.0-canary.3c51fb02c6a5

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 (111) hide show
  1. package/dist-cjs/index.d.ts +24 -0
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/TldrawEditor.js +6 -2
  4. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  5. package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
  6. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  7. package/dist-cjs/lib/components/Shape.js +7 -10
  8. package/dist-cjs/lib/components/Shape.js.map +2 -2
  9. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +2 -21
  10. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  11. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
  12. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
  14. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  15. package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
  16. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
  17. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
  18. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  19. package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
  20. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  21. package/dist-cjs/lib/editor/Editor.js +44 -15
  22. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +9 -4
  24. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  25. package/dist-cjs/lib/exports/getSvgJsx.js +1 -2
  26. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  27. package/dist-cjs/lib/hooks/useCanvasEvents.js +24 -20
  28. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  29. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
  30. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
  31. package/dist-cjs/lib/license/Watermark.js +6 -6
  32. package/dist-cjs/lib/license/Watermark.js.map +1 -1
  33. package/dist-cjs/lib/options.js +7 -0
  34. package/dist-cjs/lib/options.js.map +2 -2
  35. package/dist-cjs/version.js +3 -3
  36. package/dist-cjs/version.js.map +1 -1
  37. package/dist-esm/index.d.mts +24 -0
  38. package/dist-esm/index.mjs +1 -1
  39. package/dist-esm/lib/TldrawEditor.mjs +6 -2
  40. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  41. package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
  42. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  43. package/dist-esm/lib/components/Shape.mjs +7 -10
  44. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  45. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -21
  46. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  47. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
  48. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +1 -1
  49. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
  50. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  51. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
  52. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
  53. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
  54. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  55. package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
  56. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  57. package/dist-esm/lib/editor/Editor.mjs +44 -15
  58. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  59. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +9 -4
  60. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  61. package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
  62. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  63. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -21
  64. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  65. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
  66. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
  67. package/dist-esm/lib/license/Watermark.mjs +6 -6
  68. package/dist-esm/lib/license/Watermark.mjs.map +1 -1
  69. package/dist-esm/lib/options.mjs +7 -0
  70. package/dist-esm/lib/options.mjs.map +2 -2
  71. package/dist-esm/version.mjs +3 -3
  72. package/dist-esm/version.mjs.map +1 -1
  73. package/editor.css +293 -288
  74. package/package.json +14 -37
  75. package/src/lib/TldrawEditor.tsx +11 -6
  76. package/src/lib/components/MenuClickCapture.tsx +0 -8
  77. package/src/lib/components/Shape.tsx +6 -12
  78. package/src/lib/components/default-components/DefaultCanvas.tsx +2 -21
  79. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
  80. package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
  81. package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
  82. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +5 -1
  83. package/src/lib/config/TLUserPreferences.ts +8 -1
  84. package/src/lib/editor/Editor.test.ts +12 -11
  85. package/src/lib/editor/Editor.ts +55 -20
  86. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
  87. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
  88. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
  89. package/src/lib/editor/managers/FontManager/FontManager.test.ts +24 -23
  90. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
  91. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
  92. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
  93. package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
  94. package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
  95. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +34 -26
  96. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +6 -1
  97. package/src/lib/exports/getSvgJsx.tsx +2 -2
  98. package/src/lib/hooks/useCanvasEvents.ts +39 -32
  99. package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
  100. package/src/lib/license/LicenseManager.test.ts +3 -1
  101. package/src/lib/license/Watermark.test.tsx +2 -1
  102. package/src/lib/license/Watermark.tsx +6 -6
  103. package/src/lib/options.ts +8 -0
  104. package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
  105. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
  106. package/src/version.ts +3 -3
  107. package/dist-cjs/lib/utils/nearestMultiple.js +0 -34
  108. package/dist-cjs/lib/utils/nearestMultiple.js.map +0 -7
  109. package/dist-esm/lib/utils/nearestMultiple.mjs +0 -14
  110. package/dist-esm/lib/utils/nearestMultiple.mjs.map +0 -7
  111. package/src/lib/utils/nearestMultiple.ts +0 -13
@@ -1,5 +1,5 @@
1
1
  import { useValue } from '@tldraw/state-react'
2
- import React, { useMemo } from 'react'
2
+ import React, { useEffect, useMemo } from 'react'
3
3
  import { RIGHT_MOUSE_BUTTON } from '../constants'
4
4
  import {
5
5
  preventDefault,
@@ -16,9 +16,6 @@ export function useCanvasEvents() {
16
16
 
17
17
  const events = useMemo(
18
18
  function canvasEvents() {
19
- // Track the last screen point
20
- let lastX: number, lastY: number
21
-
22
19
  function onPointerDown(e: React.PointerEvent) {
23
20
  if ((e as any).isKilled) return
24
21
 
@@ -44,35 +41,9 @@ export function useCanvasEvents() {
44
41
  })
45
42
  }
46
43
 
47
- function onPointerMove(e: React.PointerEvent) {
48
- if ((e as any).isKilled) return
49
-
50
- if (e.clientX === lastX && e.clientY === lastY) return
51
- lastX = e.clientX
52
- lastY = e.clientY
53
-
54
- // For tools that benefit from a higher fidelity of events,
55
- // we dispatch the coalesced events.
56
- // N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
57
- const events =
58
- currentTool.useCoalescedEvents && e.nativeEvent.getCoalescedEvents
59
- ? e.nativeEvent.getCoalescedEvents()
60
- : [e]
61
- for (const singleEvent of events) {
62
- editor.dispatch({
63
- type: 'pointer',
64
- target: 'canvas',
65
- name: 'pointer_move',
66
- ...getPointerInfo(singleEvent),
67
- })
68
- }
69
- }
70
-
71
44
  function onPointerUp(e: React.PointerEvent) {
72
45
  if ((e as any).isKilled) return
73
46
  if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return
74
- lastX = e.clientX
75
- lastY = e.clientY
76
47
 
77
48
  releasePointerCapture(e.currentTarget, e)
78
49
 
@@ -158,7 +129,6 @@ export function useCanvasEvents() {
158
129
 
159
130
  return {
160
131
  onPointerDown,
161
- onPointerMove,
162
132
  onPointerUp,
163
133
  onPointerEnter,
164
134
  onPointerLeave,
@@ -169,8 +139,45 @@ export function useCanvasEvents() {
169
139
  onClick,
170
140
  }
171
141
  },
172
- [editor, currentTool]
142
+ [editor]
173
143
  )
174
144
 
145
+ // onPointerMove is special: where we're only interested in the other events when they're
146
+ // happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want
147
+ // the pointer position to be up to date regardless of whether it's over the tldraw canvas or
148
+ // not. So instead of returning a listener to be attached to the canvas, we directly attach a
149
+ // listener to the whole document instead.
150
+ useEffect(() => {
151
+ let lastX: number, lastY: number
152
+
153
+ function onPointerMove(e: PointerEvent) {
154
+ if ((e as any).isKilled) return
155
+ ;(e as any).isKilled = true
156
+
157
+ if (e.clientX === lastX && e.clientY === lastY) return
158
+ lastX = e.clientX
159
+ lastY = e.clientY
160
+
161
+ // For tools that benefit from a higher fidelity of events,
162
+ // we dispatch the coalesced events.
163
+ // N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
164
+ const events =
165
+ currentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]
166
+ for (const singleEvent of events) {
167
+ editor.dispatch({
168
+ type: 'pointer',
169
+ target: 'canvas',
170
+ name: 'pointer_move',
171
+ ...getPointerInfo(singleEvent),
172
+ })
173
+ }
174
+ }
175
+
176
+ document.body.addEventListener('pointermove', onPointerMove)
177
+ return () => {
178
+ document.body.removeEventListener('pointermove', onPointerMove)
179
+ }
180
+ }, [editor, currentTool])
181
+
175
182
  return events
176
183
  }
@@ -1,14 +1,19 @@
1
1
  import { RefObject, useEffect } from 'react'
2
2
  import { preventDefault } from '../utils/dom'
3
3
  import { useContainer } from './useContainer'
4
+ import { useMaybeEditor } from './useEditor'
4
5
 
5
6
  /** @public */
6
7
  export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
7
8
  if (!ref) throw Error('usePassThroughWheelEvents must be passed a ref')
8
9
  const container = useContainer()
10
+ const editor = useMaybeEditor()
9
11
 
10
12
  useEffect(() => {
11
13
  function onWheel(e: WheelEvent) {
14
+ // Only pass through wheel events if the editor is focused
15
+ if (!editor?.getInstanceState().isFocused) return
16
+
12
17
  if ((e as any).isSpecialRedispatchedEvent) return
13
18
 
14
19
  // if the element is scrollable, don't redispatch the event
@@ -32,5 +37,5 @@ export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
32
37
  return () => {
33
38
  elm.removeEventListener('wheel', onWheel)
34
39
  }
35
- }, [container, ref])
40
+ }, [container, editor, ref])
36
41
  }
@@ -1,4 +1,5 @@
1
1
  import crypto from 'crypto'
2
+ import { vi } from 'vitest'
2
3
  import { publishDates } from '../../version'
3
4
  import { str2ab } from '../utils/licensing'
4
5
  import {
@@ -9,8 +10,9 @@ import {
9
10
  ValidLicenseKeyResult,
10
11
  } from './LicenseManager'
11
12
 
12
- jest.mock('../../version', () => {
13
+ vi.mock('../../version', () => {
13
14
  return {
15
+ version: '3.15.1',
14
16
  publishDates: {
15
17
  major: '2024-06-28T10:56:07.893Z',
16
18
  minor: '2024-07-02T16:49:50.397Z',
@@ -1,10 +1,11 @@
1
1
  import { act, render, waitFor } from '@testing-library/react'
2
+ import { vi } from 'vitest'
2
3
  import { TldrawEditor } from '../TldrawEditor'
3
4
  import { LicenseManager } from './LicenseManager'
4
5
 
5
6
  let mockLicenseState = 'unlicensed'
6
7
 
7
- jest.mock('./useLicenseManagerState', () => ({
8
+ vi.mock('./useLicenseManagerState', () => ({
8
9
  useLicenseManagerState: () => mockLicenseState,
9
10
  }))
10
11
 
@@ -86,15 +86,15 @@ To remove the watermark, please purchase a license at tldraw.dev.
86
86
 
87
87
  .${className} {
88
88
  position: absolute;
89
- bottom: var(--space-2);
90
- right: var(--space-2);
89
+ bottom: var(--tl-space-2);
90
+ right: var(--tl-space-2);
91
91
  width: 96px;
92
92
  height: 32px;
93
93
  display: flex;
94
94
  align-items: center;
95
95
  justify-content: center;
96
- z-index: var(--layer-watermark) !important;
97
- background-color: color-mix(in srgb, var(--color-background) 62%, transparent);
96
+ z-index: var(--tl-layer-watermark) !important;
97
+ background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
98
98
  opacity: 1;
99
99
  border-radius: 5px;
100
100
  pointer-events: all;
@@ -108,7 +108,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
108
108
  height: 32px;
109
109
  pointer-events: all;
110
110
  cursor: inherit;
111
- color: var(--color-text);
111
+ color: var(--tl-color-text);
112
112
  opacity: .38;
113
113
  border: 0;
114
114
  padding: 0;
@@ -137,7 +137,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
137
137
  }
138
138
 
139
139
  .${className}:hover {
140
- background-color: var(--color-background);
140
+ background-color: var(--tl-color-background);
141
141
  transition: background-color 0.2s ease-in-out;
142
142
  transition-delay: 0.32s;
143
143
  }
@@ -27,6 +27,8 @@ export interface TldrawOptions {
27
27
  readonly multiClickDurationMs: number
28
28
  readonly coarseDragDistanceSquared: number
29
29
  readonly dragDistanceSquared: number
30
+ readonly uiDragDistanceSquared: number
31
+ readonly uiCoarseDragDistanceSquared: number
30
32
  readonly defaultSvgPadding: number
31
33
  readonly cameraSlideFriction: number
32
34
  readonly gridSteps: readonly {
@@ -53,6 +55,7 @@ export interface TldrawOptions {
53
55
  readonly flattenImageBoundsPadding: number
54
56
  readonly laserDelayMs: number
55
57
  readonly maxExportDelayMs: number
58
+ readonly tooltipDelayMs: number
56
59
  /**
57
60
  * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before
58
61
  * they expire? Defaults to 3 minutes.
@@ -97,6 +100,10 @@ export const defaultTldrawOptions = {
97
100
  multiClickDurationMs: 200,
98
101
  coarseDragDistanceSquared: 36, // 6 squared
99
102
  dragDistanceSquared: 16, // 4 squared
103
+ uiDragDistanceSquared: 16, // 4 squared
104
+ // it's really easy to accidentally drag from the toolbar on mobile, so we use a much larger
105
+ // threshold than usual here to try and prevent accidental drags.
106
+ uiCoarseDragDistanceSquared: 625, // 25 squared
100
107
  defaultSvgPadding: 32,
101
108
  cameraSlideFriction: 0.09,
102
109
  gridSteps: [
@@ -124,6 +131,7 @@ export const defaultTldrawOptions = {
124
131
  flattenImageBoundsPadding: 16,
125
132
  laserDelayMs: 1200,
126
133
  maxExportDelayMs: 5000,
134
+ tooltipDelayMs: 700,
127
135
  temporaryAssetPreviewLifetimeMs: 180000,
128
136
  actionShortcutsLocation: 'swap',
129
137
  createTextOnCanvasDoubleClick: true,
@@ -1,12 +1,13 @@
1
1
  import { createTLSchema } from '@tldraw/tlschema'
2
2
  import { openDB } from 'idb'
3
+ import { vi } from 'vitest'
3
4
  import { hardReset } from './hardReset'
4
5
  import { getAllIndexDbNames, LocalIndexedDb } from './LocalIndexedDb'
5
6
 
6
7
  const schema = createTLSchema({ shapes: {}, bindings: {} })
7
8
  describe('LocalIndexedDb', () => {
8
9
  beforeEach(() => {
9
- jest.useRealTimers()
10
+ vi.useRealTimers()
10
11
  })
11
12
  afterEach(async () => {
12
13
  await hardReset({ shouldReload: false })
@@ -1,6 +1,6 @@
1
1
  import { PageRecordType } from '@tldraw/tlschema'
2
2
  import { IndexKey, promiseWithResolve } from '@tldraw/utils'
3
- import { afterEach } from 'node:test'
3
+ import { Mock, vi } from 'vitest'
4
4
  import { createTLStore } from '../../config/createTLStore'
5
5
  import { TLLocalSyncClient } from './TLLocalSyncClient'
6
6
  import { hardReset } from './hardReset'
@@ -10,20 +10,20 @@ class BroadcastChannelMock {
10
10
  constructor(_name: string) {
11
11
  // noop
12
12
  }
13
- postMessage = jest.fn((_msg: any) => {
13
+ postMessage = vi.fn((_msg: any) => {
14
14
  // noop
15
15
  })
16
- close = jest.fn(() => {
16
+ close = vi.fn(() => {
17
17
  // noop
18
18
  })
19
19
  }
20
20
 
21
21
  function testClient(channel = new BroadcastChannelMock('test')) {
22
22
  const store = createTLStore({ shapeUtils: [], bindingUtils: [] })
23
- const onLoad = jest.fn(() => {
23
+ const onLoad = vi.fn(() => {
24
24
  return
25
25
  })
26
- const onLoadError = jest.fn(() => {
26
+ const onLoadError = vi.fn(() => {
27
27
  return
28
28
  })
29
29
  const client = new TLLocalSyncClient(
@@ -36,26 +36,26 @@ function testClient(channel = new BroadcastChannelMock('test')) {
36
36
  channel
37
37
  )
38
38
 
39
- client.db.storeSnapshot = jest.fn(() => Promise.resolve())
40
- client.db.storeChanges = jest.fn(() => Promise.resolve())
39
+ client.db.storeSnapshot = vi.fn(() => Promise.resolve())
40
+ client.db.storeChanges = vi.fn(() => Promise.resolve())
41
41
 
42
42
  return {
43
- client: client as { db: { storeSnapshot: jest.Mock; storeChanges: jest.Mock } } & typeof client,
43
+ client: client as { db: { storeSnapshot: Mock; storeChanges: Mock } } & typeof client,
44
44
  store,
45
45
  onLoad,
46
46
  onLoadError,
47
47
  channel,
48
48
  tick: async () => {
49
- jest.advanceTimersByTime(500)
49
+ vi.advanceTimersByTime(500)
50
50
  await Promise.resolve()
51
51
  await client.db.pending()
52
- jest.advanceTimersByTime(500)
52
+ vi.advanceTimersByTime(500)
53
53
  await Promise.resolve()
54
54
  },
55
55
  }
56
56
  }
57
57
 
58
- const reloadMock = jest.fn()
58
+ const reloadMock = vi.fn()
59
59
 
60
60
  beforeAll(() => {
61
61
  Object.defineProperty(window, 'location', {
@@ -65,14 +65,14 @@ beforeAll(() => {
65
65
  })
66
66
 
67
67
  beforeEach(() => {
68
- jest.clearAllMocks()
68
+ vi.clearAllMocks()
69
69
  })
70
70
 
71
71
  afterEach(async () => {
72
72
  await hardReset({ shouldReload: false })
73
73
  })
74
74
 
75
- jest.useFakeTimers()
75
+ vi.useFakeTimers()
76
76
 
77
77
  test('the client connects on instantiation, announcing its schema', async () => {
78
78
  const { channel, tick } = testClient()
@@ -86,7 +86,7 @@ test('the client connects on instantiation, announcing its schema', async () =>
86
86
  test('when a client receives an announce with a newer schema version it reloads itself', async () => {
87
87
  const { client, channel, onLoadError, tick } = testClient()
88
88
  await tick()
89
- jest.advanceTimersByTime(10000)
89
+ vi.advanceTimersByTime(10000)
90
90
  expect(reloadMock).not.toHaveBeenCalled()
91
91
  channel.onmessage?.({
92
92
  data: {
@@ -104,7 +104,7 @@ test('when a client receives an announce with a newer schema version it reloads
104
104
  test('when a client receives an announce with a newer schema version shortly after loading it does not reload but instead reports a loadError', async () => {
105
105
  const { client, channel, onLoadError, tick } = testClient()
106
106
  await tick()
107
- jest.advanceTimersByTime(1000)
107
+ vi.advanceTimersByTime(1000)
108
108
  expect(reloadMock).not.toHaveBeenCalled()
109
109
  channel.onmessage?.({
110
110
  data: {
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.16.0-canary.39bd199a7aa6'
4
+ export const version = '3.16.0-canary.3c51fb02c6a5'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-06T12:38:16.348Z',
8
- patch: '2025-08-06T12:38:16.348Z',
7
+ minor: '2025-08-25T12:12:01.278Z',
8
+ patch: '2025-08-25T12:12:01.278Z',
9
9
  }
@@ -1,34 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var nearestMultiple_exports = {};
20
- __export(nearestMultiple_exports, {
21
- nearestMultiple: () => nearestMultiple
22
- });
23
- module.exports = __toCommonJS(nearestMultiple_exports);
24
- function gcd(a, b) {
25
- return b === 0 ? a : gcd(b, a % b);
26
- }
27
- function nearestMultiple(float) {
28
- const decimal = float.toString().split(".")[1];
29
- if (!decimal) return 1;
30
- const denominator = Math.pow(10, decimal.length);
31
- const numerator = parseInt(decimal, 10);
32
- return denominator / gcd(numerator, denominator);
33
- }
34
- //# sourceMappingURL=nearestMultiple.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/lib/utils/nearestMultiple.ts"],
4
- "sourcesContent": ["// Euclidean algorithm to find the GCD\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n// Returns the lowest value that the given number can be multiplied by to reach an integer\nexport function nearestMultiple(float: number) {\n\tconst decimal = float.toString().split('.')[1]\n\tif (!decimal) return 1\n\tconst denominator = Math.pow(10, decimal.length)\n\tconst numerator = parseInt(decimal, 10)\n\treturn denominator / gcd(numerator, denominator)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,IAAI,GAAW,GAAmB;AAC1C,SAAO,MAAM,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;AAClC;AAGO,SAAS,gBAAgB,OAAe;AAC9C,QAAM,UAAU,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7C,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAAc,KAAK,IAAI,IAAI,QAAQ,MAAM;AAC/C,QAAM,YAAY,SAAS,SAAS,EAAE;AACtC,SAAO,cAAc,IAAI,WAAW,WAAW;AAChD;",
6
- "names": []
7
- }
@@ -1,14 +0,0 @@
1
- function gcd(a, b) {
2
- return b === 0 ? a : gcd(b, a % b);
3
- }
4
- function nearestMultiple(float) {
5
- const decimal = float.toString().split(".")[1];
6
- if (!decimal) return 1;
7
- const denominator = Math.pow(10, decimal.length);
8
- const numerator = parseInt(decimal, 10);
9
- return denominator / gcd(numerator, denominator);
10
- }
11
- export {
12
- nearestMultiple
13
- };
14
- //# sourceMappingURL=nearestMultiple.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/lib/utils/nearestMultiple.ts"],
4
- "sourcesContent": ["// Euclidean algorithm to find the GCD\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n// Returns the lowest value that the given number can be multiplied by to reach an integer\nexport function nearestMultiple(float: number) {\n\tconst decimal = float.toString().split('.')[1]\n\tif (!decimal) return 1\n\tconst denominator = Math.pow(10, decimal.length)\n\tconst numerator = parseInt(decimal, 10)\n\treturn denominator / gcd(numerator, denominator)\n}\n"],
5
- "mappings": "AACA,SAAS,IAAI,GAAW,GAAmB;AAC1C,SAAO,MAAM,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;AAClC;AAGO,SAAS,gBAAgB,OAAe;AAC9C,QAAM,UAAU,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7C,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAAc,KAAK,IAAI,IAAI,QAAQ,MAAM;AAC/C,QAAM,YAAY,SAAS,SAAS,EAAE;AACtC,SAAO,cAAc,IAAI,WAAW,WAAW;AAChD;",
6
- "names": []
7
- }
@@ -1,13 +0,0 @@
1
- // Euclidean algorithm to find the GCD
2
- function gcd(a: number, b: number): number {
3
- return b === 0 ? a : gcd(b, a % b)
4
- }
5
-
6
- // Returns the lowest value that the given number can be multiplied by to reach an integer
7
- export function nearestMultiple(float: number) {
8
- const decimal = float.toString().split('.')[1]
9
- if (!decimal) return 1
10
- const denominator = Math.pow(10, decimal.length)
11
- const numerator = parseInt(decimal, 10)
12
- return denominator / gcd(numerator, denominator)
13
- }