@thebase/ui 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE +28 -0
  3. package/README.md +21 -6
  4. package/dist/baseui.analytics.esm.js +1 -0
  5. package/dist/baseui.analytics.min.js +1 -0
  6. package/dist/baseui.esm.js +9 -9
  7. package/dist/baseui.icons.esm.js +1 -1
  8. package/dist/baseui.min.js +9 -9
  9. package/dist/baseui.registry.json +8 -4
  10. package/dist/types/analytics.d.ts +76 -0
  11. package/dist/types/index.d.ts +4 -0
  12. package/docs/analytics.md +267 -0
  13. package/docs/blocks.md +1 -1
  14. package/docs/components/avatar.md +3 -3
  15. package/docs/components/block-viewer.md +2 -2
  16. package/docs/components/calendar.md +3 -3
  17. package/docs/components/carousel.md +3 -3
  18. package/docs/components/chart.md +3 -3
  19. package/docs/components/combobox.md +3 -3
  20. package/docs/components/command.md +3 -3
  21. package/docs/components/context-menu.md +3 -3
  22. package/docs/components/data-table.md +3 -3
  23. package/docs/components/date-picker.md +3 -3
  24. package/docs/components/icon.md +2 -2
  25. package/docs/components/input-otp.md +3 -3
  26. package/docs/components/input.md +2 -2
  27. package/docs/components/markdown.md +2 -2
  28. package/docs/components/message-scroller.md +3 -3
  29. package/docs/components/message.md +3 -3
  30. package/docs/components/popover.md +3 -3
  31. package/docs/components/questionnaire.md +3 -3
  32. package/docs/components/resizable.md +3 -3
  33. package/docs/components/scroll-area.md +3 -3
  34. package/docs/components/text-editor.md +1 -1
  35. package/docs/components/theme-button.md +2 -2
  36. package/docs/components/toggle-group.md +3 -3
  37. package/docs/components/toggle.md +3 -3
  38. package/docs/components/tooltip.md +3 -3
  39. package/docs/icons.md +5 -5
  40. package/docs/installation.md +4 -3
  41. package/docs/owl-components.md +2 -2
  42. package/docs/registry.md +2 -1
  43. package/docs/runtime-api.md +16 -12
  44. package/docs/theming.md +4 -4
  45. package/docs/usage-guide.md +15 -15
  46. package/package.json +8 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [v1.1.1] - 2026-10-04
6
+
7
+ ### Added
8
+ - Analytics: `visitorContext()` export from `@thebase/ui/analytics` (and `window.thebase.analytics.visitorContext`). It returns the visitor's timezone (`tz`), browser language (`lang`) and a coarse screen bucket (`screen`: Mobile/Tablet/Laptop/Desktop). Pass it as `customProperties` to attach them to every event. Types are included as `BaseUIVisitorContext`. It's an additive export released as a patch by maintainer decision; nothing existing changed.
9
+ - Docs: `docs/analytics.md` covers receiving events on your own backend (payload reference, Go Fiber v3 and FastAPI receivers), a "Sample dashboard" section, and "Visitor context". README has an Analytics section.
10
+ - Examples: `examples/analytics/` contains a BaseUI analytics dashboard plus runnable Go Fiber and FastAPI sample backends (in-memory store, `GET /api/stats`, `DEMO_SEED=1` demo data). The landing page has an Analytics section, and the docs nav lists the Analytics guide.
11
+
12
+ ### Changed
13
+ - Docs and examples: production pin examples now use `@1.1.1`.
14
+ - `npm run dev` server: folder URLs serve their `index.html`, and `.go`/`.py`/`.mod` sources are served as text.
15
+
16
+ ## [v1.1.0] - 2026-10-04
17
+
18
+ ### Added
19
+ - Optional, standalone analytics service: `@thebase/ui/analytics`. Use `dist/baseui.analytics.esm.js`, or the `<script>` build `dist/baseui.analytics.min.js`, which sets `window.thebase.analytics`. It is not part of the main bundles and needs no other BaseUI file. Start it with `init({ backendUrl })`: events go to `<backendUrl>/api/event` (change the path with `apiPath`), and `domain` defaults to `location.hostname`. Pass a full `endpoint` instead when routing through a proxy. A URL without a scheme throws instead of silently posting to your own site. It is a cookieless tracker ported from `@plausible-analytics/tracker` 0.4.6 and keeps that package's options and compact payload. It covers automatic and SPA pageviews, engagement (time on page and scroll depth), outbound links, file downloads, form submissions, `thebase-event-*` / `thebase-revenue-*` class tagging, the `localStorage.thebase_ignore` opt-out, `customProperties` and `transformRequest`. After `init()` the tracker is bound to `window.thebase.track`. Types are in `dist/types/analytics.d.ts`; see `docs/analytics.md`. The upstream MIT notice is in `LICENSE`.
20
+ - The browser global is now `window.thebase`, holding the same object as before (`version`, `register`, `component`, `mount`, `mountAll`, `destroy`, `theme`, `icons`). If a page script creates `window.thebase` before a BaseUI bundle loads, the runtime adds its methods to that object instead of replacing it.
21
+
22
+ ### Changed
23
+ - Docs: production pin examples now use `@1.1.0`. `docs/installation.md` and `docs/registry.md` list the analytics bundles and the `@thebase/ui/analytics` export.
24
+
25
+ ### Deprecated
26
+ - `window.BaseUI`: use `window.thebase` instead (e.g. `thebase.mountAll(...)`, `thebase.theme.set(...)`). It still points to the same object throughout 1.x and will be removed in 2.0.0. The ESM export `import { BaseUI } from "@thebase/ui"`, `window.BaseUITheme` and the `element.BaseUI*` handles are not affected.
27
+
5
28
  ## [v1.0.0] - 2026-10-03
