@indiebob/tracker 0.2.3 → 0.3.0
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/CHANGELOG.md +80 -0
- package/README.md +125 -6
- package/dist/index.cjs +880 -2
- package/dist/index.d.mts +69 -11
- package/dist/index.d.ts +69 -11
- package/dist/index.global.js +3 -3
- package/dist/index.js +878 -2
- package/dist/server.d.mts +8 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +5 -7
- package/dist/server.mjs +5 -7
- package/dist/vue.cjs +904 -2
- package/dist/vue.global.js +3 -3
- package/dist/vue.js +900 -2
- package/package.json +11 -9
package/dist/index.d.mts
CHANGED
|
@@ -42,7 +42,15 @@ interface TrackerConfig {
|
|
|
42
42
|
formSubmit?: boolean;
|
|
43
43
|
/** Track clicks on outbound links. Default: true */
|
|
44
44
|
outboundClicks?: boolean;
|
|
45
|
+
/** Track clicks on links to files (pdf, zip, dmg, …) as `file_download`. Default: true */
|
|
46
|
+
fileDownloads?: boolean;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Treat the URL hash as part of the page path (for `/#/route` routers):
|
|
50
|
+
* a hash-only change becomes a pageview and the hash is reported in the
|
|
51
|
+
* path. Default: false (a hash-only change is not a new page).
|
|
52
|
+
*/
|
|
53
|
+
hashMode?: boolean;
|
|
46
54
|
}
|
|
47
55
|
/** Resolved config with all defaults applied. */
|
|
48
56
|
interface ResolvedConfig {
|
|
@@ -62,10 +70,12 @@ interface ResolvedConfig {
|
|
|
62
70
|
dataAttributes?: boolean;
|
|
63
71
|
formSubmit?: boolean;
|
|
64
72
|
outboundClicks?: boolean;
|
|
73
|
+
fileDownloads?: boolean;
|
|
65
74
|
};
|
|
75
|
+
hashMode: boolean;
|
|
66
76
|
}
|
|
67
77
|
/** The tracking event type. */
|
|
68
|
-
type EventType = 'page' | 'track' | 'identify' | 'revenue';
|
|
78
|
+
type EventType = 'page' | 'track' | 'identify' | 'revenue' | 'engagement';
|
|
69
79
|
/** Device category. */
|
|
70
80
|
type DeviceType = 'desktop' | 'mobile' | 'tablet';
|
|
71
81
|
/** Revenue event type. */
|
|
@@ -100,6 +110,11 @@ interface EventContext {
|
|
|
100
110
|
interface TrackerEvent {
|
|
101
111
|
/** Schema version. Always 1 for this SDK. Enables server-side backwards compat. */
|
|
102
112
|
v: 1;
|
|
113
|
+
/**
|
|
114
|
+
* Random url-safe id (21 chars), unique per event. Stays the same across
|
|
115
|
+
* retries and offline replays so the server can store each event once.
|
|
116
|
+
*/
|
|
117
|
+
id: string;
|
|
103
118
|
projectId: string;
|
|
104
119
|
type: EventType;
|
|
105
120
|
anonymousId: string;
|
|
@@ -116,6 +131,12 @@ interface TrackerEvent {
|
|
|
116
131
|
plan?: string;
|
|
117
132
|
type?: RevenueType;
|
|
118
133
|
};
|
|
134
|
+
engagement?: {
|
|
135
|
+
/** Visible-and-focused milliseconds on the page since the last engagement event. */
|
|
136
|
+
ms: number;
|
|
137
|
+
/** Deepest point of the page seen, as a percentage of its height (0–100). */
|
|
138
|
+
scroll: number;
|
|
139
|
+
};
|
|
119
140
|
}
|
|
120
141
|
/** Overrides for manual page() calls. */
|
|
121
142
|
interface PageOverrides {
|
|
@@ -139,17 +160,31 @@ interface RevenueData {
|
|
|
139
160
|
* bob.page()
|
|
140
161
|
*/
|
|
141
162
|
declare class IndieBob {
|
|
142
|
-
private
|
|
143
|
-
private
|
|
144
|
-
private
|
|
145
|
-
private
|
|
146
|
-
private
|
|
147
|
-
private
|
|
148
|
-
|
|
163
|
+
private _config;
|
|
164
|
+
private _queue;
|
|
165
|
+
private _userId;
|
|
166
|
+
private _cleanupHistory;
|
|
167
|
+
private _cleanupClicks;
|
|
168
|
+
private _cleanupFormSubmit;
|
|
169
|
+
/** Engagement meter for the current page (browser only). */
|
|
170
|
+
private _eng;
|
|
171
|
+
/** Context of the page last counted — what an engagement event describes. */
|
|
172
|
+
private _pageCtx;
|
|
173
|
+
/** Path of the page last counted; undefined until the first pageview. */
|
|
174
|
+
private _lastPath;
|
|
175
|
+
/** Overrides of the page last counted, reused for a bfcache restore. */
|
|
176
|
+
private _lastOverrides;
|
|
177
|
+
/** A first pageview waiting for the tab to become visible. */
|
|
178
|
+
private _waiting;
|
|
179
|
+
private _waitingOverrides;
|
|
149
180
|
private constructor();
|
|
150
181
|
/**
|
|
151
182
|
* Create a tracker instance. Call once at app startup.
|
|
152
183
|
*
|
|
184
|
+
* In the browser, calling it again for the same projectId returns the
|
|
185
|
+
* instance already running (its first config wins) — so a `data-project`
|
|
186
|
+
* script tag plus a manual init() never doubles the events.
|
|
187
|
+
*
|
|
153
188
|
* @example
|
|
154
189
|
* const bob = IndieBob.init({ projectId: 'proj_your16charId' })
|
|
155
190
|
*/
|
|
@@ -179,10 +214,22 @@ declare class IndieBob {
|
|
|
179
214
|
* - 'signup' if this is the first time this visitor is identified (new user)
|
|
180
215
|
* - 'login' if this visitor was previously identified (returning user)
|
|
181
216
|
*
|
|
217
|
+
* PASS `isNew` WHEN YOUR SERVER KNOWS THE ANSWER. Without it the only
|
|
218
|
+
* evidence available is a localStorage flag this SDK wrote itself, and that
|
|
219
|
+
* flag cannot exist in a browser that has never run identify() before — so
|
|
220
|
+
* the FIRST identify in any browser looks like a signup. On a product that
|
|
221
|
+
* already has users, the day you install identify() every returning user
|
|
222
|
+
* files a phantom `signup` and the funnel's top step is wrong from then on.
|
|
223
|
+
* The server knows whether it just INSERTed a user row; tell us and the
|
|
224
|
+
* guess is skipped entirely.
|
|
225
|
+
*
|
|
182
226
|
* @example
|
|
183
|
-
* bob.identify('user_123', {
|
|
227
|
+
* bob.identify('user_123', { plan: 'pro' }) // guess
|
|
228
|
+
* bob.identify('user_123', { plan: 'pro' }, { isNew: true }) // server truth
|
|
184
229
|
*/
|
|
185
|
-
identify(userId: string, traits?: Record<string, unknown
|
|
230
|
+
identify(userId: string, traits?: Record<string, unknown>, options?: {
|
|
231
|
+
isNew?: boolean;
|
|
232
|
+
}): void;
|
|
186
233
|
/**
|
|
187
234
|
* Track a revenue event.
|
|
188
235
|
*
|
|
@@ -199,6 +246,11 @@ declare class IndieBob {
|
|
|
199
246
|
optIn(): void;
|
|
200
247
|
/** Returns true if the user has explicitly opted out. */
|
|
201
248
|
isOptedOut(): boolean;
|
|
249
|
+
/**
|
|
250
|
+
* Returns true if this browser excluded itself with `?ib_ignore=1`
|
|
251
|
+
* (the owner's own visits). `?ib_ignore=0` undoes it.
|
|
252
|
+
*/
|
|
253
|
+
isIgnored(): boolean;
|
|
202
254
|
/** Force-send all queued events immediately. Useful in tests. */
|
|
203
255
|
flush(): Promise<void>;
|
|
204
256
|
/** Get the current anonymous ID. */
|
|
@@ -216,7 +268,13 @@ declare class IndieBob {
|
|
|
216
268
|
* // Later: cleanup()
|
|
217
269
|
*/
|
|
218
270
|
enableAutoPage(): () => void;
|
|
219
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Queue an engagement event for the page last counted, if its reading is
|
|
273
|
+
* worth sending. `measure`: sample the scroll first (false on an SPA
|
|
274
|
+
* change, when the DOM already shows the next page).
|
|
275
|
+
*/
|
|
276
|
+
private _leave;
|
|
277
|
+
private _buildEvent;
|
|
220
278
|
}
|
|
221
279
|
|
|
222
280
|
export { type DeviceType, type EventContext, type EventType, IndieBob, type PageOverrides, type RevenueData, type RevenueType, type TrackerConfig, type TrackerEvent, type UtmData };
|
package/dist/index.d.ts
CHANGED
|
@@ -42,7 +42,15 @@ interface TrackerConfig {
|
|
|
42
42
|
formSubmit?: boolean;
|
|
43
43
|
/** Track clicks on outbound links. Default: true */
|
|
44
44
|
outboundClicks?: boolean;
|
|
45
|
+
/** Track clicks on links to files (pdf, zip, dmg, …) as `file_download`. Default: true */
|
|
46
|
+
fileDownloads?: boolean;
|
|
45
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Treat the URL hash as part of the page path (for `/#/route` routers):
|
|
50
|
+
* a hash-only change becomes a pageview and the hash is reported in the
|
|
51
|
+
* path. Default: false (a hash-only change is not a new page).
|
|
52
|
+
*/
|
|
53
|
+
hashMode?: boolean;
|
|
46
54
|
}
|
|
47
55
|
/** Resolved config with all defaults applied. */
|
|
48
56
|
interface ResolvedConfig {
|
|
@@ -62,10 +70,12 @@ interface ResolvedConfig {
|
|
|
62
70
|
dataAttributes?: boolean;
|
|
63
71
|
formSubmit?: boolean;
|
|
64
72
|
outboundClicks?: boolean;
|
|
73
|
+
fileDownloads?: boolean;
|
|
65
74
|
};
|
|
75
|
+
hashMode: boolean;
|
|
66
76
|
}
|
|
67
77
|
/** The tracking event type. */
|
|
68
|
-
type EventType = 'page' | 'track' | 'identify' | 'revenue';
|
|
78
|
+
type EventType = 'page' | 'track' | 'identify' | 'revenue' | 'engagement';
|
|
69
79
|
/** Device category. */
|
|
70
80
|
type DeviceType = 'desktop' | 'mobile' | 'tablet';
|
|
71
81
|
/** Revenue event type. */
|
|
@@ -100,6 +110,11 @@ interface EventContext {
|
|
|
100
110
|
interface TrackerEvent {
|
|
101
111
|
/** Schema version. Always 1 for this SDK. Enables server-side backwards compat. */
|
|
102
112
|
v: 1;
|
|
113
|
+
/**
|
|
114
|
+
* Random url-safe id (21 chars), unique per event. Stays the same across
|
|
115
|
+
* retries and offline replays so the server can store each event once.
|
|
116
|
+
*/
|
|
117
|
+
id: string;
|
|
103
118
|
projectId: string;
|
|
104
119
|
type: EventType;
|
|
105
120
|
anonymousId: string;
|
|
@@ -116,6 +131,12 @@ interface TrackerEvent {
|
|
|
116
131
|
plan?: string;
|
|
117
132
|
type?: RevenueType;
|
|
118
133
|
};
|
|
134
|
+
engagement?: {
|
|
135
|
+
/** Visible-and-focused milliseconds on the page since the last engagement event. */
|
|
136
|
+
ms: number;
|
|
137
|
+
/** Deepest point of the page seen, as a percentage of its height (0–100). */
|
|
138
|
+
scroll: number;
|
|
139
|
+
};
|
|
119
140
|
}
|
|
120
141
|
/** Overrides for manual page() calls. */
|
|
121
142
|
interface PageOverrides {
|
|
@@ -139,17 +160,31 @@ interface RevenueData {
|
|
|
139
160
|
* bob.page()
|
|
140
161
|
*/
|
|
141
162
|
declare class IndieBob {
|
|
142
|
-
private
|
|
143
|
-
private
|
|
144
|
-
private
|
|
145
|
-
private
|
|
146
|
-
private
|
|
147
|
-
private
|
|
148
|
-
|
|
163
|
+
private _config;
|
|
164
|
+
private _queue;
|
|
165
|
+
private _userId;
|
|
166
|
+
private _cleanupHistory;
|
|
167
|
+
private _cleanupClicks;
|
|
168
|
+
private _cleanupFormSubmit;
|
|
169
|
+
/** Engagement meter for the current page (browser only). */
|
|
170
|
+
private _eng;
|
|
171
|
+
/** Context of the page last counted — what an engagement event describes. */
|
|
172
|
+
private _pageCtx;
|
|
173
|
+
/** Path of the page last counted; undefined until the first pageview. */
|
|
174
|
+
private _lastPath;
|
|
175
|
+
/** Overrides of the page last counted, reused for a bfcache restore. */
|
|
176
|
+
private _lastOverrides;
|
|
177
|
+
/** A first pageview waiting for the tab to become visible. */
|
|
178
|
+
private _waiting;
|
|
179
|
+
private _waitingOverrides;
|
|
149
180
|
private constructor();
|
|
150
181
|
/**
|
|
151
182
|
* Create a tracker instance. Call once at app startup.
|
|
152
183
|
*
|
|
184
|
+
* In the browser, calling it again for the same projectId returns the
|
|
185
|
+
* instance already running (its first config wins) — so a `data-project`
|
|
186
|
+
* script tag plus a manual init() never doubles the events.
|
|
187
|
+
*
|
|
153
188
|
* @example
|
|
154
189
|
* const bob = IndieBob.init({ projectId: 'proj_your16charId' })
|
|
155
190
|
*/
|
|
@@ -179,10 +214,22 @@ declare class IndieBob {
|
|
|
179
214
|
* - 'signup' if this is the first time this visitor is identified (new user)
|
|
180
215
|
* - 'login' if this visitor was previously identified (returning user)
|
|
181
216
|
*
|
|
217
|
+
* PASS `isNew` WHEN YOUR SERVER KNOWS THE ANSWER. Without it the only
|
|
218
|
+
* evidence available is a localStorage flag this SDK wrote itself, and that
|
|
219
|
+
* flag cannot exist in a browser that has never run identify() before — so
|
|
220
|
+
* the FIRST identify in any browser looks like a signup. On a product that
|
|
221
|
+
* already has users, the day you install identify() every returning user
|
|
222
|
+
* files a phantom `signup` and the funnel's top step is wrong from then on.
|
|
223
|
+
* The server knows whether it just INSERTed a user row; tell us and the
|
|
224
|
+
* guess is skipped entirely.
|
|
225
|
+
*
|
|
182
226
|
* @example
|
|
183
|
-
* bob.identify('user_123', {
|
|
227
|
+
* bob.identify('user_123', { plan: 'pro' }) // guess
|
|
228
|
+
* bob.identify('user_123', { plan: 'pro' }, { isNew: true }) // server truth
|
|
184
229
|
*/
|
|
185
|
-
identify(userId: string, traits?: Record<string, unknown
|
|
230
|
+
identify(userId: string, traits?: Record<string, unknown>, options?: {
|
|
231
|
+
isNew?: boolean;
|
|
232
|
+
}): void;
|
|
186
233
|
/**
|
|
187
234
|
* Track a revenue event.
|
|
188
235
|
*
|
|
@@ -199,6 +246,11 @@ declare class IndieBob {
|
|
|
199
246
|
optIn(): void;
|
|
200
247
|
/** Returns true if the user has explicitly opted out. */
|
|
201
248
|
isOptedOut(): boolean;
|
|
249
|
+
/**
|
|
250
|
+
* Returns true if this browser excluded itself with `?ib_ignore=1`
|
|
251
|
+
* (the owner's own visits). `?ib_ignore=0` undoes it.
|
|
252
|
+
*/
|
|
253
|
+
isIgnored(): boolean;
|
|
202
254
|
/** Force-send all queued events immediately. Useful in tests. */
|
|
203
255
|
flush(): Promise<void>;
|
|
204
256
|
/** Get the current anonymous ID. */
|
|
@@ -216,7 +268,13 @@ declare class IndieBob {
|
|
|
216
268
|
* // Later: cleanup()
|
|
217
269
|
*/
|
|
218
270
|
enableAutoPage(): () => void;
|
|
219
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Queue an engagement event for the page last counted, if its reading is
|
|
273
|
+
* worth sending. `measure`: sample the scroll first (false on an SPA
|
|
274
|
+
* change, when the DOM already shows the next page).
|
|
275
|
+
*/
|
|
276
|
+
private _leave;
|
|
277
|
+
private _buildEvent;
|
|
220
278
|
}
|
|
221
279
|
|
|
222
280
|
export { type DeviceType, type EventContext, type EventType, IndieBob, type PageOverrides, type RevenueData, type RevenueType, type TrackerConfig, type TrackerEvent, type UtmData };
|
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var IndieBob=(function(exports){'use strict';var dt=Object.defineProperty,ft=Object.defineProperties;var pt=Object.getOwnPropertyDescriptors;var D=Object.getOwnPropertySymbols;var gt=Object.prototype.hasOwnProperty,mt=Object.prototype.propertyIsEnumerable;var F=(e,t,n)=>t in e?dt(e,t,{enumerable:true,configurable:true,writable:true,value:n}):e[t]=n,p=(e,t)=>{for(var n in t||(t={}))gt.call(t,n)&&F(e,n,t[n]);if(D)for(var n of D(t))mt.call(t,n)&&F(e,n,t[n]);return e},N=(e,t)=>ft(e,pt(t));var l=(e,t,n)=>new Promise((o,i)=>{var r=a=>{try{s(n.next(a));}catch(u){i(u);}},c=a=>{try{s(n.throw(a));}catch(u){i(u);}},s=a=>a.done?o(a.value):Promise.resolve(a.value).then(r,c);s((n=n.apply(e,t)).next());});var ht="https://www.indiebob.com/api/collect";function U(e){var t,n,o,i,r;if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:(t=e.endpoint)!=null?t:ht,debug:(n=e.debug)!=null?n:false,respectDnt:(o=e.respectDnt)!=null?o:true,respectGpc:(i=e.respectGpc)!=null?i:true,autoDetect:(r=e.autoDetect)!=null?r:true}}var d="_ib_anon";function y(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t="";if(typeof crypto!="undefined"&&crypto.getRandomValues){let n=new Uint8Array(21);crypto.getRandomValues(n);for(let o of n)t+=e[o%e.length];}else for(let n=0;n<21;n++)t+=e[Math.floor(Math.random()*e.length)];return t}function b(){try{let e=localStorage.getItem(d);return e||(e=y(),localStorage.setItem(d,e)),e}catch(e){try{let t=sessionStorage.getItem(d);return t||(t=y(),sessionStorage.setItem(d,t)),t}catch(t){return y()}}}function L(){try{localStorage.removeItem(d);}catch(e){}try{sessionStorage.removeItem(d);}catch(e){}}var I="_ib_session",S="_ib_session_last";function M(){try{return crypto.randomUUID()}catch(e){return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}}function E(){var e;try{let t=Date.now(),n=parseInt((e=sessionStorage.getItem(S))!=null?e:"0",10),o=sessionStorage.getItem(I),i=n>0&&t-n>18e5;return (!o||i)&&(o=M(),sessionStorage.setItem(I,o)),sessionStorage.setItem(S,String(t)),o}catch(t){return M()}}function q(){try{sessionStorage.removeItem(I);}catch(e){}try{sessionStorage.removeItem(S);}catch(e){}}var g="_ib_first_utm",j="_ib_last_utm",m="_ib_referrer";function B(e){let t=new URLSearchParams(e),n={},o=false;return t.has("utm_source")?(n.source=t.get("utm_source"),o=true):t.get("ref")&&(n.source=t.get("ref"),o=true),t.has("utm_medium")&&(n.medium=t.get("utm_medium"),o=true),t.has("utm_campaign")&&(n.campaign=t.get("utm_campaign"),o=true),t.has("utm_term")&&(n.term=t.get("utm_term"),o=true),t.has("utm_content")&&(n.content=t.get("utm_content"),o=true),o?n:null}function Y(e,t){let n=B(e);try{n&&!localStorage.getItem(g)&&localStorage.setItem(g,JSON.stringify(n)),n&&localStorage.setItem(j,JSON.stringify(n)),t&&!localStorage.getItem(m)&&localStorage.setItem(m,t);}catch(o){}}function H(){try{let e=localStorage.getItem(g);return e?JSON.parse(e):void 0}catch(e){return}}function K(){var e;try{return (e=localStorage.getItem(m))!=null?e:void 0}catch(t){return}}function V(e){var t;return (t=B(e))!=null?t:void 0}function Q(){try{localStorage.removeItem(g);}catch(e){}try{localStorage.removeItem(j);}catch(e){}try{localStorage.removeItem(m);}catch(e){}}var h="_ib_optout",vt="_ib_queue";function f(e){try{if(localStorage.getItem(h))return !1}catch(t){}return !(e.respectDnt&&typeof navigator!="undefined"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator!="undefined"&&navigator.globalPrivacyControl===true)}function z(){try{localStorage.setItem(h,"1");}catch(e){}L(),q(),Q();try{localStorage.removeItem(vt);}catch(e){}}function X(){try{localStorage.removeItem(h);}catch(e){}}function J(){try{return !!localStorage.getItem(h)}catch(e){return false}}var yt=[1e3,2e3,4e3];function bt(e){return l(this,null,function*(){return new Promise(t=>setTimeout(t,e))})}function _(e,t,n=false){return l(this,null,function*(){let o=JSON.stringify(e);if(n&&typeof navigator!="undefined"&&navigator.sendBeacon){let i=new Blob([o],{type:"text/plain;charset=UTF-8"}),r=navigator.sendBeacon(t.endpoint,i);return t.debug&&console.log("[IndieBob] sendBeacon:",r,e.batch.length,"events"),r}for(let i=0;i<3;i++){try{let r=yield fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(r.ok)return t.debug&&console.log("[IndieBob] sent:",e.batch.length,"events"),!0;if(r.status>=400&&r.status<500)return t.debug&&console.warn("[IndieBob] 4xx error, not retrying:",r.status),!1}catch(r){t.debug&&console.warn("[IndieBob] fetch error (attempt",i+1,"):",r);}i<2&&(yield bt(yt[i]));}return t.debug&&console.warn("[IndieBob] failed to send after",3,"attempts"),false})}var w="_ib_queue",It=10,St=5e3,Et=50,v=class{constructor(t){this.queue=[];this.timer=null;this.flushing=false;this.config=t,this.startTimer(),this.setupVisibilityFlush(),this.setupOnlineFlush();}push(t){this.queue.push(t),this.queue.length>=It&&this.flush();}flush(t=false){return l(this,null,function*(){if(this.flushing&&!t||this.queue.length===0)return;this.flushing=true;let n=this.queue.splice(0);(yield _({batch:n},this.config,t))||this.pushToOfflineQueue(n),this.flushing=false;})}flushOfflineQueue(){return l(this,null,function*(){let t=this.getOfflineQueue();if(t.length===0)return;this.clearOfflineQueue(),yield _({batch:t},this.config);})}destroy(){this.timer&&clearInterval(this.timer);}startTimer(){this.timer=setInterval(()=>{this.queue.length>0&&this.flush();},St);}setupVisibilityFlush(){typeof document!="undefined"&&(document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(true);},{passive:true}),window.addEventListener("pagehide",()=>{this.flush(true);},{passive:true}));}setupOnlineFlush(){typeof window!="undefined"&&(window.addEventListener("online",()=>{this.flushOfflineQueue();}),navigator.onLine&&this.flushOfflineQueue());}pushToOfflineQueue(t){try{let i=[...this.getOfflineQueue(),...t].slice(-Et);localStorage.setItem(w,JSON.stringify(i));}catch(n){}}getOfflineQueue(){try{let t=localStorage.getItem(w);return t?JSON.parse(t):[]}catch(t){return []}}clearOfflineQueue(){try{localStorage.removeItem(w);}catch(t){}}};function $(){if(typeof window=="undefined")return "desktop";let e=window.innerWidth;return e<=768?"mobile":e<=1024?"tablet":"desktop"}function G(){return typeof window=="undefined"?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}var _t=/^https?:\/\/[^/]*(stripe\.com|paypal\.com|paddle\.com|lemonsqueezy\.com|gumroad\.com)(\/|$)/i;function T(e){var R,O,x,A,C,P;let t=typeof window=="undefined",n=(R=e==null?void 0:e.path)!=null?R:t?"":window.location.pathname+window.location.search,o=t?"":window.location.href,i=(O=e==null?void 0:e.title)!=null?O:t?"":document.title,r=(x=e==null?void 0:e.referrer)!=null?x:t?"":document.referrer,c=!t&&(r===""||_t.test(r))&&(A=K())!=null?A:r,s=G(),a=$(),u=t?void 0:(C=V(window.location.search))!=null?C:H();return {page:{path:n,url:o,title:i,referrer:c},device:N(p({},s),{type:a}),utm:u,locale:t?"en":navigator.language,timezone:t?"UTC":(P=Intl.DateTimeFormat().resolvedOptions().timeZone)!=null?P:"UTC",sdkVersion:"0.2.3"}}function W(e){if(typeof window=="undefined")return ()=>{};let t=history.pushState.bind(history),n=history.replaceState.bind(history);return history.pushState=function(...o){t(...o),e();},history.replaceState=function(...o){n(...o);},window.addEventListener("popstate",e),()=>{history.pushState=t,history.replaceState=n,window.removeEventListener("popstate",e);}}var wt={signup:[/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],login:[/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],pricing:[/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],checkout:[/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],success:[/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],onboarding:[/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],contact:[/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]},Z={signup:"signup_start",login:"login_view",pricing:"pricing_view",checkout:"checkout_view",success:"success_view",onboarding:"onboarding_view",contact:"contact_view"};function Tt(e,t){return e instanceof RegExp?e.test(t):t.includes(e)}function tt(e,t){var n;for(let o of Object.keys(Z))if(((n=t==null?void 0:t[o])!=null?n:wt[o]).some(r=>Tt(r,e)))return Z[o];return null}function et(e){return e==="signup_start"?"signup_submit":e==="login_view"?"login_submit":e==="checkout_view"?"checkout_submit":null}function nt(e,t){if(typeof document=="undefined")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var k="ib_identified";function ot(){return typeof localStorage=="undefined"?true:!localStorage.getItem(k)}function it(){typeof localStorage!="undefined"&&localStorage.setItem(k,"1");}function rt(){typeof localStorage!="undefined"&&localStorage.removeItem(k);}var st="data-ib-event",at="data-ib-";function ct(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){let i=o.getAttribute(st);if(i){let r={auto:true};for(let c of o.attributes)if(c.name.startsWith(at)&&c.name!==st){let s=c.name.slice(at.length);r[s]=c.value;}e(i,r);return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}function ut(e){if(typeof document=="undefined")return ()=>{};let t=n=>{let o=n.target;for(;o&&o!==document.body;){if(o.tagName==="A"){let i=o.href;if(!i||!/^https?:\/\//.test(i))return;try{let r=new URL(i);r.hostname!==window.location.hostname&&e("outbound_click",{auto:!0,url:i,hostname:r.hostname});}catch(r){}return}o=o.parentElement;}};return document.addEventListener("click",t,true),()=>document.removeEventListener("click",t,true)}var lt=class e{constructor(t){this.cleanupHistory=null;this.cleanupAttributes=null;this.cleanupOutbound=null;this.cleanupFormSubmit=null;if(this.config=t,this.queue=new v(t),typeof window!="undefined"&&(Y(window.location.search,document.referrer),t.autoDetect!==false)){let n=typeof t.autoDetect=="object"?t.autoDetect:{};n.dataAttributes!==false&&(this.cleanupAttributes=ct((o,i)=>this.track(o,i))),n.outboundClicks!==false&&(this.cleanupOutbound=ut((o,i)=>this.track(o,i)));}}static init(t){let n=U(t);return new e(n)}page(t){var o;if(!f(this.config))return;let n=T(t);if(this.queue.push(this.buildEvent("page",{context:n})),this.config.autoDetect!==false){let i=n.page.path,r=typeof this.config.autoDetect=="object"?this.config.autoDetect:{},c={signup:r.signupPaths,login:r.loginPaths,pricing:r.pricingPaths,checkout:r.checkoutPaths,success:r.successPaths,onboarding:r.onboardingPaths,contact:r.contactPaths},s=tt(i,c);if(s&&(this.queue.push(this.buildEvent("track",{event:s,properties:{auto:true},context:n})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${s} on ${i}`),r.formSubmit!==false)){(o=this.cleanupFormSubmit)==null||o.call(this);let a=et(s);a&&(this.cleanupFormSubmit=nt(a,u=>{this.queue.push(this.buildEvent("track",{event:u,properties:{auto:true}})),this.config.debug&&console.log(`[IndieBob] auto-detected: ${u}`);}));}}}track(t,n){f(this.config)&&this.queue.push(this.buildEvent("track",{event:t,properties:n}));}identify(t,n){if(f(this.config)&&(this.userId=t,this.queue.push(this.buildEvent("identify",{traits:n,userId:t})),this.config.autoDetect!==false)){let o=ot(),i=o?"signup":"login";this.queue.push(this.buildEvent("track",{event:i,properties:{auto:true}})),o&&it(),this.config.debug&&console.log(`[IndieBob] auto-detected: ${i} for ${t}`);}}revenue(t){var n;f(this.config)&&this.queue.push(this.buildEvent("revenue",{revenue:{amount:t.amount,currency:(n=t.currency)!=null?n:"USD",plan:t.plan,type:t.type}}));}optOut(){var t,n,o;this.queue.flush(),z(),rt(),this.userId=void 0,(t=this.cleanupAttributes)==null||t.call(this),(n=this.cleanupOutbound)==null||n.call(this),(o=this.cleanupFormSubmit)==null||o.call(this),this.cleanupAttributes=null,this.cleanupOutbound=null,this.cleanupFormSubmit=null,this.config.debug&&console.log("[IndieBob] opted out");}optIn(){X(),this.config.debug&&console.log("[IndieBob] opted in");}isOptedOut(){return J()}flush(){return l(this,null,function*(){yield this.queue.flush();})}getAnonymousId(){return b()}getSessionId(){return E()}getConfig(){return Object.freeze(p({},this.config))}enableAutoPage(){var t;return (t=this.cleanupHistory)==null||t.call(this),this.cleanupHistory=W(()=>this.page()),()=>{var n;(n=this.cleanupHistory)==null||n.call(this),this.cleanupHistory=null;}}buildEvent(t,n){var o,i;return {v:1,projectId:this.config.projectId,type:t,anonymousId:b(),userId:(o=this.userId)!=null?o:n.userId,sessionId:E(),timestamp:new Date().toISOString(),context:(i=n.context)!=null?i:T(),event:n.event,properties:n.properties,traits:n.traits,revenue:n.revenue}}};
|
|
2
|
-
exports.IndieBob=
|
|
3
|
-
;
|
|
1
|
+
var IndieBob=(function(exports){'use strict';var it="https://www.indiebob.com/api/collect";function O(e){if(!e.projectId||!e.projectId.startsWith("proj_"))throw new Error(`[IndieBob] Invalid projectId "${e.projectId}". Must start with "proj_".`);return {projectId:e.projectId,endpoint:e.endpoint??it,debug:e.debug??false,respectDnt:e.respectDnt??true,respectGpc:e.respectGpc??true,autoDetect:e.autoDetect??true,hashMode:e.hashMode??false}}var l="_ib_anon";function u(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-",t=new Uint8Array(21);if(typeof crypto<"u"&&crypto.getRandomValues)crypto.getRandomValues(t);else for(let o=0;o<21;o++)t[o]=Math.random()*64;let n="";for(let o of t)n+=e[o&63];return n}function b(){try{let e=localStorage.getItem(l);return e||(e=u(),localStorage.setItem(l,e)),e}catch{try{let e=sessionStorage.getItem(l);return e||(e=u(),sessionStorage.setItem(l,e)),e}catch{return u()}}}function P(){try{localStorage.removeItem(l);}catch{}try{sessionStorage.removeItem(l);}catch{}}var I="_ib_session",E="_ib_session_last",st=1800*1e3;function A(){try{return crypto.randomUUID()}catch{return u()}}function S(){try{let e=Date.now(),t=parseInt(sessionStorage.getItem(E)??"0",10),n=sessionStorage.getItem(I),o=t>0&&e-t>st;return (!n||o)&&(n=A(),sessionStorage.setItem(I,n)),sessionStorage.setItem(E,String(e)),n}catch{return A()}}function D(){try{sessionStorage.removeItem(I);}catch{}try{sessionStorage.removeItem(E);}catch{}}var g="_ib_first_utm",N="_ib_last_utm",m="_ib_referrer";function w(e){let t=new URLSearchParams(e),n={},o=false;!t.has("utm_source")&&t.get("ref")&&(n.source=t.get("ref"),o=true);for(let r of ["source","medium","campaign","term","content"])t.has("utm_"+r)&&(n[r]=t.get("utm_"+r),o=true);return o?n:null}function M(e,t){let n=w(e);try{n&&!localStorage.getItem(g)&&localStorage.setItem(g,JSON.stringify(n)),n&&localStorage.setItem(N,JSON.stringify(n)),t&&!localStorage.getItem(m)&&localStorage.setItem(m,t);}catch{}}function L(){try{let e=localStorage.getItem(g);return e?JSON.parse(e):void 0}catch{return}}function U(){try{return localStorage.getItem(m)??void 0}catch{return}}function F(){try{localStorage.removeItem(g);}catch{}try{localStorage.removeItem(N);}catch{}try{localStorage.removeItem(m);}catch{}}var f="ib_ignore";function j(e,t){let n=new URLSearchParams(e).get(f);return n==="1"?t.setItem(f,"1"):n==="0"&&t.removeItem(f),t.getItem(f)==="1"}function _(){try{return localStorage.getItem(f)==="1"}catch{return false}}function K(){return typeof navigator<"u"&&navigator.webdriver===true||_()}var h="_ib_optout",at="_ib_queue";function d(e){if(K())return false;try{if(localStorage.getItem(h))return !1}catch{}return !(e.respectDnt&&typeof navigator<"u"&&(navigator.doNotTrack==="1"||navigator.msDoNotTrack==="1")||e.respectGpc&&typeof navigator<"u"&&navigator.globalPrivacyControl===true)}function z(){try{localStorage.setItem(h,"1");}catch{}P(),D(),F();try{localStorage.removeItem(at);}catch{}}function Y(){try{localStorage.removeItem(h);}catch{}}function B(){try{return !!localStorage.getItem(h)}catch{return false}}function a(e,...t){e.debug&&console.log("[IndieBob]",...t);}async function x(e,t,n=false){let o=JSON.stringify(e);if(n&&typeof navigator<"u"&&navigator.sendBeacon){let r=new Blob([o],{type:"text/plain;charset=UTF-8"}),i=navigator.sendBeacon(t.endpoint,r);return a(t,"sendBeacon:",i,e.batch.length,"events"),i}for(let r=0;r<3;r++){try{let i=await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:o,keepalive:!0});if(i.ok)return a(t,"sent:",e.batch.length,"events"),!0;if(i.status>=400&&i.status<500)return a(t,"4xx error, not retrying:",i.status),!1}catch(i){a(t,"fetch error (attempt",r+1,"):",i);}r<2&&await new Promise(i=>setTimeout(i,1e3<<r));}return a(t,"failed to send after",3,"attempts"),false}var k="_ib_queue",ct=10,ut=5e3,lt=50,v=class{constructor(t,n){this.e=[];this.c=false;if(this.t=t,setInterval(()=>{this.e.length>0&&this.flush();},ut),typeof window>"u")return;let o=()=>{n?.(),this.flush(true);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&o();}),window.addEventListener("pagehide",o),window.addEventListener("online",()=>{this.p();}),navigator.onLine&&this.p();}push(t){this.e.push(t),this.e.length>=ct&&this.flush();}async flush(t=false){if(this.c&&!t||this.e.length===0)return;this.c=true;let n=this.e.splice(0);if(!await x({batch:n},this.t,t))try{let i=[...this.f(),...n].slice(-lt);localStorage.setItem(k,JSON.stringify(i));}catch{}this.c=false;}async p(){let t=this.f();if(t.length===0)return;try{localStorage.removeItem(k);}catch{}await x({batch:t},this.t);}f(){try{let t=localStorage.getItem(k);return t?JSON.parse(t):[]}catch{return []}}};function X(e,t){return e.pathname+e.search+(t?e.hash:"")}function H(e,t){if(typeof window>"u")return ()=>{};let n=history.pushState.bind(history),o=history.replaceState.bind(history);return history.pushState=function(...r){n(...r),e();},history.replaceState=function(...r){o(...r);},window.addEventListener("popstate",e),t&&window.addEventListener("hashchange",e),()=>{history.pushState=n,history.replaceState=o,window.removeEventListener("popstate",e),window.removeEventListener("hashchange",e);}}var dt=/^https?:\/\/[^/]*(stripe\.com|paypal\.com|paddle\.com|lemonsqueezy\.com|gumroad\.com)(\/|$)/i;function T(e,t){let n="0.3.0";if(typeof window>"u")return {page:{path:e?.path??"",url:"",title:e?.title??"",referrer:e?.referrer??""},device:{width:0,height:0,type:"desktop"},locale:"en",timezone:"UTC",sdkVersion:n};let o=e?.referrer??document.referrer,r=innerWidth;return {page:{path:e?.path??X(location,t),url:location.href,title:e?.title??document.title,referrer:o===""||dt.test(o)?U()??o:o},device:{width:r,height:innerHeight,type:r<=768?"mobile":r<=1024?"tablet":"desktop"},utm:w(location.search)??L(),locale:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"UTC",sdkVersion:n}}var pt=[["signup","signup_start",/\/(sign-?up|register|join|create-?account|get-?started|onboard|registro|inscription|s-?inscrire|anmeldung|registrieren|cadastro|registrazione|aanmelden|inschrijven)/i],["login","login_view",/\/(log-?in|sign-?in|auth(\/login)?|iniciar-?sesion|connexion|se-?connecter|anmelden|einloggen|entrar|accesso|accedi|inloggen)/i],["pricing","pricing_view",/\/(pricing|plans|upgrade|subscribe|precios|tarifs|preise|precos|prezzi|prijzen)/i],["checkout","checkout_view",/\/(checkout|cart|basket|pay(ment)?|order|comprar|pagar|panier|caisse|warenkorb|kasse|carrinho|carrello|winkelwagen)/i],["success","success_view",/\/(success|thank-?you|thanks|confirmation|confirmed|complete[d]?|gracias|merci|danke|obrigado|grazie|bedankt)/i],["onboarding","onboarding_view",/\/(onboarding|welcome|getting-?started|setup|bienvenido|bienvenue|willkommen|benvenuto|welkom)/i],["contact","contact_view",/\/(contact|contacto|kontakt|contato|contatto|nous-?contacter)/i]];function ft(e,t){return e instanceof RegExp?e.test(t):t.includes(e)}function V(e,t){for(let[n,o,r]of pt)if((t?.[`${n}Paths`]??[r]).some(c=>ft(c,e)))return o;return null}function $(e){let t=/^(signup|login|checkout)_/.exec(e);return t?t[1]+"_submit":null}function G(e,t){if(typeof document>"u")return ()=>{};let n=o=>{o.target instanceof HTMLFormElement&&t(e);};return document.addEventListener("submit",n,true),()=>document.removeEventListener("submit",n,true)}var R="ib_identified";function J(){return typeof localStorage>"u"?true:!localStorage.getItem(R)}function W(){typeof localStorage>"u"||localStorage.setItem(R,"1");}function q(){typeof localStorage>"u"||localStorage.removeItem(R);}var Q="data-ib-event",Z="data-ib-";function tt(e){for(;e&&e!==document.body;){let t=e.getAttribute(Q);if(t){let n={auto:true};for(let o of e.attributes)o.name.startsWith(Z)&&o.name!==Q&&(n[o.name.slice(Z.length)]=o.value);return [t,n]}e=e.parentElement;}return null}var gt=/\.(pdf|zip|dmg|exe|msi|pkg|apk|ipa|deb|rpm|appimage|t?gz|bz2|xz|tar|7z|rar|csv|xlsx?|docx?|pptx?|txt|epub|mp3|wav|mp4|mov|iso)$/i;function mt(e){let t=gt.exec(e);return t?t[1].toLowerCase():null}function ht(e,t,n,o){if(!/^https?:\/\//i.test(e))return null;try{let r=new URL(e),i=n&&mt(r.pathname);if(i)return ["file_download",{auto:!0,url:r.origin+r.pathname,path:r.pathname,ext:i}];if(o&&r.hostname!==t)return ["outbound_click",{auto:!0,url:e,hostname:r.hostname}]}catch{}return null}function et(e,t,n,o){if(typeof document>"u")return ()=>{};let r=i=>{let c=i.target,s=c?.closest?.("a");for(let p of [t&&tt(c),s&&ht(s.href,location.hostname,n,o)])p&&e(p[0],p[1]);};return document.addEventListener("click",r,true),()=>document.removeEventListener("click",r,true)}function vt(e,t,n){return t>n||e>=3e3}function yt(e,t,n){return n>0?Math.min(100,Math.round((e+t)/n*100)):0}function nt(){let e=0,t=0,n=0,o=0,r=()=>{let s=Date.now();t&&(e+=s-t),t=document.visibilityState==="visible"&&document.hasFocus()?s:0;},i=()=>{n=Math.max(n,yt(scrollY,innerHeight,Math.max(document.documentElement.scrollHeight,document.body?.scrollHeight??0)));},c=()=>{e=n=o=t=0,r();};for(let s of ["focus","blur"])window.addEventListener(s,r);return document.addEventListener("visibilitychange",r),window.addEventListener("scroll",i),c(),{y:i,b:c,I(s){if(s&&i(),r(),!vt(e,n,o))return null;let p={ms:Math.min(e,864e5),scroll:n};return e=0,o=n,p}}}var C={};function ot(){return typeof document<"u"&&(document.visibilityState==="hidden"||document.prerendering===true)}var y=class e{constructor(t){this.i=null;this.l=null;this.s=null;this.o=null;this.d=null;this.a=false;if(this.t=t,this.e=new v(t,()=>this.h(true)),typeof window<"u"){try{j(window.location.search,localStorage)&&console.info("IndieBob: this browser is excluded from analytics (ib_ignore)");}catch{}if(M(window.location.search,document.referrer),this.o=nt(),window.addEventListener("pageshow",n=>{n.persisted&&this.r!==void 0&&(this.r=void 0,this.page(this.g));}),t.autoDetect!==false){let n=typeof t.autoDetect=="object"?t.autoDetect:{};this.l=et((o,r)=>this.track(o,r),n.dataAttributes!==false,n.fileDownloads!==false,n.outboundClicks!==false);}}}static init(t){var o;let n=O(t);return typeof window>"u"?new e(n):C[o=n.projectId]??(C[o]=new e(n))}page(t){if(!d(this.t))return;if(this.r===void 0&&ot()){if(this.m=t,!this.a){this.a=true;let o=()=>{this.a&&!ot()&&(this.a=false,this.page(this.m));};document.addEventListener("visibilitychange",o),document.addEventListener("prerenderingchange",o);}return}let n=T(t,this.t.hashMode);if(n.page.path!==this.r&&(this.h(false),this.r=n.page.path,this.g=t,this.d=n,this.o&&(this.o.b(),setTimeout(this.o.y,1e3)),this.e.push(this.n("page",{context:n})),this.t.autoDetect!==false)){let o=n.page.path,r=typeof this.t.autoDetect=="object"?this.t.autoDetect:{},i=V(o,r);if(i&&(this.e.push(this.n("track",{event:i,properties:{auto:true},context:n})),a(this.t,`auto-detected: ${i} on ${o}`),r.formSubmit!==false)){this.s?.();let c=$(i);c&&(this.s=G(c,s=>{this.e.push(this.n("track",{event:s,properties:{auto:true}})),a(this.t,`auto-detected: ${s}`);}));}}}track(t,n){d(this.t)&&this.e.push(this.n("track",{event:t,properties:n}));}identify(t,n,o){if(d(this.t)&&(this.u=t,this.e.push(this.n("identify",{traits:n,userId:t})),this.t.autoDetect!==false)){let i=(typeof o?.isNew=="boolean"?o.isNew:J())?"signup":"login";this.e.push(this.n("track",{event:i,properties:{auto:typeof o?.isNew!="boolean"}})),W(),a(this.t,`${i} for ${t}`);}}revenue(t){d(this.t)&&this.e.push(this.n("revenue",{revenue:{amount:t.amount,currency:t.currency??"USD",plan:t.plan,type:t.type}}));}optOut(){this.e.flush(),z(),q(),this.u=void 0,this.l?.(),this.s?.(),this.l=null,this.s=null,a(this.t,"opted out");}optIn(){Y(),a(this.t,"opted in");}isOptedOut(){return B()}isIgnored(){return _()}async flush(){await this.e.flush();}getAnonymousId(){return b()}getSessionId(){return S()}getConfig(){return Object.freeze({...this.t})}enableAutoPage(){return this.i?.(),this.i=H(()=>this.page(),this.t.hashMode),()=>{this.i?.(),this.i=null;}}h(t){let n=this.d&&this.o?.I(t);n&&d(this.t)&&this.e.push(this.n("engagement",{context:this.d,engagement:n}));}n(t,n){return {...n,v:1,id:u(),projectId:this.t.projectId,type:t,anonymousId:b(),userId:this.u??n.userId,sessionId:S(),timestamp:new Date().toISOString(),context:n.context??T(void 0,this.t.hashMode)}}};function rt(e){let t=e("data-project");if(!t)return null;let n={projectId:t},o=e("data-api");return o&&(n.endpoint=o),e("data-hash-mode")==="true"&&(n.hashMode=true),{config:n,autoPage:e("data-auto-page")!=="false"}}if(typeof document<"u"){let e=document.currentScript,t=e&&rt(n=>e.getAttribute(n));if(t)try{let n=y.init(t.config);t.autoPage&&(n.page(),n.enableAutoPage());}catch(n){console.error(n);}}
|
|
2
|
+
exports.IndieBob=y;return exports;})({});
|
|
3
|
+
;IndieBob.IndieBob&&(IndieBob=Object.assign(IndieBob.IndieBob,IndieBob));
|