@douxcode/vue-spring-bottom-sheet 2.5.0 → 2.6.0-next.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.
@@ -7,13 +7,13 @@ declare function __VLS_template(): {
7
7
  footer?(_: {}): any;
8
8
  };
9
9
  refs: {
10
- backdrop: import('vue').ShallowUnwrapRef<{}> | null;
11
- sheet: import('vue').ShallowUnwrapRef<{}> | null;
12
- sheetHeader: import('vue').ShallowUnwrapRef<{}> | null;
10
+ backdrop: HTMLDivElement;
11
+ sheet: HTMLDivElement;
12
+ sheetHeader: HTMLDivElement;
13
13
  sheetScroll: HTMLDivElement;
14
- sheetContentWrapper: import('vue').ShallowUnwrapRef<{}> | null;
14
+ sheetContentWrapper: HTMLDivElement;
15
15
  sheetContent: HTMLDivElement;
16
- sheetFooter: import('vue').ShallowUnwrapRef<{}> | null;
16
+ sheetFooter: HTMLDivElement;
17
17
  };
18
18
  rootEl: any;
19
19
  };
@@ -37,13 +37,13 @@ declare const __VLS_component: import('vue').DefineComponent<BottomSheetProps, {
37
37
  teleportTo: string | import('vue').RendererElement;
38
38
  teleportDefer: boolean;
39
39
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
40
- backdrop: import('vue').ShallowUnwrapRef<{}> | null;
41
- sheet: import('vue').ShallowUnwrapRef<{}> | null;
42
- sheetHeader: import('vue').ShallowUnwrapRef<{}> | null;
40
+ backdrop: HTMLDivElement;
41
+ sheet: HTMLDivElement;
42
+ sheetHeader: HTMLDivElement;
43
43
  sheetScroll: HTMLDivElement;
44
- sheetContentWrapper: import('vue').ShallowUnwrapRef<{}> | null;
44
+ sheetContentWrapper: HTMLDivElement;
45
45
  sheetContent: HTMLDivElement;
46
- sheetFooter: import('vue').ShallowUnwrapRef<{}> | null;
46
+ sheetFooter: HTMLDivElement;
47
47
  }, any>;
48
48
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
49
49
  export default _default;