6
29
 
7
30
  First stable release. From here on the package follows [Semantic Versioning](https://semver.org/) — see the [Versioning policy](README.md#versioning-policy) for what counts as the public API and what each version bump means. No API changes versus v0.0.12 beyond the fixes below; upgrading from 0.0.12 needs no code changes.
package/LICENSE CHANGED
@@ -19,3 +19,31 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ ---
24
+
25
+ Third-party notice: src/runtime/base/analytics.js (the optional analytics service,
26
+ built as dist/baseui.analytics.esm.js and dist/baseui.analytics.min.js) is a port of
27
+ @plausible-analytics/tracker, distributed under the following license:
28
+
29
+ MIT License
30
+
31
+ Copyright 2020 Plausible Insights OÜ
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining a copy
34
+ of this software and associated documentation files (the "Software"), to deal
35
+ in the Software without restriction, including without limitation the rights
36
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the Software is
38
+ furnished to do so, subject to the following conditions:
39
+
40
+ The above copyright notice and this permission notice shall be included in all
41
+ copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
46
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
49
+ SOFTWARE.
package/README.md CHANGED
@@ -4,7 +4,7 @@ The Base UI is a CDN-installable UI kit built with Bootstrap 5 styling and Owl-e
4
4
 
5
5
  Its strong points: **no build step** — every component runs straight from a CDN `<script>`/import map, nothing to compile; **modular component design** — each component is a self-contained unit you import or mark up individually, not a monolith; **vanilla JavaScript/TypeScript** — no framework lock-in, no JSX, no compiler-specific syntax to learn; and this combination makes it well suited to building **WYSIWYG website builders**, where components must mount, unmount, and re-render dynamically from user-driven markup or drag-and-drop edits rather than a fixed build-time component tree.
6
6
 
7
- Both APIs load straight from a CDN — jsDelivr or unpkg — no build step, no self-hosting required. The snippets below use the `@latest` tag for readability; pin an exact version instead (e.g. `@1.0.0`, or `@1` to take only non-breaking updates) for any production page, since `@latest` can change what your page loads the moment a new version ships. Pure Owl usage:
7
+ Both APIs load straight from a CDN — jsDelivr or unpkg — no build step, no self-hosting required. The snippets below use the `@latest` tag for readability; pin an exact version instead (e.g. `@1.1.1`, or `@1` to take only non-breaking updates) for any production page, since `@latest` can change what your page loads the moment a new version ships. Pure Owl usage:
8
8
 
9
9
  ```html
10
10
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.min.css">
@@ -56,9 +56,23 @@ For app-level theme controls, import `createThemeController`/`BaseUITheme` as `@
56
56
 
57
57
  Every component ships both APIs from `src/components/<name>/`: the static `b-ui` adapter (`<name>.js`, using `b-att-*` attributes and `baseui:*` events) and a pure Owl component class (`<name>.component.js`, exported from `@thebase/ui/components`). A few components' pure Owl treatment is intentionally lighter or reshaped versus their static markup-driven adapter — most notably `chart` (a slotted container; static Chart.js bootstrapping stays a `b-ui`-only concern) and the data-driven `data-table`/`combobox`/`command`/`calendar` (props-driven instead of slot/markup-driven). See each component's doc page under `docs/components/` for specifics.
58
58
 
59
+ ## Analytics
60
+
61
+ BaseUI also ships an optional, cookieless web-analytics service (from 1.1.0). It is a standalone bundle — not part of `dist/baseui.min.js`/`baseui.esm.js`, with no Owl, Bootstrap, or component runtime dependency (~5.6 KB minified) — so you can load it with or without the rest of BaseUI. Nothing is collected until the page calls `init()`:
62
+
63
+ ```html
64
+ <script type="module">
65
+ import { init, track } from "https://cdn.jsdelivr.net/npm/@thebase/ui@latest/dist/baseui.analytics.esm.js";
66
+ init({ backendUrl: "https://stats.example.com" }); // events POST to <backendUrl>/api/event
67
+ track("Signup", { props: { plan: "pro" } });
68
+ </script>
69
+ ```
70
+
71
+ From npm, use `import { init, track } from "@thebase/ui/analytics"`; for a classic `<script>` tag, `dist/baseui.analytics.min.js` sets `window.thebase.analytics`. It covers automatic and SPA pageviews, engagement (time on page and scroll depth), outbound links, file downloads, form submissions, and `thebase-event-*` class tagging. See [Analytics](docs/analytics.md) for every option, the payload format, opt-out, and sample Go Fiber / FastAPI backends. [`examples/analytics/`](examples/analytics/) holds a ready-to-run BaseUI dashboard for the collected data.
72
+
59
73
  ## Release notes
60
74
 
61
- See [CHANGELOG.md](CHANGELOG.md) for the full version history. Current version: **1.0.0**.
75
+ See [CHANGELOG.md](CHANGELOG.md) for the full version history. Current version: **1.1.1**.
62
76
 
63
77
  ## Versioning policy
64
78
 
@@ -77,7 +91,7 @@ What each release type means:
77
91
 
78
92
  Anything prefixed `_`, undocumented internals, and the `docs/`/`examples/` sources are not part of the public API. Neither are the source-level authoring helpers described in [Component Authoring](docs/component-authoring.md) (`optional()`, `slotProps`, the `open-state.js` hooks, `bindBootstrapOverlay()`): they aren't exported from the package and may change in any release. Deprecated APIs keep working until the next major and are flagged in the CHANGELOG first.
79
93
 
80
- Pinning: use an exact version (`@1.0.0`) when you need byte-identical output, or the major range (`@1` on jsDelivr/unpkg, `^1.0.0` in npm) to receive fixes and features without breaking changes. Avoid `@latest` in production — it will move to the next major.
94
+ Pinning: use an exact version (`@1.1.1`) when you need byte-identical output, or the major range (`@1` on jsDelivr/unpkg, `^1.0.0` in npm) to receive fixes and features without breaking changes. Avoid `@latest` in production — it will move to the next major.
81
95
 
82
96
  ## Project Documents
83
97
 
@@ -85,7 +99,8 @@ Use these documents as the canonical project map:
85
99
 
86
100
  - [Usage Guide](docs/usage-guide.md) is the single entry point for integrating BaseUI into a consumer project — start here, then follow its links into the reference docs below.
87
101
  - [Installation](docs/installation.md) covers CDN, npm, self-hosted usage, icon assets, pinned versions, and release guardrails.
88
- - [Runtime API](docs/runtime-api.md) documents the `window.BaseUI` global, mounting lifecycle, theming API, and destroy behavior.
102
+ - [Analytics](docs/analytics.md) documents the optional, standalone cookieless analytics service (`@thebase/ui/analytics`).
103
+ - [Runtime API](docs/runtime-api.md) documents the `window.thebase` global, mounting lifecycle, theming API, and destroy behavior.
89
104
  - [Registry](docs/registry.md) explains `dist/baseui.registry.json`, build files, block metadata, component metadata, and integrity hashes.
90
105
  - [Theming](docs/theming.md) describes `b-theme`, runtime theme overrides, shadcn-aligned tokens, Bootstrap variable mapping, and shared example theme persistence.
91
106
  - [Built-in Icons](docs/icons.md) covers the Lucide icon library, `b-icon` markup, accessibility rules, self-hosted icon paths, and JavaScript helpers.
@@ -118,7 +133,7 @@ Open `examples/index.html` through the dev server to test the browser build.
118
133
 
119
134
  `examples/index.html` is the single Owl app shell for docs, the component gallery, the block gallery, icons, and the chart catalog, all reachable through one `main-nav` and hash routes (`#/docs`, `#/components`, `#/blocks`, `#/icons`, `#/chart`). Old bookmarked URLs like `/docs` and `/blocks` redirect to their hash-route equivalent. Each block has a shadcn-style Preview/Code/responsive viewer plus its source stylesheet colocated in `examples/blocks/`. `examples/charts/index.html` mirrors the current shadcn chart catalog with interactive BaseUI examples for area, bar, line, pie, radar, radial, and tooltip charts, and is embedded inline at `#/chart`.
120
135
 
121
- BaseUI includes the full Lucide SVG icon set as a built-in icon library. Use `<span b-icon="search"></span>` in HTML, or `BaseUI.icons.lucide.url("search")` from JavaScript. Builds publish all SVGs to `dist/icons/lucide/` and an index at `dist/icons/lucide.json`.
136
+ BaseUI includes the full Lucide SVG icon set as a built-in icon library. Use `<span b-icon="search"></span>` in HTML, or `thebase.icons.lucide.url("search")` from JavaScript. Builds publish all SVGs to `dist/icons/lucide/` and an index at `dist/icons/lucide.json`.
122
137
 
123
138
  ## Package Scripts
124
139
 
@@ -130,6 +145,6 @@ BaseUI includes the full Lucide SVG icon set as a built-in icon library. Use `<s
130
145
 
131
146
  ## Distribution
132
147
 
133
- The npm package publishes the built `dist/` artifacts plus package metadata. The browser build bundles Bootstrap CSS, and `dist/baseui.min.js`/`baseui.esm.js` embed Bootstrap's JS bundle, the Owl runtime, every pure Owl component class, and the theme helper directly (Bootstrap then Owl then BaseUI, in that load order) — consumers install BaseUI with one stylesheet and one script tag for either API. Bootstrap's JS drives every component that has a Bootstrap JS equivalent (modal, dropdown, collapse, tab, toast, carousel, tooltip, popover, alert); BaseUI's `.behavior.js`/`runtime/*.js` helpers wrap Bootstrap's JS API instead of reimplementing it, for both the static and pure-Owl APIs. `dist/bootstrap.bundle.min.js` also ships standalone (unmodified) and `dist/baseui.icons.esm.js` stays a separate, deliberate exception (2000+ generated icon components would blow the main bundle's size budget) — everything else is one file. Every shipped CSS/JS artifact is minified — there are no unminified twins to keep in sync.
148
+ The npm package publishes the built `dist/` artifacts plus package metadata. The browser build bundles Bootstrap CSS, and `dist/baseui.min.js`/`baseui.esm.js` embed Bootstrap's JS bundle, the Owl runtime, every pure Owl component class, and the theme helper directly (Bootstrap then Owl then BaseUI, in that load order) — consumers install BaseUI with one stylesheet and one script tag for either API. Bootstrap's JS drives every component that has a Bootstrap JS equivalent (modal, dropdown, collapse, tab, toast, carousel, tooltip, popover, alert); BaseUI's `.behavior.js`/`runtime/*.js` helpers wrap Bootstrap's JS API instead of reimplementing it, for both the static and pure-Owl APIs. `dist/bootstrap.bundle.min.js` also ships standalone (unmodified) and `dist/baseui.icons.esm.js` stays a separate, deliberate exception (2000+ generated icon components would blow the main bundle's size budget), as does the opt-in analytics service (`dist/baseui.analytics.esm.js`/`.min.js`, so pages that don't track pay nothing for it) — everything else is one file. Every shipped CSS/JS artifact is minified — there are no unminified twins to keep in sync.
134
149
 
135
150
  The published tarball also carries `docs/*.md` and `docs/components/` (see the "Project Documents" section above), `README.md`, `CHANGELOG.md`, and `LICENSE` — `docs/v2/` and `docs/component-authoring.md` are deliberately excluded from `package.json`'s `files` list since they're development-time-only references for working inside this repo.
@@ -0,0 +1 @@
1
+ var H=["pdf","xlsx","docx","txt","rtf","csv","exe","key","pps","ppt","pptx","7z","pkg","rar","gz","zip","avi","mov","mp4","mpeg","wmv","midi","mp3","wav","wma","dmg"];var U=/^localhost$|^127(\.[0-9]+){0,2}\.[0-9]+$|^\[::1?\]$/,F=/thebase-event-name(=|--)(.+)/,B="/api/event",z=/^(https?:\/\/|\/)/,o={},P=H,m,C,w=!1,v,O,A={},E=-1,r=0,l=0,u,s;function $(e){if(o.isInitialized)throw Error("thebase.analytics.init() can only be called once");let t=e.apiPath||B,i=e.endpoint||e.backendUrl&&`${e.backendUrl.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`;if(!i)throw Error("thebase.analytics.init(): backendUrl (or endpoint) is required");if(!z.test(i))throw Error(`thebase.analytics.init(): "${i}" must be an http(s):// URL or a /path on this site`);Object.assign(o,e,{domain:e.domain||location.hostname,endpoint:i,autoCapturePageviews:e.autoCapturePageviews!==!1,logging:e.logging!==!1,bindToWindow:e.bindToWindow!==!1,isInitialized:!0})}function I(e,t,i){fetch(e,{method:"POST",headers:{"Content-Type":"text/plain"},keepalive:!0,body:JSON.stringify(t)}).then(n=>i?.callback?.({status:n.status})).catch(n=>i?.callback?.({error:n}))}function V(){w&&(M(),u=S(),s=L())}function q(e){v=!1,O=e.u,A=e.p,E=-1,l=0,r=Date.now(),G()}function M(){let e=N();if(v||E>=s&&e<3e3)return;E=s;let t={n:"engagement",sd:Math.round(s/u*100),d:o.domain,u:O,p:A,e,v:36};r=0,l=0,o.hashBasedRouting&&(t.h=1),I(o.endpoint,t)}function p(){document.visibilityState==="visible"&&document.hasFocus()&&r===0?r=Date.now():(document.visibilityState==="hidden"||!document.hasFocus())&&(l=N(),r=0,M())}function G(){w||(document.addEventListener("visibilitychange",p),window.addEventListener("blur",p),window.addEventListener("focus",p),w=!0)}function N(){return r?l+(Date.now()-r):l}function S(){let e=document.body,t=document.documentElement;return Math.max(e.scrollHeight,e.offsetHeight,e.clientHeight,t.scrollHeight,t.offsetHeight,t.clientHeight)}function L(){return u<=window.innerHeight?u:window.scrollY+window.innerHeight}function K(){u=S()}function W(){s=Math.max(s,L())}function j(){u=S(),s=L(),new window.ResizeObserver(K).observe(document.documentElement),document.addEventListener("scroll",W)}function ae(){let e=window.innerWidth;return{tz:Intl.DateTimeFormat().resolvedOptions().timeZone,lang:navigator.language,screen:e<576?"Mobile":e<992?"Tablet":e<1440?"Laptop":"Desktop"}}function g(e,t){if(!o.isInitialized)throw Error("thebase.analytics.track() can only be called after thebase.analytics.init()");let i=e==="pageview";if(i&&V(),!o.captureOnLocalhost){if(U.test(location.hostname)||location.protocol==="file:")return d(e,t,"localhost");if((window._phantom||window.__nightmare||navigator.webdriver||window.Cypress)&&!window.__thebase)return d(e,t)}try{if(localStorage.thebase_ignore==="true")return d(e,t,"localStorage flag")}catch{}let n={n:e,v:36,u:t?.u||t?.url||location.href,d:o.domain,r:document.referrer||null};if(t?.props&&(n.p=t.props),t?.interactive===!1&&(n.i=!1),t?.revenue&&(n.$=t.revenue),o.customProperties){let a=typeof o.customProperties=="function"?o.customProperties(e):o.customProperties;typeof a=="object"&&(n.p={...a,...n.p})}if(o.hashBasedRouting&&(n.h=1),typeof o.transformRequest=="function"&&(n=o.transformRequest(n),!n))return d(e,t,"transformRequest");i&&q(n),I(o.endpoint,n,t)}function d(e,t,i){i&&o.logging&&console.warn(`Ignoring Event: ${i}`),t?.callback?.(),e==="pageview"&&(v=!0)}function x(e){return e?.tagName?.toLowerCase()==="a"}function Y(e){for(;e&&(e.tagName===void 0||!x(e)||!e.href);)e=e.parentNode;return e}function J(e){return e&&typeof e.href=="string"&&e.host&&e.host!==location.host}function Z(e){return!!e&&P.includes(e.split(".").pop())}function T(e){return!!e?.classList&&[...e.classList].some(t=>F.test(t))}function y(e,t){return!!e&&t<=3&&(T(e)||y(e.parentNode,t+1))}function D(e){let t=T(e)?e:e?.parentNode,i={name:null,props:{},revenue:{}};if(!t?.classList)return i;for(let n of t.classList){let a=n.match(/thebase-event-(.+)(=|--)(.+)/);if(a){let k=a[3].replace(/\+/g," ");a[1].toLowerCase()==="name"?i.name=k:i.props[a[1]]=k}let c=n.match(/thebase-revenue-(.+)(=|--)(.+)/);c&&(i.revenue[c[1]]=c[3])}return i}function f(e){g(e.name,{props:e.props,revenue:e.revenue})}function _(e){if(e.type==="auxclick"&&e.button!==1)return;let t=Y(e.target);if(y(t,0))return;if(o.outboundLinks&&J(t))return f({name:"Outbound Link: Click",props:{url:t.href}});let i=t&&typeof t.href=="string"&&t.href.split("?")[0];o.fileDownloads&&Z(i)&&f({name:"File Download",props:{url:i}})}function R(e){if(e.type==="auxclick"&&e.button!==1)return;let t,i,n=e.target;for(let c=0;c<=3&&n;c++){if(n.tagName?.toLowerCase()==="form")return;x(n)&&(t=n),T(n)&&(i=n),n=n.parentNode}if(!i)return;let a=D(i);t&&(a.props.url=t.href),f(a)}function Q(e){let t=e.target;(t.hasAttribute("novalidate")||t.checkValidity())&&!y(t,0)&&g("Form: Submission")}function X(e){let t=D(e.target);t.name&&f(t)}function ee(){document.addEventListener("click",_),document.addEventListener("auxclick",_),Array.isArray(o.fileDownloads?.fileExtensions)&&(P=o.fileDownloads.fileExtensions),o.formSubmissions&&document.addEventListener("submit",Q,!0),document.addEventListener("submit",X),document.addEventListener("click",R),document.addEventListener("auxclick",R)}function h(e){!o.hashBasedRouting&&e&&m===location.pathname||(m=location.pathname,g("pageview"))}function b(){h(!0)}function te(...e){C.apply(this,e),b()}function ne(){!m&&document.visibilityState==="visible"&&h()}function ie(e){e.persisted&&h()}function oe(){o.hashBasedRouting?window.addEventListener("hashchange",b):(C=window.history.pushState,window.history.pushState=te,window.addEventListener("popstate",b)),document.visibilityState==="hidden"||document.visibilityState==="prerender"?document.addEventListener("visibilitychange",ne):h(),window.addEventListener("pageshow",ie)}function re(e){$(e||{}),j(),o.autoCapturePageviews&&oe(),ee(),o.bindToWindow&&(window.thebase??(window.thebase={}),window.thebase.track=g,window.thebase.track.s="npm",window.thebase.track.v=36,window.thebase.track.l=!0)}export{H as DEFAULT_FILE_TYPES,re as init,g as track,ae as visitorContext};
@@ -0,0 +1 @@
1
+ (()=>{var F=Object.defineProperty;var B=(e,t)=>{for(var n in t)F(e,n,{get:t[n],enumerable:!0})};var k={};B(k,{DEFAULT_FILE_TYPES:()=>C,init:()=>ue,track:()=>d,visitorContext:()=>Q});var C=["pdf","xlsx","docx","txt","rtf","csv","exe","key","pps","ppt","pptx","7z","pkg","rar","gz","zip","avi","mov","mp4","mpeg","wmv","midi","mp3","wav","wma","dmg"];var z=/^localhost$|^127(\.[0-9]+){0,2}\.[0-9]+$|^\[::1?\]$/,$=/thebase-event-name(=|--)(.+)/,V="/api/event",q=/^(https?:\/\/|\/)/,o={},O=C,m,A,w=!1,v,I,M={},E=-1,r=0,l=0,u,s;function G(e){if(o.isInitialized)throw Error("thebase.analytics.init() can only be called once");let t=e.apiPath||V,n=e.endpoint||e.backendUrl&&`${e.backendUrl.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`;if(!n)throw Error("thebase.analytics.init(): backendUrl (or endpoint) is required");if(!q.test(n))throw Error(`thebase.analytics.init(): "${n}" must be an http(s):// URL or a /path on this site`);Object.assign(o,e,{domain:e.domain||location.hostname,endpoint:n,autoCapturePageviews:e.autoCapturePageviews!==!1,logging:e.logging!==!1,bindToWindow:e.bindToWindow!==!1,isInitialized:!0})}function N(e,t,n){fetch(e,{method:"POST",headers:{"Content-Type":"text/plain"},keepalive:!0,body:JSON.stringify(t)}).then(i=>n?.callback?.({status:i.status})).catch(i=>n?.callback?.({error:i}))}function K(){w&&(x(),u=S(),s=L())}function W(e){v=!1,I=e.u,M=e.p,E=-1,l=0,r=Date.now(),j()}function x(){let e=D();if(v||E>=s&&e<3e3)return;E=s;let t={n:"engagement",sd:Math.round(s/u*100),d:o.domain,u:I,p:M,e,v:36};r=0,l=0,o.hashBasedRouting&&(t.h=1),N(o.endpoint,t)}function p(){document.visibilityState==="visible"&&document.hasFocus()&&r===0?r=Date.now():(document.visibilityState==="hidden"||!document.hasFocus())&&(l=D(),r=0,x())}function j(){w||(document.addEventListener("visibilitychange",p),window.addEventListener("blur",p),window.addEventListener("focus",p),w=!0)}function D(){return r?l+(Date.now()-r):l}function S(){let e=document.body,t=document.documentElement;return Math.max(e.scrollHeight,e.offsetHeight,e.clientHeight,t.scrollHeight,t.offsetHeight,t.clientHeight)}function L(){return u<=window.innerHeight?u:window.scrollY+window.innerHeight}function Y(){u=S()}function J(){s=Math.max(s,L())}function Z(){u=S(),s=L(),new window.ResizeObserver(Y).observe(document.documentElement),document.addEventListener("scroll",J)}function Q(){let e=window.innerWidth;return{tz:Intl.DateTimeFormat().resolvedOptions().timeZone,lang:navigator.language,screen:e<576?"Mobile":e<992?"Tablet":e<1440?"Laptop":"Desktop"}}function d(e,t){if(!o.isInitialized)throw Error("thebase.analytics.track() can only be called after thebase.analytics.init()");let n=e==="pageview";if(n&&K(),!o.captureOnLocalhost){if(z.test(location.hostname)||location.protocol==="file:")return f(e,t,"localhost");if((window._phantom||window.__nightmare||navigator.webdriver||window.Cypress)&&!window.__thebase)return f(e,t)}try{if(localStorage.thebase_ignore==="true")return f(e,t,"localStorage flag")}catch{}let i={n:e,v:36,u:t?.u||t?.url||location.href,d:o.domain,r:document.referrer||null};if(t?.props&&(i.p=t.props),t?.interactive===!1&&(i.i=!1),t?.revenue&&(i.$=t.revenue),o.customProperties){let a=typeof o.customProperties=="function"?o.customProperties(e):o.customProperties;typeof a=="object"&&(i.p={...a,...i.p})}if(o.hashBasedRouting&&(i.h=1),typeof o.transformRequest=="function"&&(i=o.transformRequest(i),!i))return f(e,t,"transformRequest");n&&W(i),N(o.endpoint,i,t)}function f(e,t,n){n&&o.logging&&console.warn(`Ignoring Event: ${n}`),t?.callback?.(),e==="pageview"&&(v=!0)}function H(e){return e?.tagName?.toLowerCase()==="a"}function X(e){for(;e&&(e.tagName===void 0||!H(e)||!e.href);)e=e.parentNode;return e}function ee(e){return e&&typeof e.href=="string"&&e.host&&e.host!==location.host}function te(e){return!!e&&O.includes(e.split(".").pop())}function T(e){return!!e?.classList&&[...e.classList].some(t=>$.test(t))}function y(e,t){return!!e&&t<=3&&(T(e)||y(e.parentNode,t+1))}function U(e){let t=T(e)?e:e?.parentNode,n={name:null,props:{},revenue:{}};if(!t?.classList)return n;for(let i of t.classList){let a=i.match(/thebase-event-(.+)(=|--)(.+)/);if(a){let _=a[3].replace(/\+/g," ");a[1].toLowerCase()==="name"?n.name=_:n.props[a[1]]=_}let c=i.match(/thebase-revenue-(.+)(=|--)(.+)/);c&&(n.revenue[c[1]]=c[3])}return n}function g(e){d(e.name,{props:e.props,revenue:e.revenue})}function R(e){if(e.type==="auxclick"&&e.button!==1)return;let t=X(e.target);if(y(t,0))return;if(o.outboundLinks&&ee(t))return g({name:"Outbound Link: Click",props:{url:t.href}});let n=t&&typeof t.href=="string"&&t.href.split("?")[0];o.fileDownloads&&te(n)&&g({name:"File Download",props:{url:n}})}function P(e){if(e.type==="auxclick"&&e.button!==1)return;let t,n,i=e.target;for(let c=0;c<=3&&i;c++){if(i.tagName?.toLowerCase()==="form")return;H(i)&&(t=i),T(i)&&(n=i),i=i.parentNode}if(!n)return;let a=U(n);t&&(a.props.url=t.href),g(a)}function ne(e){let t=e.target;(t.hasAttribute("novalidate")||t.checkValidity())&&!y(t,0)&&d("Form: Submission")}function ie(e){let t=U(e.target);t.name&&g(t)}function oe(){document.addEventListener("click",R),document.addEventListener("auxclick",R),Array.isArray(o.fileDownloads?.fileExtensions)&&(O=o.fileDownloads.fileExtensions),o.formSubmissions&&document.addEventListener("submit",ne,!0),document.addEventListener("submit",ie),document.addEventListener("click",P),document.addEventListener("auxclick",P)}function h(e){!o.hashBasedRouting&&e&&m===location.pathname||(m=location.pathname,d("pageview"))}function b(){h(!0)}function ae(...e){A.apply(this,e),b()}function re(){!m&&document.visibilityState==="visible"&&h()}function se(e){e.persisted&&h()}function ce(){o.hashBasedRouting?window.addEventListener("hashchange",b):(A=window.history.pushState,window.history.pushState=ae,window.addEventListener("popstate",b)),document.visibilityState==="hidden"||document.visibilityState==="prerender"?document.addEventListener("visibilitychange",re):h(),window.addEventListener("pageshow",se)}function ue(e){G(e||{}),Z(),o.autoCapturePageviews&&ce(),oe(),o.bindToWindow&&(window.thebase??(window.thebase={}),window.thebase.track=d,window.thebase.track.s="npm",window.thebase.track.v=36,window.thebase.track.l=!0)}window.thebase??(window.thebase={});window.thebase.analytics=k;})();