visionary-image 1.0.2 → 1.0.3

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.
package/README.md CHANGED
@@ -2,18 +2,25 @@
2
2
 
3
3
  React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.
4
4
 
5
- ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/visionary-ux/visionary-image/.github%2Fworkflows%2Fci-cd-workflow.yml?branch=master&style=flat-square) ![npm package size (minzipped, via Bundlephobia)](https://img.shields.io/bundlephobia/minzip/visionary-image?style=flat-square&color=blue)
5
+ ![GitHub Release](https://img.shields.io/github/v/release/visionary-ux/visionary-image?color=beige) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/visionary-ux/visionary-image/.github%2Fworkflows%2Fci-cd-workflow.yml?branch=master&style=flat-square)](https://github.com/visionary-ux/visionary-image/actions/workflows/ci-cd-workflow.yml?query=branch%3Amaster) [![npm package size (minzipped, via Bundlephobia)](https://img.shields.io/bundlephobia/minzip/visionary-image?style=flat-square&color=blue)](https://bundlephobia.com/package/visionary-image) [![Storybook demo](https://img.shields.io/badge/-Storybook-FF4785?style=flat-square&logo=storybook&logoColor=white)](https://visionary-ux.github.io/visionary-image/)
6
6
 
7
- **Features:**
7
+ ## Features
8
8
 
9
- - Blurhash data encoded in the image URL via [visionary-url](https://github.com/visionary-ux/visionary-url) for instant image placeholders
10
- - Renders a true-to-size, responsive Blurhash placeholder while the image loads, eliminating Cumulative Layout Shift (CLS)
11
- - Images below the fold are lazily loaded, reducing initial page load size and request count, optimizing Interaction to Next Paint (INP)
12
- - Framework-tested (Remix, Next.js, Vite) with support for both client and server-side rendering (SSR, SSG) environments
13
- - Additional features: Prevent dragging, user-selection of image
14
- - Improves Core Web Vitals scores which Google notes as an important ranking signal in Search.
9
+ - **Easy Blurhash:** Get started with Blurhash in 60 seconds.
10
+ - **Layout stability**: Eliminates Cumulative Layout Shift (CLS) with true-to-size, responsive placeholders.
11
+ - **Automatic lazy loading**: Off-screen images are deferred, reducing initial pageload size and optimizing Interaction to Next Paint (INP).
12
+ - **Lighning-fast previews**: Renders placeholders early (by initial DOM layout) using URL-embedded Blurhash data, powered by [`visionary-url`](https://github.com/visionary-ux/visionary-url).
13
+ - **Framework tested**: Compatible with Remix, Next.js, and Vite and supports both client and server-side rendering (SSR, SSG).
14
+ - **Additional features**: Prevent image dragging; prevent user selecting image
15
+ - **Developer friendly**: Written in Typescript and [unit tested](./src/components/Image/__test__/).
16
+ - Check out the [interactive Storybook sandbox](https://visionary-ux.github.io/visionary-image/)
17
+ - **Search performance**: Enhance search ranking potential by improving Core Web Vitals scores.
18
+ > "We highly recommend site owners achieve good Core Web Vitals for success with Search" — [Google Search Central](https://developers.google.com/search/docs/appearance/core-web-vitals)
15
19
 
16
- > "We highly recommend site owners achieve good Core Web Vitals for success with Search", [Google Search Central](https://developers.google.com/search/docs/appearance/core-web-vitals)
20
+ ### Lighthouse Performance
21
+
22
+ Lighthouse report filmstrip showing three-layer image loading process
23
+ ![Lighthouse report loading stage filmstrip](https://github.com/user-attachments/assets/20fd15ad-6801-4105-b75d-bf12cc8c704e)
17
24
 
18
25
  ## Installation
19
26
 
@@ -25,7 +32,7 @@ npm install --save visionary-image
25
32
 
26
33
  ## Usage
27
34
 
28
- Create a Visionary image URL to get started.
35
+ Begin by creating a Visionary image URL. This is then passed to the `src` prop of the Image component.
29
36
 
30
37
  ### Creating a Visionary Image URL
31
38
 
@@ -40,14 +47,7 @@ There are several ways to create a Visionary URL.
40
47
  ```tsx
41
48
  import { Image } from "visionary-image";
42
49
 
43
- const imageUrl = "<visionary url or code>";
44
- const altText = "Nighttime stroll in Tokyo, neon-lit with a purple glow";
45
-
46
- const App = () => {
47
- <div>
48
- <Image alt={altText} src={imageUrl} />
49
- </div>;
50
- };
50
+ const ImageDetails = () => <Image alt="..." src="<Visionary URL>" />;
51
51
  ```
52
52
 
53
53
  ## Component Props
@@ -60,8 +60,9 @@ const App = () => {
60
60
  | `debug` <br/> boolean | Prints handy debug info to the console (Visionary URL data, render times). |
61
61
  | `disableBlurLayer` <br/> boolean | Disables rendering of the blur (canvas) layer. |
62
62
  | `disableImageLayer` <br/> boolean | Disables rendering of the image layer. |
63
+ | `height` <br/>number, string | If set, will override internally computed image height. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
63
64
  | `hideImageLayer` <br/> boolean | Hides the image layer, revealing the blur layer underneath. |
64
- | `lazy` <br/> boolean | Should image lazily load. <br/> Default: `true` |
65
+ | `lazy` <br/> boolean | Should image load lazily. <br/> Default: `true` |
65
66
  | `onClick` <br/> function | Callback function to invoke when the image is clicked. function. |
66
67
  | `onError` <br/> function | Error callback function. |
67
68
  | `onLoad` <br/> function | Image loaded callback function. |
@@ -69,9 +70,18 @@ const App = () => {
69
70
  | `preventSelection` <br/>boolean | Prevents user from highlighting the image element. |
70
71
  | `punch` <br/>number | Blurhash punch parameter.<br /> Default: `1` |
71
72
  | `src` <br/>string | Visionary URL, Visionary Code, or ordinary image URL.<br/> If `src` contains Visionary data, placeholders will be rendered, otherwise falls back to an `img` element. <br/> **required** |
73
+ | `width` <br/>number, string | If set, will override internally computed image width. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
74
+
75
+ ## Relevant Questions
76
+
77
+ ### Do image placeholders render server-side?
78
+
79
+ Yes, Visionary Image supports server-side rendering (SSR) and static site generation (SSG), as well as client-side rendering. In server-rendered scenarios, the first layer (background color) renders immediately, followed by the Blurhash and image layers once the page loads in the client's browser.
80
+
81
+ ### How long does the Blurhash canvas take to load?
82
+
83
+ Canvas operations are highly efficient in modern browsers. Rendering the 24x24 pixel Blurhash placeholder typically takes around 1ms.
72
84
 
73
- ### More Props
85
+ ### What is Blurhash and where can I learn more?
74
86
 
75
- | | |
76
- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
77
- | `height`, `width` | If set, will override internally computed image dimensions. By default, Visionary renders optimally sized images, using the aspect-ratio and max-width placeholder data. |
87
+ Blurhash uses Discrete Cosine Transforms to represent a color-accurate image placeholder as a compact string (in 20-30 characters). Check out the official [Blurhash docs](https://github.com/woltapp/blurhash) for more info.
@@ -1,10 +1,10 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.id="v7y-styles",e.appendChild(document.createTextNode('.v7y_7587:before{content:"";display:block;padding-top:var(--v-ar)}.v7y_b8c0{-webkit-user-drag:none;pointer-events:none}.v7y_e0dd{-webkit-user-select:none;user-select:none}')),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})();
2
- import { jsx as G, jsxs as vt } from "react/jsx-runtime";
3
- import { useRef as Y, useCallback as q, useState as wt, useEffect as It, useLayoutEffect as Et, useMemo as At } from "react";
2
+ import { jsx as T, jsxs as wt } from "react/jsx-runtime";
3
+ import { useRef as Y, useCallback as q, useState as It, useEffect as Et, useLayoutEffect as Rt, useMemo as At } from "react";
4
4
  function xt(t) {
5
5
  return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
6
6
  }
7
- var nt = { exports: {} };
7
+ var et = { exports: {} };
8
8
  /*!
9
9
  Copyright (c) 2018 Jed Watson.
10
10
  Licensed under the MIT License (MIT), see
@@ -39,43 +39,45 @@ var nt = { exports: {} };
39
39
  }
40
40
  t.exports ? (e.default = e, t.exports = e) : window.classNames = e;
41
41
  })();
42
- })(nt);
43
- var Rt = nt.exports;
44
- const St = /* @__PURE__ */ xt(Rt), Ut = (t, { root: n, rootMargin: e, threshold: o } = {}, i = []) => {
42
+ })(et);
43
+ var Ut = et.exports;
44
+ const Nt = /* @__PURE__ */ xt(Ut), Ot = (t, { root: n, rootMargin: e, threshold: o } = {}, i = []) => {
45
45
  const r = Y(null), s = Y(null);
46
46
  return q((c) => {
47
47
  r.current && s.current && (s.current.unobserve(r.current), s.current.disconnect(), s.current = null), c && (s.current = new IntersectionObserver(t, { root: n, rootMargin: e, threshold: o }), s.current.observe(c), r.current = c);
48
48
  }, [r, n, e, JSON.stringify(o), ...i]);
49
- }, Nt = ({ root: t, rootMargin: n, threshold: e, unobserveOnEnter: o, target: i, onEnter: r, onLeave: s, defaultInView: u } = {}, c = []) => {
50
- const [a, p] = wt({
49
+ }, Tt = ({ root: t, rootMargin: n, threshold: e, unobserveOnEnter: o, target: i, onEnter: r, onLeave: s, defaultInView: u } = {}, c = []) => {
50
+ const [a, p] = It({
51
51
  inView: u || !1,
52
52
  entry: null,
53
53
  observer: null
54
- }), l = q(([h], f) => {
55
- const b = f.thresholds.some((g) => h.intersectionRatio >= g) && h.isIntersecting;
54
+ }), l = q(([h], d) => {
55
+ const b = d.thresholds.some((g) => h.intersectionRatio >= g) && h.isIntersecting;
56
56
  p({
57
57
  inView: b,
58
58
  entry: h,
59
- observer: f
60
- }), b && o && (f.unobserve(h.target), f.disconnect()), b ? r == null || r(h, f) : s == null || s(h, f);
61
- }, [r, s, o]), m = Ut(l, { root: t, rootMargin: n, threshold: e }, [o, ...c]);
62
- return It(() => {
59
+ observer: d
60
+ }), b && o && (d.unobserve(h.target), d.disconnect()), b ? r == null || r(h, d) : s == null || s(h, d);
61
+ }, [r, s, o]), m = Ot(l, { root: t, rootMargin: n, threshold: e }, [o, ...c]);
62
+ return Et(() => {
63
63
  i != null && i.current && m(i.current);
64
64
  }, [i, m]), [m, a.inView, a.entry, a.observer];
65
- };
66
- var V = /* @__PURE__ */ ((t) => (t.AUTO = "auto", t.AVIF = "avif", t.JPEG = "jpeg", t.WEBP = "webp", t))(V || {}), v = /* @__PURE__ */ ((t) => (t.xs = "xs", t.sm = "sm", t.md = "md", t.lg = "lg", t.xl = "xl", t.xxl = "xxl", t["4k"] = "4k", t["5k"] = "5k", t.full = "full", t))(v || {}), T = /* @__PURE__ */ ((t) => (t.DEBUG = "debug", t.DOWNLOAD = "download", t))(T || {});
67
- const Ot = "https://link.visionary.cloud";
68
- V.AUTO, v.lg;
65
+ }, Ct = {
66
+ overflow: "hidden"
67
+ }, Dt = ({ aspectRatio: t, children: n }) => /* @__PURE__ */ T("div", { style: { aspectRatio: t, ...Ct }, children: n });
68
+ var $ = /* @__PURE__ */ ((t) => (t.AUTO = "auto", t.AVIF = "avif", t.JPEG = "jpeg", t.WEBP = "webp", t))($ || {}), w = /* @__PURE__ */ ((t) => (t.xs = "xs", t.sm = "sm", t.md = "md", t.lg = "lg", t.xl = "xl", t.xxl = "xxl", t["4k"] = "4k", t["5k"] = "5k", t.full = "full", t))(w || {}), D = /* @__PURE__ */ ((t) => (t.DEBUG = "debug", t.DOWNLOAD = "download", t))(D || {});
69
+ const Pt = "https://link.visionary.cloud";
70
+ $.AUTO, w.lg;
69
71
  const Z = {
70
- [v.xs]: 160,
71
- [v.sm]: 320,
72
- [v.md]: 640,
73
- [v.lg]: 1280,
74
- [v.xl]: 1920,
75
- [v.xxl]: 2560,
76
- [v["4k"]]: 3840,
77
- [v["5k"]]: 5120,
78
- [v.full]: 0
72
+ [w.xs]: 160,
73
+ [w.sm]: 320,
74
+ [w.md]: 640,
75
+ [w.lg]: 1280,
76
+ [w.xl]: 1920,
77
+ [w.xxl]: 2560,
78
+ [w["4k"]]: 3840,
79
+ [w["5k"]]: 5120,
80
+ [w.full]: 0
79
81
  };
80
82
  Object.keys(Z).reduce(
81
83
  (t, n) => {
@@ -84,118 +86,118 @@ Object.keys(Z).reduce(
84
86
  },
85
87
  {}
86
88
  );
87
- const et = "!";
88
- var Tt = Object.defineProperty, Ct = (t, n, e) => n in t ? Tt(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e, Dt = (t, n, e) => Ct(t, typeof n != "symbol" ? n + "" : n, e), J = {}, $ = {};
89
- Object.defineProperty($, "__esModule", { value: !0 });
90
- function Pt(t) {
89
+ const rt = "!";
90
+ var St = Object.defineProperty, _t = (t, n, e) => n in t ? St(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e, Lt = (t, n, e) => _t(t, typeof n != "symbol" ? n + "" : n, e), J = {}, j = {};
91
+ Object.defineProperty(j, "__esModule", { value: !0 });
92
+ function Vt(t) {
91
93
  return String.fromCharCode(parseInt(t.slice(1), 16));
92
94
  }
93
- function _t(t) {
94
- return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g, Pt));
95
+ function $t(t) {
96
+ return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g, Vt));
95
97
  }
96
- $.encode = _t;
97
- function Lt(t) {
98
+ j.encode = $t;
99
+ function jt(t) {
98
100
  return `%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`;
99
101
  }
100
- function Vt(t) {
101
- return decodeURIComponent(Array.from(atob(t), Lt).join(""));
102
+ function kt(t) {
103
+ return decodeURIComponent(Array.from(atob(t), jt).join(""));
102
104
  }
103
- $.decode = Vt;
105
+ j.decode = kt;
104
106
  Object.defineProperty(J, "__esModule", { value: !0 });
105
- const rt = $;
106
- function $t(t) {
107
- return rt.decode(t.replace(/\-/g, "+").replace(/_/g, "/"));
107
+ const ot = j;
108
+ function zt(t) {
109
+ return ot.decode(t.replace(/\-/g, "+").replace(/_/g, "/"));
108
110
  }
109
- var jt = J.decode = $t;
110
- function kt(t) {
111
- return rt.encode(t).replace(/\//g, "_").replace(/\+/g, "-").replace(/=+$/, "");
111
+ var Bt = J.decode = zt;
112
+ function Mt(t) {
113
+ return ot.encode(t).replace(/\//g, "_").replace(/\+/g, "-").replace(/=+$/, "");
112
114
  }
113
- var zt = J.encode = kt;
114
- const Bt = (t) => t.filter(Boolean), K = (t) => {
115
+ var Wt = J.encode = Mt;
116
+ const Gt = (t) => t.filter(Boolean), Q = (t) => {
115
117
  try {
116
118
  return new URL(t);
117
119
  } catch {
118
120
  return null;
119
121
  }
120
- }, j = (t = "") => /^[A-Za-z0-9_-]*$/.test(t), Mt = (t) => {
122
+ }, k = (t = "") => /^[A-Za-z0-9_-]*$/.test(t), Ft = (t) => {
121
123
  const { altText: n, bcc: e, blurhash: o, blurhashX: i, blurhashY: r, sourceHeight: s, sourceWidth: u, url: c } = t;
122
124
  if (!c || !u || !s)
123
125
  return new Error("Cannot construct visionary code: missing required url/width/height");
124
126
  const a = [c, u, s];
125
- return !e || (a.push(e), !o || !i || !r) || (a.push(o, i, r), n && n.length && a.push(n)), Gt(a);
126
- }, Gt = (t) => zt(t.join(et)), ot = (t) => {
127
+ return !e || (a.push(e), !o || !i || !r) || (a.push(o, i, r), n && n.length && a.push(n)), Ht(a);
128
+ }, Ht = (t) => Wt(t.join(rt)), st = (t) => {
127
129
  if (typeof t != "string")
128
130
  return null;
129
131
  const n = t.trim();
130
- if (!n.length || !j(n))
132
+ if (!n.length || !k(n))
131
133
  return null;
132
- const e = jt(n);
134
+ const e = Bt(n);
133
135
  if (!e)
134
136
  return null;
135
- const o = e.split(et);
137
+ const o = e.split(rt);
136
138
  if (o.length < 3)
137
139
  return null;
138
140
  const [i, r, s, u, c, a, p, l] = o, m = i.trim();
139
141
  if (!m.length)
140
142
  return console.error("Cannot parse code, empty file id"), null;
141
- const h = Number(r.trim()), f = Number(s.trim());
142
- if (isNaN(h) || isNaN(f) || !h || !f)
143
+ const h = Number(r.trim()), d = Number(s.trim());
144
+ if (isNaN(h) || isNaN(d) || !h || !d)
143
145
  return console.error("Cannot parse Visionary Code: invalid image dimensions", r, s), null;
144
- const y = Number(a) ?? 0, b = Number(p) ?? 0;
145
- return y < 1 || b < 1 ? (console.error(
146
+ const v = Number(a) ?? 0, b = Number(p) ?? 0;
147
+ return v < 1 || b < 1 ? (console.error(
146
148
  "Cannot parse Visionary Code: invalid blurhash x, y component dimensions",
147
- y,
149
+ v,
148
150
  b
149
151
  ), null) : {
150
152
  altText: l,
151
153
  bcc: u,
152
154
  blurhash: c,
153
- blurhashX: y,
155
+ blurhashX: v,
154
156
  blurhashY: b,
155
- sourceHeight: f,
157
+ sourceHeight: d,
156
158
  sourceWidth: h,
157
159
  url: m
158
160
  };
159
161
  };
160
- class Wt extends Error {
162
+ class Xt extends Error {
161
163
  constructor() {
162
- super(...arguments), Dt(this, "message", "invalid endpoint URL (does it contain http/https?)");
164
+ super(...arguments), Lt(this, "message", "invalid endpoint URL (does it contain http/https?)");
163
165
  }
164
166
  }
165
- const Ft = (t) => t === T.DEBUG, Ht = (t) => t === T.DOWNLOAD, Xt = (t) => Object.values(V).includes(t), st = (t) => Object.values(v).includes(t), Yt = (t = []) => {
167
+ const Yt = (t) => t === D.DEBUG, Zt = (t) => t === D.DOWNLOAD, qt = (t) => Object.values($).includes(t), ct = (t) => Object.values(w).includes(t), Jt = (t = []) => {
166
168
  const n = {};
167
169
  for (const e of t)
168
- st(e) ? n.size = v[e] : Ft(e) ? n.debug = !0 : Ht(e) ? n.download = !0 : Xt(e) && (n.format = e);
170
+ ct(e) ? n.size = w[e] : Yt(e) ? n.debug = !0 : Zt(e) ? n.download = !0 : qt(e) && (n.format = e);
169
171
  return n;
170
- }, Zt = (t) => {
172
+ }, Kt = (t) => {
171
173
  if (!t || typeof t != "object")
172
174
  return null;
173
175
  const n = [];
174
- return t.debug && n.push(T.DEBUG), t.download && n.push(T.DOWNLOAD), t.format && t.format !== V.AUTO && n.push(t.format), t.size && st(t.size) && n.push(t.size), n.length ? n.sort().join(",") : null;
175
- }, qt = (t) => {
176
- if (j(t)) {
177
- const n = ot(t);
176
+ return t.debug && n.push(D.DEBUG), t.download && n.push(D.DOWNLOAD), t.format && t.format !== $.AUTO && n.push(t.format), t.size && ct(t.size) && n.push(t.size), n.length ? n.sort().join(",") : null;
177
+ }, Qt = (t) => {
178
+ if (k(t)) {
179
+ const n = st(t);
178
180
  if (n)
179
181
  return {
180
182
  fields: n,
181
183
  options: {}
182
184
  };
183
185
  }
184
- return Jt(t);
185
- }, Jt = (t) => {
186
+ return tn(t);
187
+ }, tn = (t) => {
186
188
  if (!t)
187
189
  return null;
188
190
  const n = t.trim();
189
191
  if (!n)
190
192
  return null;
191
193
  try {
192
- const e = Qt(n);
194
+ const e = en(n);
193
195
  if (!e)
194
196
  return null;
195
- const { code: o, optionTokens: i } = e, r = ot(o);
197
+ const { code: o, optionTokens: i } = e, r = st(o);
196
198
  if (!r)
197
199
  return null;
198
- const s = Yt(i);
200
+ const s = Jt(i);
199
201
  return {
200
202
  fields: r,
201
203
  options: s
@@ -204,25 +206,25 @@ const Ft = (t) => t === T.DEBUG, Ht = (t) => t === T.DOWNLOAD, Xt = (t) => Objec
204
206
  e instanceof Error ? console.error(`Error parsing URL: ${e.message}`, e) : console.error("uncaught error", e);
205
207
  }
206
208
  return null;
207
- }, Kt = (t, n) => {
208
- const e = Mt(t);
209
+ }, nn = (t, n) => {
210
+ const e = Ft(t);
209
211
  if (e instanceof Error)
210
212
  return null;
211
213
  let o = null;
212
- if (n != null && n.endpoint && (o = K(n == null ? void 0 : n.endpoint), !o))
213
- throw new Wt(
214
+ if (n != null && n.endpoint && (o = Q(n == null ? void 0 : n.endpoint), !o))
215
+ throw new Xt(
214
216
  "Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://"
215
217
  );
216
- o || (o = K(Ot));
217
- const i = [o.origin, "image", e], r = n ? Zt(n) : null;
218
+ o || (o = Q(Pt));
219
+ const i = [o.origin, "image", e], r = n ? Kt(n) : null;
218
220
  return r && i.push(r), n != null && n.filename ? i.push(n.filename) : i.push("image.jpg"), i.join("/");
219
- }, Qt = (t) => {
221
+ }, en = (t) => {
220
222
  try {
221
- const n = new URL(t), e = Bt(n.pathname.split("/"));
223
+ const n = new URL(t), e = Gt(n.pathname.split("/"));
222
224
  if (e[0] !== "image" || ![3, 4].includes(e.length))
223
225
  throw new Error("Unrecognized URL");
224
226
  const o = e[1].trim();
225
- if (!o.length || !j(o))
227
+ if (!o.length || !k(o))
226
228
  throw new Error("URL is not formatted as base64url");
227
229
  if (e.length === 4) {
228
230
  const i = e[2].split(",");
@@ -240,152 +242,152 @@ const Ft = (t) => t === T.DEBUG, Ht = (t) => t === T.DOWNLOAD, Xt = (t) => Objec
240
242
  return null;
241
243
  }
242
244
  return null;
243
- }, ct = 0.7, it = 1, S = 24, tn = v.lg, at = process.env.NODE_ENV, nn = at === "development", lt = typeof document > "u", en = at === "test", rn = lt ? () => {
244
- } : Et, on = "<visionary>", R = (t, ...n) => {
245
- !console || typeof console.log != "function" || console.log(`${on} ${t}`, ...n);
246
- }, ut = new Uint8Array(128);
245
+ }, it = 0.7, at = 1, U = 24, rn = w.lg, lt = process.env.NODE_ENV, on = lt === "development", ut = typeof document > "u", sn = lt === "test", cn = ut ? () => {
246
+ } : Rt, an = "<visionary>", x = (t, ...n) => {
247
+ !console || typeof console.log != "function" || console.log(`${an} ${t}`, ...n);
248
+ }, dt = new Uint8Array(128);
247
249
  for (let t = 0; t < 83; t++)
248
- ut["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(
250
+ dt["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(
249
251
  t
250
252
  )] = t;
251
- const _ = (t, n, e) => {
253
+ const L = (t, n, e) => {
252
254
  let o = 0;
253
255
  for (; n < e; )
254
- o *= 83, o += ut[t.charCodeAt(n++)];
256
+ o *= 83, o += dt[t.charCodeAt(n++)];
255
257
  return o;
256
- }, ft = Math.pow, C = Math.PI, sn = C * 2, dt = 3294.6, pt = 269.025, cn = (t) => t > 10.31475 ? ft(t / pt + 0.052132, 2.4) : t / dt, W = (t) => ~~(t > 1227e-8 ? pt * ft(t, 0.416666) - 13.025 : t * dt + 1), O = (t) => (t < 0 ? -1 : 1) * t * t, Q = (t) => {
257
- for (t += C / 2; t > C; )
258
- t -= sn;
259
- const n = 1.27323954 * t - 0.405284735 * O(t);
260
- return 0.225 * (O(n) - n) + n;
258
+ }, ft = Math.pow, P = Math.PI, ln = P * 2, pt = 3294.6, ht = 269.025, un = (t) => t > 10.31475 ? ft(t / ht + 0.052132, 2.4) : t / pt, G = (t) => ~~(t > 1227e-8 ? ht * ft(t, 0.416666) - 13.025 : t * pt + 1), C = (t) => (t < 0 ? -1 : 1) * t * t, tt = (t) => {
259
+ for (t += P / 2; t > P; )
260
+ t -= ln;
261
+ const n = 1.27323954 * t - 0.405284735 * C(t);
262
+ return 0.225 * (C(n) - n) + n;
261
263
  };
262
- function an(t) {
263
- const n = _(t, 2, 6);
264
+ function dn(t) {
265
+ const n = L(t, 2, 6);
264
266
  return [n >> 16, n >> 8 & 255, n & 255];
265
267
  }
266
- function ln(t, n, e, o) {
267
- const i = _(t, 0, 1), r = i % 9 + 1, s = ~~(i / 9) + 1, u = r * s;
268
- let c = 0, a = 0, p = 0, l = 0, m = 0, h = 0, f = 0, y = 0, b = 0, g = 0, w = 0, E = 0;
269
- const d = (_(t, 1, 2) + 1) / 13446 * (o | 1), I = new Float64Array(u * 3), k = an(t);
268
+ function fn(t, n, e, o) {
269
+ const i = L(t, 0, 1), r = i % 9 + 1, s = ~~(i / 9) + 1, u = r * s;
270
+ let c = 0, a = 0, p = 0, l = 0, m = 0, h = 0, d = 0, v = 0, b = 0, g = 0, y = 0, E = 0;
271
+ const f = (L(t, 1, 2) + 1) / 13446 * (o | 1), I = new Float64Array(u * 3), z = dn(t);
270
272
  for (c = 0; c < 3; c++)
271
- I[c] = cn(k[c]);
273
+ I[c] = un(z[c]);
272
274
  for (c = 1; c < u; c++)
273
- E = _(t, 4 + c * 2, 6 + c * 2), I[c * 3] = O(~~(E / 361) - 9) * d, I[c * 3 + 1] = O(~~(E / 19) % 19 - 9) * d, I[c * 3 + 2] = O(E % 19 - 9) * d;
274
- const D = new Float64Array(s * e), P = new Float64Array(r * n);
275
+ E = L(t, 4 + c * 2, 6 + c * 2), I[c * 3] = C(~~(E / 361) - 9) * f, I[c * 3 + 1] = C(~~(E / 19) % 19 - 9) * f, I[c * 3 + 2] = C(E % 19 - 9) * f;
276
+ const S = new Float64Array(s * e), _ = new Float64Array(r * n);
275
277
  for (a = 0; a < s; a++)
276
278
  for (l = 0; l < e; l++)
277
- D[a * e + l] = Q(C * l * a / e);
279
+ S[a * e + l] = tt(P * l * a / e);
278
280
  for (c = 0; c < r; c++)
279
281
  for (p = 0; p < n; p++)
280
- P[c * n + p] = Q(C * p * c / n);
281
- const U = n * 4, A = new Uint8ClampedArray(U * e);
282
+ _[c * n + p] = tt(P * p * c / n);
283
+ const N = n * 4, R = new Uint8ClampedArray(N * e);
282
284
  for (l = 0; l < e; l++)
283
285
  for (p = 0; p < n; p++) {
284
- for (m = h = f = 0, a = 0; a < s; a++)
285
- for (b = D[a * e + l], c = 0; c < r; c++)
286
- y = P[c * n + p] * b, g = (c + a * r) * 3, m += I[g] * y, h += I[g + 1] * y, f += I[g + 2] * y;
287
- w = 4 * p + l * U, A[w] = W(m), A[w + 1] = W(h), A[w + 2] = W(f), A[w + 3] = 255;
286
+ for (m = h = d = 0, a = 0; a < s; a++)
287
+ for (b = S[a * e + l], c = 0; c < r; c++)
288
+ v = _[c * n + p] * b, g = (c + a * r) * 3, m += I[g] * v, h += I[g + 1] * v, d += I[g + 2] * v;
289
+ y = 4 * p + l * N, R[y] = G(m), R[y + 1] = G(h), R[y + 2] = G(d), R[y + 3] = 255;
288
290
  }
289
- return A;
291
+ return R;
290
292
  }
291
- const L = (t) => {
293
+ const V = (t) => {
292
294
  try {
293
295
  return new URL(t);
294
296
  } catch {
295
297
  return null;
296
298
  }
297
- }, un = (t, n) => `rgba(${t.r},${t.g},${t.b},${n})`, F = (t) => nn || en ? {
299
+ }, pn = (t, n) => `rgba(${t.r},${t.g},${t.b},${n})`, F = (t) => on || sn ? {
298
300
  "data-testid": t
299
- } : {}, fn = (t, n) => n ? {
301
+ } : {}, hn = (t, n) => n ? {
300
302
  "data-fileid": t
301
- } : {}, tt = (t, n) => Math.min(t, n), dn = (t) => {
303
+ } : {}, nt = (t, n) => Math.min(t, n), mn = (t) => {
302
304
  let n = t.replace(/^#/, "");
303
305
  if (n.length !== 3 && n.length !== 6)
304
306
  return null;
305
307
  n.length === 3 && (n = `${n[0]}${n[0]}${n[1]}${n[1]}${n[2]}${n[2]}`);
306
308
  const e = parseInt(n.slice(0, 2), 16), o = parseInt(n.slice(2, 4), 16);
307
309
  return { b: parseInt(n.slice(4, 6), 16), g: o, r: e };
308
- }, x = (t, n = 0) => {
310
+ }, A = (t, n = 0) => {
309
311
  const e = Math.pow(10, n);
310
312
  return Math.round(t * e) / e;
311
- }, pn = (t, n) => {
312
- const e = L(t), o = L(n);
313
+ }, gn = (t, n) => {
314
+ const e = V(t), o = V(n);
313
315
  return !e || !o ? t : (o.pathname = e.pathname, o.search = e.search, o.toString());
314
- }, hn = (t, n = {}, e = ct, o = it) => {
316
+ }, bn = (t, n = {}, e = it, o = at) => {
315
317
  if (!t)
316
318
  return null;
317
319
  try {
318
- n.debug && R("input imageSrc:", t);
319
- const i = qt(t);
320
- if (n.debug && R("Visionary URL data: ", i), !i)
320
+ n.debug && x("input imageSrc:", t);
321
+ const i = Qt(t);
322
+ if (n.debug && x("Visionary URL data: ", i), !i)
321
323
  throw new Error("Could not parse Visionary URL");
322
324
  const { fields: r, options: s } = i;
323
325
  if (r.sourceWidth < 1 || r.sourceHeight < 1)
324
326
  throw new Error("Invalid image dimensions");
325
- const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ?? tn, a = Z[c];
327
+ const u = r.sourceWidth / r.sourceHeight, c = (n == null ? void 0 : n.size) ?? s.size ?? rn, a = Z[c];
326
328
  let p = 0, l = 0, m = 0;
327
329
  if (u >= 1) {
328
- l = p = tt(a, r.sourceWidth);
329
- const g = x(l / u);
330
- m = x(l / g, 6);
330
+ l = p = nt(a, r.sourceWidth);
331
+ const g = A(l / u);
332
+ m = A(l / g, 6);
331
333
  } else
332
- p = tt(a, r.sourceHeight), l = x(p * u), m = x(l / p, 6);
333
- const h = x(100 / m, 6), f = {
334
+ p = nt(a, r.sourceHeight), l = A(p * u), m = A(l / p, 6);
335
+ const h = A(100 / m, 6), d = {
334
336
  ...r,
335
337
  arPaddingTop: `${h}%`,
336
338
  aspectRatio: m,
337
339
  maxWidth: l,
338
340
  src: t
339
- }, y = L(r.url);
340
- if (y)
341
- f.src = y.toString();
342
- else if (!L(t) && j(r.url)) {
343
- const g = Kt(r, {
341
+ }, v = V(r.url);
342
+ if (v)
343
+ d.src = v.toString();
344
+ else if (!V(t) && k(r.url)) {
345
+ const g = nn(r, {
344
346
  endpoint: n.endpoint,
345
347
  size: c
346
348
  });
347
- g && (f.src = g);
349
+ g && (d.src = g);
348
350
  }
349
- n.endpoint && (f.src = pn(f.src, n.endpoint));
350
- const b = r.bcc ? dn(r.bcc) : null;
351
- if (b && (f.backgroundColor = un(b, e)), !lt && r.blurhash && !n.disableBlurLayer) {
352
- const g = performance.now(), w = ln(r.blurhash, S, S, o), E = performance.now() - g;
353
- n.debug && R(`Blurhash decode time: ${x(E, 1)} ms`), w && (f.pixels = w);
351
+ n.endpoint && (d.src = gn(d.src, n.endpoint));
352
+ const b = r.bcc ? mn(r.bcc) : null;
353
+ if (b && (d.backgroundColor = pn(b, e)), !ut && r.blurhash && !n.disableBlurLayer) {
354
+ const g = performance.now(), y = fn(r.blurhash, U, U, o), E = performance.now() - g;
355
+ n.debug && x(`Blurhash decode time: ${A(E, 1)} ms`), y && (d.pixels = y);
354
356
  }
355
- return n.debug && R("Visionary Image state: ", f), f;
357
+ return n.debug && x("Visionary Image state: ", d), d;
356
358
  } catch {
357
359
  return null;
358
360
  }
359
- }, ht = {
361
+ }, mt = {
360
362
  bottom: 0,
361
363
  left: 0,
362
364
  position: "absolute",
363
365
  right: 0,
364
366
  top: 0
365
- }, mn = {
366
- ...ht,
367
+ }, vn = {
368
+ ...mt,
367
369
  maxHeight: "100%",
368
370
  maxWidth: "100%"
369
- }, gn = {
370
- ...ht,
371
+ }, yn = {
372
+ ...mt,
371
373
  height: "100%",
372
374
  width: "100%"
373
- }, bn = (t) => {
375
+ }, wn = (t) => {
374
376
  const n = {
375
- ...mn
377
+ ...vn
376
378
  };
377
379
  return t && (n.display = "none"), n;
378
380
  }, H = {
379
381
  CANVAS: "canvas",
380
382
  CONTAINER: "container",
381
383
  IMAGE: "image"
382
- }, yn = "v7y_7587", vn = "v7y_b8c0", wn = "v7y_e0dd", X = {
383
- container: yn,
384
- preventDrag: vn,
385
- preventSelection: wn
386
- }, Rn = ({
384
+ }, In = "v7y_7587", En = "v7y_b8c0", Rn = "v7y_e0dd", X = {
385
+ container: In,
386
+ preventDrag: En,
387
+ preventSelection: Rn
388
+ }, On = ({
387
389
  alt: t,
388
- bgColorAlpha: n = ct,
390
+ bgColorAlpha: n = it,
389
391
  className: e,
390
392
  debug: o = !1,
391
393
  disableBlurLayer: i = !1,
@@ -398,121 +400,121 @@ const L = (t) => {
398
400
  onError: l,
399
401
  onLoad: m,
400
402
  preventDrag: h = !1,
401
- preventSelection: f = !1,
402
- punch: y = it,
403
+ preventSelection: d = !1,
404
+ punch: v = at,
403
405
  size: b,
404
406
  src: g,
405
- style: w,
407
+ style: y,
406
408
  width: E
407
409
  }) => {
408
- const d = At(() => hn(g, {
410
+ const f = At(() => bn(g, {
409
411
  debug: o,
410
412
  disableBlurLayer: i,
411
413
  endpoint: s,
412
414
  size: b
413
- }, n, y), [n, o, i, s, y, b, g]), I = Y(null), [k, D] = Nt();
414
- rn(
415
+ }, n, v), [n, o, i, s, v, b, g]), I = Y(null), [z, S] = Tt();
416
+ cn(
415
417
  function() {
416
- if (!I.current || !(d != null && d.blurhash))
418
+ if (!I.current || !(f != null && f.blurhash))
417
419
  return;
418
- if (!d.pixels) {
420
+ if (!f.pixels) {
419
421
  console.warn("No pixel data passed in, skipping");
420
422
  return;
421
423
  }
422
- const bt = performance.now(), B = I.current.getContext("2d");
423
- if (!B) {
424
+ const vt = performance.now(), M = I.current.getContext("2d");
425
+ if (!M) {
424
426
  console.warn("Cannot access canvasRenderingContext, skipping");
425
427
  return;
426
428
  }
427
- const M = B.createImageData(S, S);
428
- if (!M) {
429
+ const W = M.createImageData(U, U);
430
+ if (!W) {
429
431
  console.warn("Could not create ImageData on CanvasRenderingContext");
430
432
  return;
431
433
  }
432
- if (M.data.set(d.pixels), B.putImageData(M, 0, 0), o) {
433
- const yt = performance.now() - bt;
434
- R(`Canvas render time: ${x(yt, 1)} ms`);
434
+ if (W.data.set(f.pixels), M.putImageData(W, 0, 0), o) {
435
+ const yt = performance.now() - vt;
436
+ x(`Canvas render time: ${A(yt, 1)} ms`);
435
437
  }
436
438
  },
437
- [d == null ? void 0 : d.blurhash, d == null ? void 0 : d.pixels, o]
439
+ [f == null ? void 0 : f.blurhash, f == null ? void 0 : f.pixels, o]
438
440
  );
439
- const P = q(
440
- (N) => {
441
- o && R("Image load error ", N), l && l();
441
+ const _ = q(
442
+ (O) => {
443
+ o && x("Image load error ", O), l && l();
442
444
  },
443
445
  [o, l]
444
- ), U = {
446
+ ), N = {
445
447
  alt: t,
446
- loading: !a || D ? "eager" : "lazy",
448
+ loading: !a || S ? "eager" : "lazy",
447
449
  onLoad: m
448
450
  };
449
- if (!d) {
450
- o && R("Not a Visionary URL, rendering fallback <img />");
451
- const N = {
452
- ...U,
451
+ if (!f) {
452
+ o && x("Not a Visionary URL, rendering fallback <img />");
453
+ const O = {
454
+ ...N,
453
455
  className: e,
454
456
  height: u,
455
457
  onClick: p,
456
458
  onError: l,
457
459
  src: g,
458
- style: w,
460
+ style: y,
459
461
  width: E
460
462
  };
461
- return /* @__PURE__ */ G("img", { ...N });
463
+ return /* @__PURE__ */ T("img", { ...O });
462
464
  }
463
- const A = St(X.container, e, {
465
+ const R = Nt(X.container, e, {
464
466
  [X.preventDrag]: !!h,
465
- [X.preventSelection]: !!f
466
- }), z = {
467
+ [X.preventSelection]: !!d
468
+ }), B = {
467
469
  ...{
468
- "--v-ar": d.arPaddingTop
470
+ "--v-ar": f.arPaddingTop
469
471
  },
470
- aspectRatio: d.aspectRatio,
471
- backgroundColor: (d == null ? void 0 : d.backgroundColor) ?? void 0,
472
- maxWidth: d.maxWidth,
472
+ ...y,
473
+ aspectRatio: f.aspectRatio,
474
+ backgroundColor: (f == null ? void 0 : f.backgroundColor) ?? void 0,
475
+ maxWidth: f.maxWidth,
473
476
  position: "relative",
474
- width: "100%",
475
- ...w
477
+ width: "100%"
476
478
  };
477
- E && (z.width = E), u && (z.height = u);
478
- const mt = {
479
+ E && (B.width = E), u && (B.height = u);
480
+ const gt = {
479
481
  onClick: p
480
- }, gt = bn(c);
481
- return /* @__PURE__ */ vt(
482
+ }, bt = wn(c), K = /* @__PURE__ */ wt(
482
483
  "div",
483
484
  {
484
- className: A,
485
- ref: k,
486
- style: z,
487
- ...fn(d.url, o),
485
+ className: R,
486
+ ref: z,
487
+ style: B,
488
+ ...hn(f.url, o),
488
489
  ...F(H.CONTAINER),
489
- ...mt,
490
+ ...gt,
490
491
  children: [
491
- !i && /* @__PURE__ */ G(
492
+ !i && /* @__PURE__ */ T(
492
493
  "canvas",
493
494
  {
494
- height: S,
495
+ height: U,
495
496
  ref: I,
496
- style: gn,
497
- width: S,
497
+ style: yn,
498
+ width: U,
498
499
  ...F(H.CANVAS)
499
500
  }
500
501
  ),
501
502
  !r && // eslint-disable-next-line jsx-a11y/alt-text -- `sharedImgProps` includes alt tag
502
- /* @__PURE__ */ G(
503
+ /* @__PURE__ */ T(
503
504
  "img",
504
505
  {
505
- ...U,
506
+ ...N,
506
507
  ...F(H.IMAGE),
507
- onError: P,
508
- src: d.src,
509
- style: gt
508
+ onError: _,
509
+ src: f.src,
510
+ style: bt
510
511
  }
511
512
  )
512
513
  ]
513
514
  }
514
515
  );
516
+ return y != null && y.aspectRatio ? /* @__PURE__ */ T(Dt, { aspectRatio: y.aspectRatio, children: K }) : K;
515
517
  };
516
518
  export {
517
- Rn as Image
519
+ On as Image
518
520
  };
@@ -1,6 +1,6 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.id="v7y-styles",e.appendChild(document.createTextNode('.v7y_7587:before{content:"";display:block;padding-top:var(--v-ar)}.v7y_b8c0{-webkit-user-drag:none;pointer-events:none}.v7y_e0dd{-webkit-user-select:none;user-select:none}')),document.head.appendChild(e)}}catch(n){console.error("vite-plugin-css-injected-by-js",n)}})();
2
- (function(A,R){typeof exports=="object"&&typeof module<"u"?R(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],R):(A=typeof globalThis<"u"?globalThis:A||self,R(A.VisionaryImage={},A.jsxRuntime,A.React))})(this,function(A,R,x){"use strict";function me(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var K={exports:{}};/*!
2
+ (function(R,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],x):(R=typeof globalThis<"u"?globalThis:R||self,x(R.VisionaryImage={},R.jsxRuntime,R.React))})(this,function(R,x,E){"use strict";function gt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var K={exports:{}};/*!
3
3
  Copyright (c) 2018 Jed Watson.
4
4
  Licensed under the MIT License (MIT), see
5
5
  http://jedwatson.github.io/classnames
6
- */(function(e){(function(){var t={}.hasOwnProperty;function n(){for(var r="",s=0;s<arguments.length;s++){var u=arguments[s];u&&(r=i(r,o(u)))}return r}function o(r){if(typeof r=="string"||typeof r=="number")return r;if(typeof r!="object")return"";if(Array.isArray(r))return n.apply(null,r);if(r.toString!==Object.prototype.toString&&!r.toString.toString().includes("[native code]"))return r.toString();var s="";for(var u in r)t.call(r,u)&&r[u]&&(s=i(s,u));return s}function i(r,s){return s?r?r+" "+s:r+s:r}e.exports?(n.default=n,e.exports=n):window.classNames=n})()})(K);var ge=K.exports;const be=me(ge),ye=(e,{root:t,rootMargin:n,threshold:o}={},i=[])=>{const r=x.useRef(null),s=x.useRef(null);return x.useCallback(c=>{r.current&&s.current&&(s.current.unobserve(r.current),s.current.disconnect(),s.current=null),c&&(s.current=new IntersectionObserver(e,{root:t,rootMargin:n,threshold:o}),s.current.observe(c),r.current=c)},[r,t,n,JSON.stringify(o),...i])},ve=({root:e,rootMargin:t,threshold:n,unobserveOnEnter:o,target:i,onEnter:r,onLeave:s,defaultInView:u}={},c=[])=>{const[a,p]=x.useState({inView:u||!1,entry:null,observer:null}),l=x.useCallback(([h],f)=>{const b=f.thresholds.some(g=>h.intersectionRatio>=g)&&h.isIntersecting;p({inView:b,entry:h,observer:f}),b&&o&&(f.unobserve(h.target),f.disconnect()),b?r==null||r(h,f):s==null||s(h,f)},[r,s,o]),m=ye(l,{root:e,rootMargin:t,threshold:n},[o,...c]);return x.useEffect(()=>{i!=null&&i.current&&m(i.current)},[i,m]),[m,a.inView,a.entry,a.observer]};var j=(e=>(e.AUTO="auto",e.AVIF="avif",e.JPEG="jpeg",e.WEBP="webp",e))(j||{}),v=(e=>(e.xs="xs",e.sm="sm",e.md="md",e.lg="lg",e.xl="xl",e.xxl="xxl",e["4k"]="4k",e["5k"]="5k",e.full="full",e))(v||{}),O=(e=>(e.DEBUG="debug",e.DOWNLOAD="download",e))(O||{});const we="https://link.visionary.cloud";j.AUTO,v.lg;const M={[v.xs]:160,[v.sm]:320,[v.md]:640,[v.lg]:1280,[v.xl]:1920,[v.xxl]:2560,[v["4k"]]:3840,[v["5k"]]:5120,[v.full]:0};Object.keys(M).reduce((e,t)=>{const n=t,o=M[n];return o&&(e[o]=n),e},{});const Q="!";var Ie=Object.defineProperty,xe=(e,t,n)=>t in e?Ie(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Ee=(e,t,n)=>xe(e,typeof t!="symbol"?t+"":t,n),G={},V={};Object.defineProperty(V,"__esModule",{value:!0});function Ae(e){return String.fromCharCode(parseInt(e.slice(1),16))}function Re(e){return btoa(encodeURIComponent(e).replace(/%[0-9A-F]{2}/g,Ae))}V.encode=Re;function Se(e){return`%${`00${e.charCodeAt(0).toString(16)}`.slice(-2)}`}function Te(e){return decodeURIComponent(Array.from(atob(e),Se).join(""))}V.decode=Te,Object.defineProperty(G,"__esModule",{value:!0});const ee=V;function Ue(e){return ee.decode(e.replace(/\-/g,"+").replace(/_/g,"/"))}var Ne=G.decode=Ue;function Oe(e){return ee.encode(e).replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,"")}var Ce=G.encode=Oe;const De=e=>e.filter(Boolean),te=e=>{try{return new URL(e)}catch{return null}},L=(e="")=>/^[A-Za-z0-9_-]*$/.test(e),Pe=e=>{const{altText:t,bcc:n,blurhash:o,blurhashX:i,blurhashY:r,sourceHeight:s,sourceWidth:u,url:c}=e;if(!c||!u||!s)return new Error("Cannot construct visionary code: missing required url/width/height");const a=[c,u,s];return!n||(a.push(n),!o||!i||!r)||(a.push(o,i,r),t&&t.length&&a.push(t)),_e(a)},_e=e=>Ce(e.join(Q)),ne=e=>{if(typeof e!="string")return null;const t=e.trim();if(!t.length||!L(t))return null;const n=Ne(t);if(!n)return null;const o=n.split(Q);if(o.length<3)return null;const[i,r,s,u,c,a,p,l]=o,m=i.trim();if(!m.length)return console.error("Cannot parse code, empty file id"),null;const h=Number(r.trim()),f=Number(s.trim());if(isNaN(h)||isNaN(f)||!h||!f)return console.error("Cannot parse Visionary Code: invalid image dimensions",r,s),null;const y=Number(a)??0,b=Number(p)??0;return y<1||b<1?(console.error("Cannot parse Visionary Code: invalid blurhash x, y component dimensions",y,b),null):{altText:l,bcc:u,blurhash:c,blurhashX:y,blurhashY:b,sourceHeight:f,sourceWidth:h,url:m}};class je extends Error{constructor(){super(...arguments),Ee(this,"message","invalid endpoint URL (does it contain http/https?)")}}const Ve=e=>e===O.DEBUG,Le=e=>e===O.DOWNLOAD,$e=e=>Object.values(j).includes(e),re=e=>Object.values(v).includes(e),ke=(e=[])=>{const t={};for(const n of e)re(n)?t.size=v[n]:Ve(n)?t.debug=!0:Le(n)?t.download=!0:$e(n)&&(t.format=n);return t},ze=e=>{if(!e||typeof e!="object")return null;const t=[];return e.debug&&t.push(O.DEBUG),e.download&&t.push(O.DOWNLOAD),e.format&&e.format!==j.AUTO&&t.push(e.format),e.size&&re(e.size)&&t.push(e.size),t.length?t.sort().join(","):null},Be=e=>{if(L(e)){const t=ne(e);if(t)return{fields:t,options:{}}}return Me(e)},Me=e=>{if(!e)return null;const t=e.trim();if(!t)return null;try{const n=We(t);if(!n)return null;const{code:o,optionTokens:i}=n,r=ne(o);if(!r)return null;const s=ke(i);return{fields:r,options:s}}catch(n){n instanceof Error?console.error(`Error parsing URL: ${n.message}`,n):console.error("uncaught error",n)}return null},Ge=(e,t)=>{const n=Pe(e);if(n instanceof Error)return null;let o=null;if(t!=null&&t.endpoint&&(o=te(t==null?void 0:t.endpoint),!o))throw new je("Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://");o||(o=te(we));const i=[o.origin,"image",n],r=t?ze(t):null;return r&&i.push(r),t!=null&&t.filename?i.push(t.filename):i.push("image.jpg"),i.join("/")},We=e=>{try{const t=new URL(e),n=De(t.pathname.split("/"));if(n[0]!=="image"||![3,4].includes(n.length))throw new Error("Unrecognized URL");const o=n[1].trim();if(!o.length||!L(o))throw new Error("URL is not formatted as base64url");if(n.length===4){const i=n[2].split(",");return{code:o,optionTokens:i}}if(n.length===3)return{code:o,optionTokens:[]}}catch{return null}return null},oe=.7,se=1,N=24,Fe=v.lg,ce=process.env.NODE_ENV,He=ce==="development",ie=typeof document>"u",Xe=ce==="test",Ye=ie?()=>{}:x.useLayoutEffect,qe="<visionary>",S=(e,...t)=>{!console||typeof console.log!="function"||console.log(`${qe} ${e}`,...t)},ae=new Uint8Array(128);for(let e=0;e<83;e++)ae["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(e)]=e;const $=(e,t,n)=>{let o=0;for(;t<n;)o*=83,o+=ae[e.charCodeAt(t++)];return o},le=Math.pow,C=Math.PI,Ze=C*2,ue=3294.6,fe=269.025,Je=e=>e>10.31475?le(e/fe+.052132,2.4):e/ue,W=e=>~~(e>1227e-8?fe*le(e,.416666)-13.025:e*ue+1),D=e=>(e<0?-1:1)*e*e,de=e=>{for(e+=C/2;e>C;)e-=Ze;const t=1.27323954*e-.405284735*D(e);return .225*(D(t)-t)+t};function Ke(e){const t=$(e,2,6);return[t>>16,t>>8&255,t&255]}function Qe(e,t,n,o){const i=$(e,0,1),r=i%9+1,s=~~(i/9)+1,u=r*s;let c=0,a=0,p=0,l=0,m=0,h=0,f=0,y=0,b=0,g=0,w=0,E=0;const d=($(e,1,2)+1)/13446*(o|1),I=new Float64Array(u*3),Y=Ke(e);for(c=0;c<3;c++)I[c]=Je(Y[c]);for(c=1;c<u;c++)E=$(e,4+c*2,6+c*2),I[c*3]=D(~~(E/361)-9)*d,I[c*3+1]=D(~~(E/19)%19-9)*d,I[c*3+2]=D(E%19-9)*d;const z=new Float64Array(s*n),B=new Float64Array(r*t);for(a=0;a<s;a++)for(l=0;l<n;l++)z[a*n+l]=de(C*l*a/n);for(c=0;c<r;c++)for(p=0;p<t;p++)B[c*t+p]=de(C*p*c/t);const P=t*4,U=new Uint8ClampedArray(P*n);for(l=0;l<n;l++)for(p=0;p<t;p++){for(m=h=f=0,a=0;a<s;a++)for(b=z[a*n+l],c=0;c<r;c++)y=B[c*t+p]*b,g=(c+a*r)*3,m+=I[g]*y,h+=I[g+1]*y,f+=I[g+2]*y;w=4*p+l*P,U[w]=W(m),U[w+1]=W(h),U[w+2]=W(f),U[w+3]=255}return U}const k=e=>{try{return new URL(e)}catch{return null}},et=(e,t)=>`rgba(${e.r},${e.g},${e.b},${t})`,F=e=>He||Xe?{"data-testid":e}:{},tt=(e,t)=>t?{"data-fileid":e}:{},pe=(e,t)=>Math.min(e,t),nt=e=>{let t=e.replace(/^#/,"");if(t.length!==3&&t.length!==6)return null;t.length===3&&(t=`${t[0]}${t[0]}${t[1]}${t[1]}${t[2]}${t[2]}`);const n=parseInt(t.slice(0,2),16),o=parseInt(t.slice(2,4),16);return{b:parseInt(t.slice(4,6),16),g:o,r:n}},T=(e,t=0)=>{const n=Math.pow(10,t);return Math.round(e*n)/n},rt=(e,t)=>{const n=k(e),o=k(t);return!n||!o?e:(o.pathname=n.pathname,o.search=n.search,o.toString())},ot=(e,t={},n=oe,o=se)=>{if(!e)return null;try{t.debug&&S("input imageSrc:",e);const i=Be(e);if(t.debug&&S("Visionary URL data: ",i),!i)throw new Error("Could not parse Visionary URL");const{fields:r,options:s}=i;if(r.sourceWidth<1||r.sourceHeight<1)throw new Error("Invalid image dimensions");const u=r.sourceWidth/r.sourceHeight,c=(t==null?void 0:t.size)??s.size??Fe,a=M[c];let p=0,l=0,m=0;if(u>=1){l=p=pe(a,r.sourceWidth);const g=T(l/u);m=T(l/g,6)}else p=pe(a,r.sourceHeight),l=T(p*u),m=T(l/p,6);const h=T(100/m,6),f={...r,arPaddingTop:`${h}%`,aspectRatio:m,maxWidth:l,src:e},y=k(r.url);if(y)f.src=y.toString();else if(!k(e)&&L(r.url)){const g=Ge(r,{endpoint:t.endpoint,size:c});g&&(f.src=g)}t.endpoint&&(f.src=rt(f.src,t.endpoint));const b=r.bcc?nt(r.bcc):null;if(b&&(f.backgroundColor=et(b,n)),!ie&&r.blurhash&&!t.disableBlurLayer){const g=performance.now(),w=Qe(r.blurhash,N,N,o),E=performance.now()-g;t.debug&&S(`Blurhash decode time: ${T(E,1)} ms`),w&&(f.pixels=w)}return t.debug&&S("Visionary Image state: ",f),f}catch{return null}},he={bottom:0,left:0,position:"absolute",right:0,top:0},st={...he,maxHeight:"100%",maxWidth:"100%"},ct={...he,height:"100%",width:"100%"},it=e=>{const t={...st};return e&&(t.display="none"),t},H={CANVAS:"canvas",CONTAINER:"container",IMAGE:"image"},X={container:"v7y_7587",preventDrag:"v7y_b8c0",preventSelection:"v7y_e0dd"},at=({alt:e,bgColorAlpha:t=oe,className:n,debug:o=!1,disableBlurLayer:i=!1,disableImageLayer:r=!1,endpoint:s,height:u,hideImageLayer:c=!1,lazy:a=!0,onClick:p,onError:l,onLoad:m,preventDrag:h=!1,preventSelection:f=!1,punch:y=se,size:b,src:g,style:w,width:E})=>{const d=x.useMemo(()=>ot(g,{debug:o,disableBlurLayer:i,endpoint:s,size:b},t,y),[t,o,i,s,y,b,g]),I=x.useRef(null),[Y,z]=ve();Ye(function(){if(!I.current||!(d!=null&&d.blurhash))return;if(!d.pixels){console.warn("No pixel data passed in, skipping");return}const ft=performance.now(),Z=I.current.getContext("2d");if(!Z){console.warn("Cannot access canvasRenderingContext, skipping");return}const J=Z.createImageData(N,N);if(!J){console.warn("Could not create ImageData on CanvasRenderingContext");return}if(J.data.set(d.pixels),Z.putImageData(J,0,0),o){const dt=performance.now()-ft;S(`Canvas render time: ${T(dt,1)} ms`)}},[d==null?void 0:d.blurhash,d==null?void 0:d.pixels,o]);const B=x.useCallback(_=>{o&&S("Image load error ",_),l&&l()},[o,l]),P={alt:e,loading:!a||z?"eager":"lazy",onLoad:m};if(!d){o&&S("Not a Visionary URL, rendering fallback <img />");const _={...P,className:n,height:u,onClick:p,onError:l,src:g,style:w,width:E};return R.jsx("img",{..._})}const U=be(X.container,n,{[X.preventDrag]:!!h,[X.preventSelection]:!!f}),q={...{"--v-ar":d.arPaddingTop},aspectRatio:d.aspectRatio,backgroundColor:(d==null?void 0:d.backgroundColor)??void 0,maxWidth:d.maxWidth,position:"relative",width:"100%",...w};E&&(q.width=E),u&&(q.height=u);const lt={onClick:p},ut=it(c);return R.jsxs("div",{className:U,ref:Y,style:q,...tt(d.url,o),...F(H.CONTAINER),...lt,children:[!i&&R.jsx("canvas",{height:N,ref:I,style:ct,width:N,...F(H.CANVAS)}),!r&&R.jsx("img",{...P,...F(H.IMAGE),onError:B,src:d.src,style:ut})]})};A.Image=at,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
6
+ */(function(t){(function(){var e={}.hasOwnProperty;function n(){for(var r="",s=0;s<arguments.length;s++){var u=arguments[s];u&&(r=i(r,o(u)))}return r}function o(r){if(typeof r=="string"||typeof r=="number")return r;if(typeof r!="object")return"";if(Array.isArray(r))return n.apply(null,r);if(r.toString!==Object.prototype.toString&&!r.toString.toString().includes("[native code]"))return r.toString();var s="";for(var u in r)e.call(r,u)&&r[u]&&(s=i(s,u));return s}function i(r,s){return s?r?r+" "+s:r+s:r}t.exports?(n.default=n,t.exports=n):window.classNames=n})()})(K);var bt=K.exports;const vt=gt(bt),yt=(t,{root:e,rootMargin:n,threshold:o}={},i=[])=>{const r=E.useRef(null),s=E.useRef(null);return E.useCallback(c=>{r.current&&s.current&&(s.current.unobserve(r.current),s.current.disconnect(),s.current=null),c&&(s.current=new IntersectionObserver(t,{root:e,rootMargin:n,threshold:o}),s.current.observe(c),r.current=c)},[r,e,n,JSON.stringify(o),...i])},wt=({root:t,rootMargin:e,threshold:n,unobserveOnEnter:o,target:i,onEnter:r,onLeave:s,defaultInView:u}={},c=[])=>{const[a,p]=E.useState({inView:u||!1,entry:null,observer:null}),l=E.useCallback(([h],f)=>{const b=f.thresholds.some(g=>h.intersectionRatio>=g)&&h.isIntersecting;p({inView:b,entry:h,observer:f}),b&&o&&(f.unobserve(h.target),f.disconnect()),b?r==null||r(h,f):s==null||s(h,f)},[r,s,o]),m=yt(l,{root:t,rootMargin:e,threshold:n},[o,...c]);return E.useEffect(()=>{i!=null&&i.current&&m(i.current)},[i,m]),[m,a.inView,a.entry,a.observer]},It={overflow:"hidden"},xt=({aspectRatio:t,children:e})=>x.jsx("div",{style:{aspectRatio:t,...It},children:e});var j=(t=>(t.AUTO="auto",t.AVIF="avif",t.JPEG="jpeg",t.WEBP="webp",t))(j||{}),w=(t=>(t.xs="xs",t.sm="sm",t.md="md",t.lg="lg",t.xl="xl",t.xxl="xxl",t["4k"]="4k",t["5k"]="5k",t.full="full",t))(w||{}),O=(t=>(t.DEBUG="debug",t.DOWNLOAD="download",t))(O||{});const Et="https://link.visionary.cloud";j.AUTO,w.lg;const M={[w.xs]:160,[w.sm]:320,[w.md]:640,[w.lg]:1280,[w.xl]:1920,[w.xxl]:2560,[w["4k"]]:3840,[w["5k"]]:5120,[w.full]:0};Object.keys(M).reduce((t,e)=>{const n=e,o=M[n];return o&&(t[o]=n),t},{});const Q="!";var At=Object.defineProperty,Rt=(t,e,n)=>e in t?At(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,Tt=(t,e,n)=>Rt(t,typeof e!="symbol"?e+"":e,n),W={},V={};Object.defineProperty(V,"__esModule",{value:!0});function Ut(t){return String.fromCharCode(parseInt(t.slice(1),16))}function Ct(t){return btoa(encodeURIComponent(t).replace(/%[0-9A-F]{2}/g,Ut))}V.encode=Ct;function Nt(t){return`%${`00${t.charCodeAt(0).toString(16)}`.slice(-2)}`}function Ot(t){return decodeURIComponent(Array.from(atob(t),Nt).join(""))}V.decode=Ot,Object.defineProperty(W,"__esModule",{value:!0});const tt=V;function St(t){return tt.decode(t.replace(/\-/g,"+").replace(/_/g,"/"))}var Dt=W.decode=St;function Pt(t){return tt.encode(t).replace(/\//g,"_").replace(/\+/g,"-").replace(/=+$/,"")}var _t=W.encode=Pt;const jt=t=>t.filter(Boolean),et=t=>{try{return new URL(t)}catch{return null}},L=(t="")=>/^[A-Za-z0-9_-]*$/.test(t),Vt=t=>{const{altText:e,bcc:n,blurhash:o,blurhashX:i,blurhashY:r,sourceHeight:s,sourceWidth:u,url:c}=t;if(!c||!u||!s)return new Error("Cannot construct visionary code: missing required url/width/height");const a=[c,u,s];return!n||(a.push(n),!o||!i||!r)||(a.push(o,i,r),e&&e.length&&a.push(e)),Lt(a)},Lt=t=>_t(t.join(Q)),nt=t=>{if(typeof t!="string")return null;const e=t.trim();if(!e.length||!L(e))return null;const n=Dt(e);if(!n)return null;const o=n.split(Q);if(o.length<3)return null;const[i,r,s,u,c,a,p,l]=o,m=i.trim();if(!m.length)return console.error("Cannot parse code, empty file id"),null;const h=Number(r.trim()),f=Number(s.trim());if(isNaN(h)||isNaN(f)||!h||!f)return console.error("Cannot parse Visionary Code: invalid image dimensions",r,s),null;const v=Number(a)??0,b=Number(p)??0;return v<1||b<1?(console.error("Cannot parse Visionary Code: invalid blurhash x, y component dimensions",v,b),null):{altText:l,bcc:u,blurhash:c,blurhashX:v,blurhashY:b,sourceHeight:f,sourceWidth:h,url:m}};class $t extends Error{constructor(){super(...arguments),Tt(this,"message","invalid endpoint URL (does it contain http/https?)")}}const kt=t=>t===O.DEBUG,zt=t=>t===O.DOWNLOAD,Bt=t=>Object.values(j).includes(t),rt=t=>Object.values(w).includes(t),Mt=(t=[])=>{const e={};for(const n of t)rt(n)?e.size=w[n]:kt(n)?e.debug=!0:zt(n)?e.download=!0:Bt(n)&&(e.format=n);return e},Wt=t=>{if(!t||typeof t!="object")return null;const e=[];return t.debug&&e.push(O.DEBUG),t.download&&e.push(O.DOWNLOAD),t.format&&t.format!==j.AUTO&&e.push(t.format),t.size&&rt(t.size)&&e.push(t.size),e.length?e.sort().join(","):null},Gt=t=>{if(L(t)){const e=nt(t);if(e)return{fields:e,options:{}}}return Ft(t)},Ft=t=>{if(!t)return null;const e=t.trim();if(!e)return null;try{const n=Xt(e);if(!n)return null;const{code:o,optionTokens:i}=n,r=nt(o);if(!r)return null;const s=Mt(i);return{fields:r,options:s}}catch(n){n instanceof Error?console.error(`Error parsing URL: ${n.message}`,n):console.error("uncaught error",n)}return null},Ht=(t,e)=>{const n=Vt(t);if(n instanceof Error)return null;let o=null;if(e!=null&&e.endpoint&&(o=et(e==null?void 0:e.endpoint),!o))throw new $t("Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://");o||(o=et(Et));const i=[o.origin,"image",n],r=e?Wt(e):null;return r&&i.push(r),e!=null&&e.filename?i.push(e.filename):i.push("image.jpg"),i.join("/")},Xt=t=>{try{const e=new URL(t),n=jt(e.pathname.split("/"));if(n[0]!=="image"||![3,4].includes(n.length))throw new Error("Unrecognized URL");const o=n[1].trim();if(!o.length||!L(o))throw new Error("URL is not formatted as base64url");if(n.length===4){const i=n[2].split(",");return{code:o,optionTokens:i}}if(n.length===3)return{code:o,optionTokens:[]}}catch{return null}return null},ot=.7,st=1,N=24,Yt=w.lg,ct=process.env.NODE_ENV,qt=ct==="development",it=typeof document>"u",Zt=ct==="test",Jt=it?()=>{}:E.useLayoutEffect,Kt="<visionary>",T=(t,...e)=>{!console||typeof console.log!="function"||console.log(`${Kt} ${t}`,...e)},at=new Uint8Array(128);for(let t=0;t<83;t++)at["0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~".charCodeAt(t)]=t;const $=(t,e,n)=>{let o=0;for(;e<n;)o*=83,o+=at[t.charCodeAt(e++)];return o},lt=Math.pow,S=Math.PI,Qt=S*2,ut=3294.6,ft=269.025,te=t=>t>10.31475?lt(t/ft+.052132,2.4):t/ut,G=t=>~~(t>1227e-8?ft*lt(t,.416666)-13.025:t*ut+1),D=t=>(t<0?-1:1)*t*t,dt=t=>{for(t+=S/2;t>S;)t-=Qt;const e=1.27323954*t-.405284735*D(t);return .225*(D(e)-e)+e};function ee(t){const e=$(t,2,6);return[e>>16,e>>8&255,e&255]}function ne(t,e,n,o){const i=$(t,0,1),r=i%9+1,s=~~(i/9)+1,u=r*s;let c=0,a=0,p=0,l=0,m=0,h=0,f=0,v=0,b=0,g=0,y=0,A=0;const d=($(t,1,2)+1)/13446*(o|1),I=new Float64Array(u*3),Y=ee(t);for(c=0;c<3;c++)I[c]=te(Y[c]);for(c=1;c<u;c++)A=$(t,4+c*2,6+c*2),I[c*3]=D(~~(A/361)-9)*d,I[c*3+1]=D(~~(A/19)%19-9)*d,I[c*3+2]=D(A%19-9)*d;const z=new Float64Array(s*n),B=new Float64Array(r*e);for(a=0;a<s;a++)for(l=0;l<n;l++)z[a*n+l]=dt(S*l*a/n);for(c=0;c<r;c++)for(p=0;p<e;p++)B[c*e+p]=dt(S*p*c/e);const P=e*4,C=new Uint8ClampedArray(P*n);for(l=0;l<n;l++)for(p=0;p<e;p++){for(m=h=f=0,a=0;a<s;a++)for(b=z[a*n+l],c=0;c<r;c++)v=B[c*e+p]*b,g=(c+a*r)*3,m+=I[g]*v,h+=I[g+1]*v,f+=I[g+2]*v;y=4*p+l*P,C[y]=G(m),C[y+1]=G(h),C[y+2]=G(f),C[y+3]=255}return C}const k=t=>{try{return new URL(t)}catch{return null}},re=(t,e)=>`rgba(${t.r},${t.g},${t.b},${e})`,F=t=>qt||Zt?{"data-testid":t}:{},oe=(t,e)=>e?{"data-fileid":t}:{},pt=(t,e)=>Math.min(t,e),se=t=>{let e=t.replace(/^#/,"");if(e.length!==3&&e.length!==6)return null;e.length===3&&(e=`${e[0]}${e[0]}${e[1]}${e[1]}${e[2]}${e[2]}`);const n=parseInt(e.slice(0,2),16),o=parseInt(e.slice(2,4),16);return{b:parseInt(e.slice(4,6),16),g:o,r:n}},U=(t,e=0)=>{const n=Math.pow(10,e);return Math.round(t*n)/n},ce=(t,e)=>{const n=k(t),o=k(e);return!n||!o?t:(o.pathname=n.pathname,o.search=n.search,o.toString())},ie=(t,e={},n=ot,o=st)=>{if(!t)return null;try{e.debug&&T("input imageSrc:",t);const i=Gt(t);if(e.debug&&T("Visionary URL data: ",i),!i)throw new Error("Could not parse Visionary URL");const{fields:r,options:s}=i;if(r.sourceWidth<1||r.sourceHeight<1)throw new Error("Invalid image dimensions");const u=r.sourceWidth/r.sourceHeight,c=(e==null?void 0:e.size)??s.size??Yt,a=M[c];let p=0,l=0,m=0;if(u>=1){l=p=pt(a,r.sourceWidth);const g=U(l/u);m=U(l/g,6)}else p=pt(a,r.sourceHeight),l=U(p*u),m=U(l/p,6);const h=U(100/m,6),f={...r,arPaddingTop:`${h}%`,aspectRatio:m,maxWidth:l,src:t},v=k(r.url);if(v)f.src=v.toString();else if(!k(t)&&L(r.url)){const g=Ht(r,{endpoint:e.endpoint,size:c});g&&(f.src=g)}e.endpoint&&(f.src=ce(f.src,e.endpoint));const b=r.bcc?se(r.bcc):null;if(b&&(f.backgroundColor=re(b,n)),!it&&r.blurhash&&!e.disableBlurLayer){const g=performance.now(),y=ne(r.blurhash,N,N,o),A=performance.now()-g;e.debug&&T(`Blurhash decode time: ${U(A,1)} ms`),y&&(f.pixels=y)}return e.debug&&T("Visionary Image state: ",f),f}catch{return null}},ht={bottom:0,left:0,position:"absolute",right:0,top:0},ae={...ht,maxHeight:"100%",maxWidth:"100%"},le={...ht,height:"100%",width:"100%"},ue=t=>{const e={...ae};return t&&(e.display="none"),e},H={CANVAS:"canvas",CONTAINER:"container",IMAGE:"image"},X={container:"v7y_7587",preventDrag:"v7y_b8c0",preventSelection:"v7y_e0dd"},fe=({alt:t,bgColorAlpha:e=ot,className:n,debug:o=!1,disableBlurLayer:i=!1,disableImageLayer:r=!1,endpoint:s,height:u,hideImageLayer:c=!1,lazy:a=!0,onClick:p,onError:l,onLoad:m,preventDrag:h=!1,preventSelection:f=!1,punch:v=st,size:b,src:g,style:y,width:A})=>{const d=E.useMemo(()=>ie(g,{debug:o,disableBlurLayer:i,endpoint:s,size:b},e,v),[e,o,i,s,v,b,g]),I=E.useRef(null),[Y,z]=wt();Jt(function(){if(!I.current||!(d!=null&&d.blurhash))return;if(!d.pixels){console.warn("No pixel data passed in, skipping");return}const he=performance.now(),Z=I.current.getContext("2d");if(!Z){console.warn("Cannot access canvasRenderingContext, skipping");return}const J=Z.createImageData(N,N);if(!J){console.warn("Could not create ImageData on CanvasRenderingContext");return}if(J.data.set(d.pixels),Z.putImageData(J,0,0),o){const me=performance.now()-he;T(`Canvas render time: ${U(me,1)} ms`)}},[d==null?void 0:d.blurhash,d==null?void 0:d.pixels,o]);const B=E.useCallback(_=>{o&&T("Image load error ",_),l&&l()},[o,l]),P={alt:t,loading:!a||z?"eager":"lazy",onLoad:m};if(!d){o&&T("Not a Visionary URL, rendering fallback <img />");const _={...P,className:n,height:u,onClick:p,onError:l,src:g,style:y,width:A};return x.jsx("img",{..._})}const C=vt(X.container,n,{[X.preventDrag]:!!h,[X.preventSelection]:!!f}),q={...{"--v-ar":d.arPaddingTop},...y,aspectRatio:d.aspectRatio,backgroundColor:(d==null?void 0:d.backgroundColor)??void 0,maxWidth:d.maxWidth,position:"relative",width:"100%"};A&&(q.width=A),u&&(q.height=u);const de={onClick:p},pe=ue(c),mt=x.jsxs("div",{className:C,ref:Y,style:q,...oe(d.url,o),...F(H.CONTAINER),...de,children:[!i&&x.jsx("canvas",{height:N,ref:I,style:le,width:N,...F(H.CANVAS)}),!r&&x.jsx("img",{...P,...F(H.IMAGE),onError:B,src:d.src,style:pe})]});return y!=null&&y.aspectRatio?x.jsx(xt,{aspectRatio:y.aspectRatio,children:mt}):mt};R.Image=fe,Object.defineProperty(R,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "visionary-image",
3
3
  "description": "React image component with built-in Blurhash placeholders for better UX and Core Web Vitals.",
4
- "version": "1.0.2",
4
+ "version": "1.0.3",
5
+ "homepage": "https://visionary.cloud",
5
6
  "type": "module",
6
7
  "main": "./dist/visionary-image.umd.js",
7
8
  "module": "./dist/visionary-image.es.js",