@@ -0,0 +1,13 @@
1
+ export interface SwipeResult {
2
+ direction: 'up' | 'down' | 'none';
3
+ velocity: number;
4
+ isSwipe: boolean;
5
+ }
6
+ export interface UseSwipeDetectionOptions {
7
+ velocityThreshold?: number;
8
+ }
9
+ export declare function useSwipeDetection(options?: UseSwipeDetectionOptions): {
10
+ start: (y: number) => void;
11
+ update: (y: number) => void;
12
+ end: () => SwipeResult;
13
+ };
package/dist/index.mjs CHANGED
@@ -1,83 +1,112 @@
1
- import { ref as C, computed as _, defineComponent as Be, watch as q, onMounted as Ie, toRefs as Ee, nextTick as N, onUnmounted as _e, createBlock as te, openBlock as ae, Teleport as De, createElementVNode as ne, createVNode as $, unref as m, withCtx as E, createCommentVNode as ge, normalizeStyle as He, normalizeClass as oe, renderSlot as le } from "vue";
2
- import { useMotionValue as me, animate as B, AnimatePresence as ye, Motion as A } from "motion-v";
3
- import { useVModel as Ve, useWindowSize as Fe, useElementBounding as Q, useScrollLock as be } from "@vueuse/core";
4
- import { useFocusTrap as Re } from "@vueuse/integrations/useFocusTrap";
5
- function G(n, a) {
6
- const o = parseFloat(n);
7
- return a * o / 100;
1
+ import { ref as g, computed as I, defineComponent as Re, useCssVars as Le, watch as U, onMounted as _e, toRefs as Ae, nextTick as ge, onUnmounted as Ve, createElementBlock as ae, openBlock as V, Fragment as We, createBlock as we, Teleport as Se, createVNode as Ce, Transition as be, withCtx as ye, createCommentVNode as Pe, unref as le, normalizeStyle as ze, createElementVNode as W, normalizeClass as oe, renderSlot as ue } from "vue";
2
+ import { useVModel as Ne, useWindowSize as qe, useElementBounding as J, useScrollLock as Te } from "@vueuse/core";
3
+ import { useFocusTrap as Qe } from "@vueuse/integrations/useFocusTrap";
4
+ function z(o, l) {
5
+ const r = parseFloat(o);
6
+ return l * r / 100;
8
7
  }
9
- function $e(n, a, o) {
10
- const t = C(0), s = _(() => n.value.map((f) => typeof f == "string" ? G(f, o.value) : f)), b = _(() => Math.min(...s.value)), r = _(() => Math.max(...s.value)), p = _(() => {
11
- const f = s.value.reduce(
12
- (h, O) => Math.abs(O - a.value) < Math.abs(h - a.value) ? O : h
8
+ function je(o, l, r) {
9
+ const t = g(0), v = I(() => o.value.map((b) => typeof b == "string" ? z(b, r.value) : b)), C = I(() => Math.min(...v.value)), i = I(() => Math.max(...v.value)), y = I(() => {
10
+ const b = v.value.reduce(
11
+ (P, w) => Math.abs(w - l.value) < Math.abs(P - l.value) ? w : P
13
12
  );
14
- return s.value.indexOf(f);
13
+ return v.value.indexOf(b);
15
14
  });
16
15
  return {
17
16
  currentSnapPointIndex: t,
18
- flattenedSnapPoints: s,
19
- minSnapPoint: b,
20
- maxSnapPoint: r,
21
- closestSnapPointIndex: p
17
+ flattenedSnapPoints: v,
18
+ minSnapPoint: C,
19
+ maxSnapPoint: i,
20
+ closestSnapPointIndex: y
22
21
  };
23
22
  }
24
- function Ae(n, a, o) {
25
- let t = (s) => n(s, ...a);
26
- return o === void 0 ? t : Object.assign(t, { lazy: o, lazyArgs: a });
23
+ function Ge(o = {}) {
24
+ const { velocityThreshold: l = 0.5 } = o, r = g(0), t = g(0), v = g(0), C = g(0), i = g([]);
25
+ return {
26
+ start: (w) => {
27
+ const S = performance.now();
28
+ r.value = w, t.value = S, v.value = w, C.value = S, i.value = [{ y: w, time: S }];
29
+ },
30
+ update: (w) => {
31
+ const S = performance.now();
32
+ v.value = w, C.value = S, i.value.push({ y: w, time: S });
33
+ const M = S - 100;
34
+ i.value = i.value.filter((d) => d.time > M).slice(-5);
35
+ },
36
+ end: () => {
37
+ const w = i.value;
38
+ let S = 0;
39
+ if (w.length >= 2) {
40
+ const h = w[0], D = w[w.length - 1], $ = D.y - h.y, L = D.time - h.time;
41
+ L > 0 && (S = $ / L);
42
+ }
43
+ const M = Math.abs(S) >= l;
44
+ let d = "none";
45
+ return M && (d = S < 0 ? "up" : "down"), i.value = [], {
46
+ direction: d,
47
+ velocity: Math.abs(S),
48
+ isSwipe: M
49
+ };
50
+ }
51
+ };
52
+ }
53
+ function Ke(o, l, r) {
54
+ let t = (v) => o(v, ...l);
55
+ return r === void 0 ? t : Object.assign(t, { lazy: r, lazyArgs: l });
27
56
  }
28
- function We(n, a, o) {
29
- let t = n.length - a.length;
30
- if (t === 0) return n(...a);
31
- if (t === 1) return Ae(n, a, o);
57
+ function Ue(o, l, r) {
58
+ let t = o.length - l.length;
59
+ if (t === 0) return o(...l);
60
+ if (t === 1) return Ke(o, l, r);
32
61
  throw new Error("Wrong number of arguments");
33
62
  }
34
- function je(n, { triggerAt: a = "end", minQuietPeriodMs: o, maxBurstDurationMs: t, minGapMs: s, reducer: b = ze }) {
35
- let r, p, f, h, O = () => {
36
- let i = f;
37
- i !== void 0 && (f = void 0, n(i), s !== void 0 && (p = setTimeout(D, s)));
38
- }, D = () => {
39
- clearTimeout(p), p = void 0, r === void 0 && O();
40
- }, H = () => {
41
- clearTimeout(r), r = void 0, h = void 0, p === void 0 && O();
63
+ function Je(o, { triggerAt: l = "end", minQuietPeriodMs: r, maxBurstDurationMs: t, minGapMs: v, reducer: C = Xe }) {
64
+ let i, y, b, P, w = () => {
65
+ let d = b;
66
+ d !== void 0 && (b = void 0, o(d), v !== void 0 && (y = setTimeout(S, v)));
67
+ }, S = () => {
68
+ clearTimeout(y), y = void 0, i === void 0 && w();
69
+ }, M = () => {
70
+ clearTimeout(i), i = void 0, P = void 0, y === void 0 && w();
42
71
  };
43
- return { call: (...i) => {
44
- let c = r === void 0 && p === void 0;
45
- if ((a !== "start" || c) && (f = b(f, ...i)), !(r === void 0 && !c)) {
46
- if (o !== void 0 || t !== void 0 || s === void 0) {
47
- clearTimeout(r);
48
- let P = Date.now();
49
- h ?? (h = P);
50
- let W = t === void 0 ? o ?? 0 : Math.min(o ?? t, t - (P - h));
51
- r = setTimeout(H, W);
72
+ return { call: (...d) => {
73
+ let h = i === void 0 && y === void 0;
74
+ if ((l !== "start" || h) && (b = C(b, ...d)), !(i === void 0 && !h)) {
75
+ if (r !== void 0 || t !== void 0 || v === void 0) {
76
+ clearTimeout(i);
77
+ let D = Date.now();
78
+ P ?? (P = D);
79
+ let $ = t === void 0 ? r ?? 0 : Math.min(r ?? t, t - (D - P));
80
+ i = setTimeout(M, $);
52
81
  }
53
- a !== "end" && c && O();
82
+ l !== "end" && h && w();
54
83
  }
55
84
  }, cancel: () => {
56
- clearTimeout(r), r = void 0, h = void 0, clearTimeout(p), p = void 0, f = void 0;
85
+ clearTimeout(i), i = void 0, P = void 0, clearTimeout(y), y = void 0, b = void 0;
57
86
  }, flush: () => {
58
- H(), D();
87
+ M(), S();
59
88
  }, get isIdle() {
60
- return r === void 0 && p === void 0;
89
+ return i === void 0 && y === void 0;
61
90
  } };
62
91
  }
63
- var ze = () => "";
64
- function y(...n) {
65
- return We(Le, n);
92
+ var Xe = () => "";
93
+ function T(...o) {
94
+ return Ue(Ze, o);
66
95
  }
67
- var Le = (n, { min: a, max: o }) => a !== void 0 && n < a ? a : o !== void 0 && n > o ? o : n;
68
- function qe(n, a, o) {
69
- return Math.max(a, Math.min(n, o));
96
+ var Ze = (o, { min: l, max: r }) => l !== void 0 && o < l ? l : r !== void 0 && o > r ? r : o;
97
+ function et(o, l, r) {
98
+ return Math.max(l, Math.min(o, r));
70
99
  }
71
- function Ne(n, a) {
72
- return Math.pow(n, a * 5);
100
+ function tt(o, l) {
101
+ return Math.pow(o, l * 5);
73
102
  }
74
- function Se(n, a, o) {
75
- return a === 0 || Math.abs(a) === 1 / 0 ? Ne(n, o) : n * a * o / (a + o * n);
103
+ function ke(o, l, r) {
104
+ return l === 0 || Math.abs(l) === 1 / 0 ? tt(o, r) : o * l * r / (l + r * o);
76
105
  }
77
- function ue(n, a, o, t = 0.15) {
78
- return t === 0 ? qe(n, a, o) : n < a ? -Se(a - n, o - a, t) + a : n > o ? +Se(n - o, o - a, t) + o : n;
106
+ function se(o, l, r, t = 0.15) {
107
+ return t === 0 ? et(o, l, r) : o < l ? -ke(l - o, r - l, t) + l : o > r ? +ke(o - r, r - l, t) + r : o;
79
108
  }
80
- const Qe = { "data-vsbs-container": "" }, Ge = /* @__PURE__ */ Be({
109
+ const nt = ["data-vsbs-shadow", "data-vsbs-sheet-show"], at = /* @__PURE__ */ Re({
81
110
  __name: "BottomSheet",
82
111
  props: {
83
112
  duration: { default: 250 },
@@ -96,326 +125,385 @@ const Qe = { "data-vsbs-container": "" }, Ge = /* @__PURE__ */ Be({
96
125
  footerClass: {}
97
126
  },
98
127
  emits: ["opened", "opening-started", "closed", "closing-started", "ready", "dragging-up", "dragging-down", "snapped", "instinctHeight", "update:modelValue"],
99
- setup(n, { expose: a, emit: o }) {
100
- const t = n, s = o, b = Ve(t, "modelValue", s, {
128
+ setup(o, { expose: l, emit: r }) {
129
+ Le((e) => ({
130
+ "55bcd70e": xe.value
131
+ }));
132
+ const t = o, v = r, C = Ne(t, "modelValue", v, {
101
133
  passive: !0
102
134
  });
103
- q(b, (e) => {
104
- e && X();
105
- }), Ie(() => {
106
- b.value && X();
135
+ U(C, (e) => {
136
+ e && te();
137
+ }), _e(() => {
138
+ C.value && te();
107
139
  });
108
- const r = C(), p = C(null), f = C(null), h = C(null), O = C(null), D = C(null), H = C(null), i = C(t.expandOnContentDrag), { height: c } = Fe(), { height: P } = Q(r), { height: W } = Q(p), { height: se } = Q(D), { height: re } = Q(f), K = _({
140
+ const i = g(null), y = g(null), b = g(null), P = g(null), w = g(null), S = g(null), M = g(null), d = g(t.expandOnContentDrag), { height: h } = qe(), { height: D } = J(i), { height: $ } = J(y), { height: L } = J(S), { height: re } = J(b), X = I({
109
141
  get() {
110
- return y(
111
- Math.ceil(se.value + W.value + re.value),
142
+ return T(
143
+ Math.ceil(L.value + $.value + re.value),
112
144
  {
113
- max: c.value
145
+ max: h.value
114
146
  }
115
147
  );
116
148
  },
117
149
  set(e) {
118
- [W.value, se.value, re.value] = e;
150
+ [$.value, L.value, re.value] = e;
119
151
  }
120
- }), l = C(0), v = C(0), w = me(0), S = me(0), { snapPoints: Ce } = Ee(t), d = _(() => Ce.value ?? [K.value]), {
121
- flattenedSnapPoints: U,
122
- currentSnapPointIndex: I,
123
- closestSnapPointIndex: V,
124
- minSnapPoint: M,
125
- maxSnapPoint: F
126
- } = $e(d, l, c);
127
- let T;
128
- const j = be(document.body), z = be(document.documentElement), Y = Re([r, H], {
152
+ }), a = g(0), u = g(0), xe = I(() => t.duration + "ms"), { snapPoints: Ye } = Ae(t), f = I(() => Ye.value ?? [X.value]), {
153
+ flattenedSnapPoints: k,
154
+ currentSnapPointIndex: B,
155
+ closestSnapPointIndex: F,
156
+ minSnapPoint: O,
157
+ maxSnapPoint: _
158
+ } = je(f, a, h), N = Te(document.body), q = Te(document.documentElement), E = g(!1), A = g(0), Q = g(0), j = g(0), H = g(0), G = g(!0), R = Ge({ velocityThreshold: 0.5 }), Z = Qe([i, M], {
129
159
  immediate: !1,
130
- fallbackFocus: () => {
131
- var e;
132
- return ((e = r.value) == null ? void 0 : e.$el) || document.body;
133
- }
160
+ fallbackFocus: () => i.value || document.body
134
161
  });
135
162
  function ie(e) {
136
- i.value = !0, ve(e);
163
+ d.value = !0, ve(e);
137
164
  }
138
165
  function ve(e) {
139
- i.value && e.preventDefault();
166
+ d.value && e.preventDefault();
140
167
  }
141
- const de = (e) => {
142
- e.key === "Escape" && L();
143
- }, Pe = () => {
144
- t.canBackdropClose && L();
168
+ const ce = (e) => {
169
+ e.key === "Escape" && x();
170
+ }, Me = () => {
171
+ t.canBackdropClose && x();
145
172
  };
146
- let J = !1;
147
- const X = async () => {
148
- if (J) return;
149
- b.value = !0, J = !0, s("opening-started"), t.blocking && (j.value = !0, z.value = !0), await N();
150
- const e = r.value.$el;
151
- P.value = e.getBoundingClientRect().height;
152
- const u = e.querySelector("[data-vsbs-content]"), g = e.querySelector("[data-vsbs-header]"), k = e.querySelector("[data-vsbs-footer]");
153
- if (K.value = [
154
- g.getBoundingClientRect().height,
155
- u.getBoundingClientRect().height,
156
- k.getBoundingClientRect().height
157
- ], await N(), I.value = U.value.findIndex(
158
- (x) => x === M.value
173
+ let ee = !1;
174
+ const te = async () => {
175
+ if (ee) return;
176
+ C.value = !0, ee = !0, v("opening-started"), t.blocking && (N.value = !0, q.value = !0), await ge();
177
+ const e = i.value;
178
+ D.value = e.getBoundingClientRect().height;
179
+ const n = e.querySelector("[data-vsbs-content]"), s = e.querySelector("[data-vsbs-header]"), p = e.querySelector("[data-vsbs-footer]");
180
+ if (X.value = [
181
+ s.getBoundingClientRect().height,
182
+ n.getBoundingClientRect().height,
183
+ p.getBoundingClientRect().height
184
+ ], await ge(), B.value = k.value.findIndex(
185
+ (c) => c === O.value
159
186
  ), t.initialSnapPoint) {
160
- const x = t.initialSnapPoint;
161
- if (x < 0 || x >= d.value.length) {
187
+ const c = t.initialSnapPoint;
188
+ if (c < 0 || c >= f.value.length) {
162
189
  console.warn("Index out of bounds");
163
190
  return;
164
191
  }
165
- let R;
166
- typeof d.value[x] == "number" ? R = y(d.value[x], {
167
- max: c.value
168
- }) : R = G(d.value[x], c.value), l.value = R;
192
+ let m;
193
+ typeof f.value[c] == "number" ? m = T(f.value[c], {
194
+ max: h.value
195
+ }) : m = z(f.value[c], h.value), a.value = m;
169
196
  } else
170
- l.value = y(M.value, {
171
- max: c.value
197
+ a.value = T(O.value, {
198
+ max: h.value
172
199
  });
173
- v.value = l.value, w.jump(l.value), S.jump(l.value), requestAnimationFrame(() => {
174
- T = B(w, l.value, {
175
- duration: t.duration / 1e3,
176
- ease: "easeInOut"
177
- }), T = B(S, 0, {
178
- duration: t.duration / 1e3,
179
- ease: "easeInOut",
180
- onComplete: () => {
181
- t.blocking && (s("opened"), Y.activate());
182
- }
183
- });
184
- }), window.addEventListener("keydown", de), J = !1;
200
+ u.value = a.value, requestAnimationFrame(() => {
201
+ u.value = 0, t.blocking && setTimeout(() => {
202
+ C.value && (v("opened"), Z.activate());
203
+ }, t.duration);
204
+ }), window.addEventListener("keydown", ce), ee = !1;
185
205
  };
186
- let Z = !1;
187
- const L = () => {
188
- Z || (b.value = !1, Z = !0, s("closing-started"), t.blocking && (j.value = !1, z.value = !1), window.removeEventListener("keydown", de), t.blocking && Y.deactivate(), setTimeout(() => {
189
- s("closed"), Z = !1;
206
+ let ne = !1;
207
+ const x = () => {
208
+ ne || (C.value = !1, ne = !0, v("closing-started"), t.blocking && (N.value = !1, q.value = !1), window.removeEventListener("keydown", ce), t.blocking && Z.deactivate(), u.value = a.value, setTimeout(() => {
209
+ v("closed"), ne = !1;
190
210
  }, t.duration));
191
- }, ce = (e) => {
192
- if (!d.value) return;
193
- if (e < 0 || e >= d.value.length) {
211
+ }, de = (e) => {
212
+ if (!f.value) return;
213
+ if (e < 0 || e >= f.value.length) {
194
214
  console.warn("Index out of bounds");
195
215
  return;
196
216
  }
197
- I.value = e;
198
- let u;
199
- typeof d.value[e] == "number" ? u = y(d.value[e], {
200
- max: c.value
201
- }) : u = G(d.value[e], c.value), l.value = u, T = B(w, l.value, {
202
- duration: t.duration / 1e3,
203
- ease: "easeInOut",
204
- onComplete: () => s("snapped", d.value.indexOf(d.value[e]))
205
- });
217
+ B.value = e;
218
+ let n;
219
+ typeof f.value[e] == "number" ? n = T(f.value[e], {
220
+ max: h.value
221
+ }) : n = z(f.value[e], h.value), a.value = n, v("snapped", f.value.indexOf(f.value[e]));
206
222
  };
207
223
  function fe(e) {
208
- e > 0 ? s("dragging-down") : e < 0 && s("dragging-up");
224
+ e > 0 ? v("dragging-down") : e < 0 && v("dragging-up");
209
225
  }
210
- const pe = () => {
211
- l.value = P.value, v.value = S.get(), w.jump(l.value), S.jump(v.value);
212
- }, he = async (e, u) => {
213
- await N(), r.value && (v.value <= 0 && (l.value -= u.delta.y), l.value <= M.value && (l.value = M.value, v.value += u.delta.y, S.set(
214
- t.canSwipeClose ? y(v.value, { min: 0 }) : y(ue(v.value, -P.value, 0, 0.5), {
215
- min: 0
216
- })
217
- )), w.set(
218
- y(ue(l.value, 0, F.value, 0.25), {
219
- min: 0,
220
- max: c.value
221
- })
222
- ), fe(u.delta.y));
223
- }, ee = () => {
224
- if (t.canSwipeClose) {
225
- let u = l.value / 2;
226
- t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "number" && (u = t.swipeCloseThreshold), t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "string" && t.swipeCloseThreshold.includes("%") && (u = l.value * (Number(t.swipeCloseThreshold.replace("%", "")) / 100)), v.value > u && (v.value = l.value);
226
+ const pe = (e) => {
227
+ if (!i.value) return;
228
+ const n = window.getComputedStyle(i.value), s = parseFloat(n.height);
229
+ let p = 0;
230
+ n.transform && n.transform !== "none" && (p = new DOMMatrix(n.transform).m42), a.value = s, u.value = p, E.value = !0, A.value = e.clientY, Q.value = a.value, j.value = u.value, H.value = e.clientY, R.start(e.clientY), e.target.setPointerCapture(e.pointerId);
231
+ }, he = (e) => {
232
+ if (!E.value) return;
233
+ const n = e.clientY - A.value, s = e.clientY;
234
+ u.value <= 0 && (a.value = Q.value - n), a.value <= O.value && (a.value = O.value, u.value = j.value + n, t.canSwipeClose ? u.value = T(u.value, { min: 0 }) : u.value = T(
235
+ se(u.value, -D.value, 0, 0.5),
236
+ { min: 0 }
237
+ )), a.value = T(se(a.value, 0, _.value, 0.25), {
238
+ min: 0,
239
+ max: h.value
240
+ }), fe(e.clientY - H.value), R.update(e.clientY), H.value = s;
241
+ }, K = (e) => {
242
+ if (E.value = !1, e.target.releasePointerCapture(e.pointerId), t.canSwipeClose) {
243
+ let c = a.value / 2;
244
+ if (t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "number" && (c = t.swipeCloseThreshold), t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "string" && t.swipeCloseThreshold.includes("%") && (c = a.value * (Number(t.swipeCloseThreshold.replace("%", "")) / 100)), u.value > c) {
245
+ u.value = a.value, x();
246
+ return;
247
+ }
248
+ } else
249
+ u.value = 0;
250
+ if (u.value === a.value) {
251
+ u.value = 0, x();
252
+ return;
253
+ }
254
+ const n = R.end();
255
+ if (n.isSwipe && n.direction === "down" && t.canSwipeClose && a.value <= O.value + 10) {
256
+ u.value = a.value, x();
257
+ return;
258
+ }
259
+ let s;
260
+ if (n.isSwipe && k.value.length > 1) {
261
+ const c = [...k.value].sort((m, Y) => m - Y);
262
+ if (n.direction === "up") {
263
+ const m = c.find((Y) => Y > a.value + 1);
264
+ s = m !== void 0 ? k.value.indexOf(m) : F.value;
265
+ } else {
266
+ const m = [...c].reverse().find((Y) => Y < a.value - 1);
267
+ s = m !== void 0 ? k.value.indexOf(m) : F.value;
268
+ }
227
269
  } else
228
- v.value = 0;
229
- T = B(S, v.value, {
230
- duration: t.duration / 1e3,
231
- ease: "easeInOut"
232
- }), v.value === l.value && (v.value = 0, L()), I.value = V.value;
233
- let e;
234
- typeof d.value[V.value] == "number" ? e = y(d.value[V.value], {
235
- max: c.value
236
- }) : e = G(
237
- d.value[V.value],
238
- c.value
239
- ), l.value = e, T = B(w, l.value, {
240
- duration: t.duration / 1e3,
241
- ease: "easeInOut",
242
- onComplete: () => s(
243
- "snapped",
244
- d.value.indexOf(d.value[V.value])
245
- )
246
- }), T = B(S, 0, {
247
- duration: t.duration / 1e3,
248
- ease: "easeInOut"
249
- });
250
- }, we = (e, u) => {
251
- if (l.value = P.value, v.value = S.get(), T && T.stop(), !h.value) return;
252
- const g = h.value.scrollTop === 0, k = u.delta.y > 0, x = U.value.length === 1, R = 0.5 > Math.abs(l.value - F.value);
253
- if (x) {
270
+ s = F.value;
271
+ B.value = s;
272
+ let p;
273
+ if (typeof f.value[s] == "number" ? p = T(f.value[s], {
274
+ max: h.value
275
+ }) : p = z(
276
+ f.value[s],
277
+ h.value
278
+ ), p === 0) {
279
+ x();
280
+ return;
281
+ }
282
+ a.value = p, u.value = 0, v("snapped", f.value.indexOf(f.value[s]));
283
+ }, De = (e) => {
284
+ if (!P.value) return;
285
+ const n = P.value.scrollTop === 0, s = e > 0, p = k.value.length === 1, c = 0.5 > Math.abs(a.value - _.value);
286
+ if (console.log(e), p) {
254
287
  if (!t.expandOnContentDrag) {
255
- i.value = !1;
288
+ d.value = !1;
256
289
  return;
257
290
  }
258
- S.get() === 0 && g && k && (i.value = !0), S.get() === 0 && g && !k && (i.value = !1);
291
+ u.value === 0 && n && s && (d.value = !0), u.value === 0 && n && !s && (d.value = !1);
259
292
  } else {
260
293
  if (!t.expandOnContentDrag) {
261
- i.value = !1;
294
+ d.value = !1;
262
295
  return;
263
296
  }
264
- i.value = !0, R && (k && g && (i.value = !0), !k && g && (i.value = !1), g || (i.value = !1));
297
+ d.value = !0, c && (s && n && (d.value = !0), !s && n && (d.value = !1), n || (d.value = !1));
265
298
  }
266
- }, Te = async (e, u) => {
267
- if (await N(), !t.expandOnContentDrag) {
268
- i.value = !1;
299
+ }, Oe = (e) => {
300
+ if (!i.value) return;
301
+ const n = window.getComputedStyle(i.value), s = parseFloat(n.height);
302
+ let p = 0;
303
+ n.transform && n.transform !== "none" && (p = new DOMMatrix(n.transform).m42), a.value = s, u.value = p, E.value = !0, A.value = e.clientY, Q.value = a.value, j.value = u.value, H.value = e.clientY, G.value = !0, R.start(e.clientY), e.target.setPointerCapture(e.pointerId);
304
+ }, Be = (e) => {
305
+ if (!E.value) return;
306
+ if (!t.expandOnContentDrag) {
307
+ d.value = !1;
269
308
  return;
270
309
  }
271
- if (!r.value) return;
272
- v.value === 0 && i.value && t.expandOnContentDrag && (l.value -= u.delta.y), l.value <= M.value && (l.value = M.value, i.value && t.expandOnContentDrag && (v.value += u.delta.y), v.value = y(v.value, { min: 0, max: M.value }), S.set(
273
- t.canSwipeClose ? y(v.value, { min: 0 }) : y(ue(v.value, -P.value, 0, 0.5), {
274
- min: 0
275
- })
276
- )), l.value > F.value && (l.value = F.value), l.value = y(l.value, { max: c.value }), U.value.length === 1 || l.value === F.value && (i.value = !1), w.set(l.value), fe(u.delta.y);
277
- }, ke = () => {
278
- t.blocking || (j.value = !0, z.value = !0);
279
- }, xe = () => {
280
- t.blocking || (j.value = !1, z.value = !1);
281
- }, Oe = () => {
282
- if (!h.value) return;
283
- const e = h.value.scrollTop === 0;
284
- i.value = e;
285
- }, Me = je((e) => ce(e), {
310
+ const n = e.clientY - A.value, s = e.clientY, p = e.clientY - H.value;
311
+ if (G.value) {
312
+ const m = e.clientY - A.value;
313
+ if (Math.abs(m) > 3)
314
+ G.value = !1, De(m);
315
+ else {
316
+ H.value = s;
317
+ return;
318
+ }
319
+ }
320
+ u.value === 0 && d.value && t.expandOnContentDrag && (a.value = Q.value - n), a.value <= O.value && (a.value = O.value, d.value && t.expandOnContentDrag && (u.value = j.value + n), u.value = T(u.value, { min: 0, max: O.value }), t.canSwipeClose ? u.value = T(u.value, { min: 0 }) : u.value = T(
321
+ se(u.value, -D.value, 0, 0.5),
322
+ { min: 0 }
323
+ )), a.value > _.value && (a.value = _.value), a.value = T(a.value, { max: h.value }), k.value.length === 1 || a.value === _.value && (d.value = !1), fe(p), R.update(e.clientY), H.value = s;
324
+ }, me = (e) => {
325
+ if (E.value = !1, G.value = !0, e.target.releasePointerCapture(e.pointerId), t.canSwipeClose) {
326
+ let c = a.value / 2;
327
+ if (t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "number" && (c = t.swipeCloseThreshold), t.swipeCloseThreshold && typeof t.swipeCloseThreshold == "string" && t.swipeCloseThreshold.includes("%") && (c = a.value * (Number(t.swipeCloseThreshold.replace("%", "")) / 100)), u.value > c) {
328
+ u.value = a.value, x();
329
+ return;
330
+ }
331
+ } else
332
+ u.value = 0;
333
+ if (u.value === a.value) {
334
+ u.value = 0, x();
335
+ return;
336
+ }
337
+ const n = R.end();
338
+ if (n.isSwipe && n.direction === "down" && t.canSwipeClose && a.value <= O.value + 10) {
339
+ u.value = a.value, x();
340
+ return;
341
+ }
342
+ let s;
343
+ if (n.isSwipe && k.value.length > 1) {
344
+ const c = [...k.value].sort((m, Y) => m - Y);
345
+ if (n.direction === "up") {
346
+ const m = c.find((Y) => Y > a.value + 1);
347
+ s = m !== void 0 ? k.value.indexOf(m) : F.value;
348
+ } else {
349
+ const m = [...c].reverse().find((Y) => Y < a.value - 1);
350
+ s = m !== void 0 ? k.value.indexOf(m) : F.value;
351
+ }
352
+ } else
353
+ s = F.value;
354
+ B.value = s;
355
+ let p;
356
+ if (typeof f.value[s] == "number" ? p = T(f.value[s], {
357
+ max: h.value
358
+ }) : p = z(
359
+ f.value[s],
360
+ h.value
361
+ ), p === 0) {
362
+ x();
363
+ return;
364
+ }
365
+ a.value = p, u.value = 0, v("snapped", f.value.indexOf(f.value[s]));
366
+ }, Ee = () => {
367
+ t.blocking || (N.value = !0, q.value = !0);
368
+ }, He = () => {
369
+ t.blocking || (N.value = !1, q.value = !1);
370
+ }, Ie = () => {
371
+ if (!P.value) return;
372
+ const e = P.value.scrollTop === 0;
373
+ d.value = e;
374
+ }, $e = Je((e) => de(e), {
286
375
  minQuietPeriodMs: t.duration,
287
- reducer: (e, u) => u
376
+ reducer: (e, n) => n
288
377
  });
289
- return q(d, (e, u) => {
290
- if (b.value === !1 || !e || !u) return;
291
- const g = e[I.value], k = u[I.value];
292
- typeof g != "string" && typeof k != "string" && (l.value = y(g, {
293
- max: c.value
294
- }), g !== k && (T = B(w, l.value, {
295
- duration: t.duration / 1e3,
296
- ease: "easeInOut"
297
- })));
298
- }), q(c, () => {
299
- Me.call(I.value);
300
- }), q(K, (e) => {
301
- s("instinctHeight", e);
302
- }), _e(() => {
303
- Y.deactivate();
304
- }), a({ open: X, close: L, snapToPoint: ce }), (e, u) => (ae(), te(De, {
305
- to: e.teleportTo,
306
- defer: e.teleportDefer
307
- }, [
308
- ne("div", Qe, [
309
- $(m(ye), null, {
310
- default: E(() => [
311
- m(b) && e.blocking ? (ae(), te(m(A), {
378
+ U(f, (e, n) => {
379
+ if (C.value === !1 || !e || !n) return;
380
+ const s = e[B.value], p = n[B.value];
381
+ typeof s != "string" && typeof p != "string" && (a.value = T(s, {
382
+ max: h.value
383
+ }));
384
+ }), U(h, () => {
385
+ $e.call(B.value);
386
+ }), U(X, (e) => {
387
+ v("instinctHeight", e);
388
+ }), Ve(() => {
389
+ Z.deactivate();
390
+ });
391
+ const Fe = (e) => {
392
+ const n = e;
393
+ n.style.transition = `transform ${t.duration}ms ease, height ${t.duration}ms ease`, n.style.transform = `translateY(${a.value}px)`;
394
+ };
395
+ return l({ open: te, close: x, snapToPoint: de }), (e, n) => (V(), ae(We, null, [
396
+ (V(), we(Se, {
397
+ to: e.teleportTo,
398
+ defer: e.teleportDefer
399
+ }, [
400
+ Ce(be, { name: "vsbs-backdrop" }, {
401
+ default: ye(() => [
402
+ le(C) && e.blocking ? (V(), ae("div", {
312
403
  key: 0,
313
404
  ref_key: "backdrop",
314
- ref: H,
405
+ ref: M,
315
406
  "data-vsbs-backdrop": "",
316
- onClick: u[0] || (u[0] = (g) => Pe()),
317
- transition: {
318
- ease: "easeInOut",
319
- duration: e.duration / 1e3
320
- },
321
- initial: { opacity: 0 },
322
- animate: { opacity: 1 },
323
- exit: { opacity: 0 }
324
- }, null, 8, ["transition"])) : ge("", !0)
407
+ onClick: n[0] || (n[0] = (s) => Me())
408
+ }, null, 512)) : Pe("", !0)
325
409
  ]),
326
410
  _: 1
327
- }),
328
- $(m(ye), null, {
329
- default: E(() => [
330
- m(b) ? (ae(), te(m(A), {
411
+ })
412
+ ], 8, ["to", "defer"])),
413
+ (V(), we(Se, {
414
+ to: e.teleportTo,
415
+ defer: e.teleportDefer
416
+ }, [
417
+ Ce(be, {
418
+ name: "vsbs-sheet",
419
+ onLeave: Fe
420
+ }, {
421
+ default: ye(() => [
422
+ le(C) ? (V(), ae("div", {
331
423
  key: 0,
332
424
  ref_key: "sheet",
333
- ref: r,
334
- exit: { y: "100%", height: m(P) },
335
- initial: !1,
336
- style: He({ y: m(S), height: m(w) }),
425
+ ref: i,
426
+ style: ze({
427
+ transform: `translateY(${u.value}px)`,
428
+ height: `${a.value}px`,
429
+ transition: E.value ? "none" : `transform ${e.duration}ms ease, height ${e.duration}ms ease`
430
+ }),
337
431
  "data-vsbs-shadow": !e.blocking,
338
- "data-vsbs-sheet-show": m(b),
432
+ "data-vsbs-sheet-show": le(C),
339
433
  "aria-modal": "true",
340
434
  "data-vsbs-sheet": "",
341
435
  tabindex: "-1",
342
- onTouchstart: ke,
343
- onTouchend: xe
344
- }, {
345
- default: E(() => [
346
- $(m(A), {
347
- ref_key: "sheetHeader",
348
- ref: p,
349
- "data-vsbs-header": "",
350
- onPanStart: pe,
351
- onPan: he,
352
- onPanEnd: ee,
353
- onTouchmove: ie,
354
- class: oe(e.headerClass)
355
- }, {
356
- default: E(() => [
357
- le(e.$slots, "header", {}, void 0, !0)
358
- ]),
359
- _: 3
360
- }, 8, ["class"]),
361
- ne("div", {
362
- ref_key: "sheetScroll",
363
- ref: h,
364
- "data-vsbs-scroll": "",
365
- onScrollend: Oe
436
+ onTouchstart: Ee,
437
+ onTouchend: He
438
+ }, [
439
+ W("div", {
440
+ ref_key: "sheetHeader",
441
+ ref: y,
442
+ "data-vsbs-header": "",
443
+ onPointerdown: pe,
444
+ onPointermove: he,
445
+ onPointerup: K,
446
+ onPointercancel: K,
447
+ onTouchmove: ie,
448
+ class: oe(e.headerClass),
449
+ style: { "touch-action": "none" }
450
+ }, [
451
+ ue(e.$slots, "header", {}, void 0, !0)
452
+ ], 34),
453
+ W("div", {
454
+ ref_key: "sheetScroll",
455
+ ref: P,
456
+ "data-vsbs-scroll": "",
457
+ onScrollend: Ie
458
+ }, [
459
+ W("div", {
460
+ ref_key: "sheetContentWrapper",
461
+ ref: w,
462
+ "data-vsbs-content-wrapper": "",
463
+ onPointerdown: Oe,
464
+ onPointermove: Be,
465
+ onPointerup: me,
466
+ onPointercancel: me,
467
+ onTouchmove: ve,
468
+ style: { touchAction: "pan-y" }
366
469
  }, [
367
- $(m(A), {
368
- ref_key: "sheetContentWrapper",
369
- ref: O,
370
- "data-vsbs-content-wrapper": "",
371
- onPanStart: we,
372
- onPan: Te,
373
- onPanEnd: ee,
374
- onTouchmove: ve
375
- }, {
376
- default: E(() => [
377
- ne("div", {
378
- ref_key: "sheetContent",
379
- ref: D,
380
- "data-vsbs-content": "",
381
- class: oe(e.contentClass)
382
- }, [
383
- le(e.$slots, "default", {}, void 0, !0)
384
- ], 2)
385
- ]),
386
- _: 3
387
- }, 512)
388
- ], 544),
389
- $(m(A), {
390
- ref_key: "sheetFooter",
391
- ref: f,
392
- "data-vsbs-footer": "",
393
- onPanStart: pe,
394
- onPan: he,
395
- onPanEnd: ee,
396
- onTouchmove: ie,
397
- class: oe(e.footerClass)
398
- }, {
399
- default: E(() => [
400
- le(e.$slots, "footer", {}, void 0, !0)
401
- ]),
402
- _: 3
403
- }, 8, ["class"])
404
- ]),
405
- _: 3
406
- }, 8, ["exit", "style", "data-vsbs-shadow", "data-vsbs-sheet-show"])) : ge("", !0)
470
+ W("div", {
471
+ ref_key: "sheetContent",
472
+ ref: S,
473
+ "data-vsbs-content": "",
474
+ class: oe(e.contentClass)
475
+ }, [
476
+ ue(e.$slots, "default", {}, void 0, !0)
477
+ ], 2)
478
+ ], 544)
479
+ ], 544),
480
+ W("div", {
481
+ ref_key: "sheetFooter",
482
+ ref: b,
483
+ "data-vsbs-footer": "",
484
+ onPointerdown: pe,
485
+ onPointermove: he,
486
+ onPointerup: K,
487
+ onPointercancel: K,
488
+ onTouchmove: ie,
489
+ class: oe(e.footerClass),
490
+ style: { "touch-action": "none" }
491
+ }, [
492
+ ue(e.$slots, "footer", {}, void 0, !0)
493
+ ], 34)
494
+ ], 44, nt)) : Pe("", !0)
407
495
  ]),
408
496
  _: 3
409
497
  })
410
- ])
411
- ], 8, ["to", "defer"]));
498
+ ], 8, ["to", "defer"]))
499
+ ], 64));
412
500
  }
413
- }), Ke = (n, a) => {
414
- const o = n.__vccOpts || n;
415
- for (const [t, s] of a)
416
- o[t] = s;
417
- return o;
418
- }, Ze = /* @__PURE__ */ Ke(Ge, [["__scopeId", "data-v-ccadc172"]]);
501
+ }), lt = (o, l) => {
502
+ const r = o.__vccOpts || o;
503
+ for (const [t, v] of l)
504
+ r[t] = v;
505
+ return r;
506
+ }, rt = /* @__PURE__ */ lt(at, [["__scopeId", "data-v-ac41efee"]]);
419
507
  export {
420
- Ze as default
508
+ rt as default
421
509
  };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- [data-vsbs-container][data-v-ccadc172]{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;pointer-events:none;z-index:9999;visibility:visible}[data-vsbs-backdrop][data-v-ccadc172]{background-color:var(--vsbs-backdrop-bg, rgba(0, 0, 0, .5));top:0;right:0;bottom:0;left:0;pointer-events:auto;position:fixed;-webkit-user-select:none;user-select:none;will-change:opacity;z-index:1}[data-vsbs-shadow=true][data-v-ccadc172]:before{content:"";z-index:-1;position:absolute;top:0;height:100lvh;width:100%;border-radius:var(--vsbs-border-radius, 16px);box-shadow:0 -5px 60px 0 var(--vsbs-shadow-color, rgba(89, 89, 89, .2))}[data-vsbs-sheet][data-v-ccadc172]{background-color:var(--vsbs-background, #fff);border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-right:1px solid var(--vsbs-outer-border-color, transparent);border-left:1px solid var(--vsbs-outer-border-color, transparent);bottom:0;display:flex;flex-direction:column;left:0;margin-left:auto;margin-right:auto;max-height:inherit;max-width:var(--vsbs-max-width, 640px);pointer-events:all;position:fixed;right:0;width:100%;will-change:height;z-index:2}[data-vsbs-sheet-show=true][data-v-ccadc172]{visibility:visible}[data-vsbs-header][data-v-ccadc172]{box-shadow:0 1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-shrink:0;padding:20px var(--vsbs-padding-x, 16px) 8px;-webkit-user-select:none;user-select:none;z-index:3;border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-top:1px solid var(--vsbs-outer-border-color, transparent)}[data-vsbs-header][data-v-ccadc172]:before{background-color:var(--vsbs-handle-background, rgba(0, 0, 0, .28));border-radius:2px;content:"";display:block;height:4px;left:50%;position:absolute;top:8px;transform:translate(-50%);width:36px}[data-vsbs-header][data-v-ccadc172]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-ccadc172]{box-shadow:0 -1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-grow:0;flex-shrink:0;padding:16px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}[data-vsbs-footer][data-v-ccadc172]:empty{display:none}[data-vsbs-scroll][data-v-ccadc172]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content-wrapper][data-v-ccadc172]{height:100%}[data-vsbs-content][data-v-ccadc172]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}
1
+ [data-vsbs-backdrop][data-v-ac41efee]{background-color:var(--vsbs-backdrop-bg, rgba(0, 0, 0, .5));top:0;right:0;bottom:0;left:0;pointer-events:auto;position:fixed;-webkit-user-select:none;user-select:none;will-change:opacity;--vsbs-duration: var(--55bcd70e)}[data-vsbs-shadow=true][data-v-ac41efee]:before{content:"";z-index:-1;position:absolute;top:0;height:100lvh;width:100%;border-radius:var(--vsbs-border-radius, 16px);box-shadow:0 -5px 60px 0 var(--vsbs-shadow-color, rgba(89, 89, 89, .2))}[data-vsbs-sheet][data-v-ac41efee]{background-color:var(--vsbs-background, #fff);border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-right:1px solid var(--vsbs-outer-border-color, transparent);border-left:1px solid var(--vsbs-outer-border-color, transparent);bottom:0;display:flex;flex-direction:column;left:0;margin-left:auto;margin-right:auto;max-width:var(--vsbs-max-width, 640px);pointer-events:all;position:fixed;right:0;width:100%;will-change:height,transform}[data-vsbs-sheet-show=true][data-v-ac41efee]{visibility:visible}[data-vsbs-header][data-v-ac41efee]{box-shadow:0 1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-shrink:0;padding:20px var(--vsbs-padding-x, 16px) 8px;-webkit-user-select:none;user-select:none;z-index:3;border-top-left-radius:var(--vsbs-border-radius, 16px);border-top-right-radius:var(--vsbs-border-radius, 16px);border-top:1px solid var(--vsbs-outer-border-color, transparent)}[data-vsbs-header][data-v-ac41efee]:before{background-color:var(--vsbs-handle-background, rgba(0, 0, 0, .28));border-radius:2px;content:"";display:block;height:4px;left:50%;position:absolute;top:8px;transform:translate(-50%);width:36px}[data-vsbs-header][data-v-ac41efee]:empty{box-shadow:none;padding:14px var(--vsbs-padding-x, 16px) 10px}[data-vsbs-footer][data-v-ac41efee]{box-shadow:0 -1px 0 var(--vsbs-border-color, rgba(46, 59, 66, .125));flex-grow:0;flex-shrink:0;padding:16px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}[data-vsbs-footer][data-v-ac41efee]:empty{display:none}[data-vsbs-scroll][data-v-ac41efee]{flex-grow:1;overflow-y:auto;overscroll-behavior:none}[data-vsbs-content-wrapper][data-v-ac41efee]{height:100%}[data-vsbs-content][data-v-ac41efee]{display:grid;padding:8px var(--vsbs-padding-x, 16px);-webkit-user-select:none;user-select:none}.vsbs-backdrop-enter-active[data-v-ac41efee],.vsbs-backdrop-leave-active[data-v-ac41efee]{transition:opacity var(--vsbs-duration) ease}.vsbs-backdrop-enter-from[data-v-ac41efee],.vsbs-backdrop-leave-to[data-v-ac41efee]{opacity:0}
package/package.json CHANGED
@@ -32,7 +32,7 @@
32
32
  "url": "https://github.com/megaarmos/vue-spring-bottom-sheet/issues"
33
33
  },
34
34
  "private": false,
35
- "version": "2.5.0",
35
+ "version": "2.6.0-next.1",
36
36
  "type": "module",
37
37
  "exports": {
38
38
  ".": {
@@ -64,7 +64,6 @@
64
64
  "@vueuse/core": "^13.2.0",
65
65
  "@vueuse/integrations": "^13.2.0",
66
66
  "focus-trap": "^7.6.4",
67
- "motion-v": "^1.5.0",
68
67
  "remeda": "^2.21.6",
69
68
  "vue": "^3.5.14"
70
69
  },
@@ -89,6 +88,7 @@
89
88
  "LICENSE"
90
89
  ],
91
90
  "publishConfig": {
92
- "access": "public"
91
+ "access": "public",
92
+ "provenance": true
93
93
  }
94
94
  }