@shware/analytics 3.6.4 → 3.7.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/README.md +50 -3
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/constants/storage.cjs +12 -37
- package/dist/constants/storage.cjs.map +1 -1
- package/dist/constants/storage.d.cts +10 -8
- package/dist/constants/storage.d.cts.map +1 -0
- package/dist/constants/storage.d.mts +13 -0
- package/dist/constants/storage.d.mts.map +1 -0
- package/dist/constants/storage.mjs +12 -13
- package/dist/constants/storage.mjs.map +1 -1
- package/dist/feedback/index.cjs +14 -40
- package/dist/feedback/index.cjs.map +1 -1
- package/dist/feedback/index.d.cts +4 -4
- package/dist/feedback/index.d.cts.map +1 -0
- package/dist/feedback/index.d.mts +6 -0
- package/dist/feedback/index.d.mts.map +1 -0
- package/dist/feedback/index.mjs +12 -14
- package/dist/feedback/index.mjs.map +1 -1
- package/dist/hooks/use-app-analytics.cjs +46 -65
- package/dist/hooks/use-app-analytics.cjs.map +1 -1
- package/dist/hooks/use-app-analytics.d.cts +3 -1
- package/dist/hooks/use-app-analytics.d.cts.map +1 -0
- package/dist/hooks/use-app-analytics.d.mts +5 -0
- package/dist/hooks/use-app-analytics.d.mts.map +1 -0
- package/dist/hooks/use-app-analytics.mjs +41 -36
- package/dist/hooks/use-app-analytics.mjs.map +1 -1
- package/dist/hooks/use-click-id-persistence.cjs +43 -65
- package/dist/hooks/use-click-id-persistence.cjs.map +1 -1
- package/dist/hooks/use-click-id-persistence.d.cts +3 -1
- package/dist/hooks/use-click-id-persistence.d.cts.map +1 -0
- package/dist/hooks/use-click-id-persistence.d.mts +5 -0
- package/dist/hooks/use-click-id-persistence.d.mts.map +1 -0
- package/dist/hooks/use-click-id-persistence.mjs +40 -38
- package/dist/hooks/use-click-id-persistence.mjs.map +1 -1
- package/dist/hooks/use-outbound-click-analytics.cjs +33 -55
- package/dist/hooks/use-outbound-click-analytics.cjs.map +1 -1
- package/dist/hooks/use-outbound-click-analytics.d.cts +3 -1
- package/dist/hooks/use-outbound-click-analytics.d.cts.map +1 -0
- package/dist/hooks/{use-outbound-click-analytics.d.ts → use-outbound-click-analytics.d.mts} +3 -1
- package/dist/hooks/use-outbound-click-analytics.d.mts.map +1 -0
- package/dist/hooks/use-outbound-click-analytics.mjs +31 -29
- package/dist/hooks/use-outbound-click-analytics.mjs.map +1 -1
- package/dist/hooks/use-previous.cjs +11 -35
- package/dist/hooks/use-previous.cjs.map +1 -1
- package/dist/hooks/use-previous.d.cts +3 -1
- package/dist/hooks/use-previous.d.cts.map +1 -0
- package/dist/hooks/use-previous.d.mts +5 -0
- package/dist/hooks/use-previous.d.mts.map +1 -0
- package/dist/hooks/use-previous.mjs +9 -9
- package/dist/hooks/use-previous.mjs.map +1 -1
- package/dist/hooks/use-track-impression.cjs +24 -51
- package/dist/hooks/use-track-impression.cjs.map +1 -1
- package/dist/hooks/use-track-impression.d.cts +5 -6
- package/dist/hooks/use-track-impression.d.cts.map +1 -0
- package/dist/hooks/use-track-impression.d.mts +6 -0
- package/dist/hooks/use-track-impression.d.mts.map +1 -0
- package/dist/hooks/use-track-impression.mjs +22 -25
- package/dist/hooks/use-track-impression.mjs.map +1 -1
- package/dist/hooks/use-web-analytics.cjs +98 -109
- package/dist/hooks/use-web-analytics.cjs.map +1 -1
- package/dist/hooks/use-web-analytics.d.cts +3 -1
- package/dist/hooks/use-web-analytics.d.cts.map +1 -0
- package/dist/hooks/{use-web-analytics.d.ts → use-web-analytics.d.mts} +3 -1
- package/dist/hooks/use-web-analytics.d.mts.map +1 -0
- package/dist/hooks/use-web-analytics.mjs +93 -80
- package/dist/hooks/use-web-analytics.mjs.map +1 -1
- package/dist/index.cjs +28 -74
- package/dist/index.d.cts +11 -13
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +3 -34
- package/dist/link/index.cjs +31 -58
- package/dist/link/index.cjs.map +1 -1
- package/dist/link/index.d.cts +7 -7
- package/dist/link/index.d.cts.map +1 -0
- package/dist/link/index.d.mts +11 -0
- package/dist/link/index.d.mts.map +1 -0
- package/dist/link/index.mjs +28 -31
- package/dist/link/index.mjs.map +1 -1
- package/dist/native/fbsdk.cjs +12 -33
- package/dist/native/fbsdk.cjs.map +1 -1
- package/dist/native/fbsdk.d.cts +4 -4
- package/dist/native/fbsdk.d.cts.map +1 -0
- package/dist/native/{fbsdk.d.ts → fbsdk.d.mts} +4 -4
- package/dist/native/fbsdk.d.mts.map +1 -0
- package/dist/native/fbsdk.mjs +10 -7
- package/dist/native/fbsdk.mjs.map +1 -1
- package/dist/native/fingerprint.cjs +41 -64
- package/dist/native/fingerprint.cjs.map +1 -1
- package/dist/native/fingerprint.d.cts +22 -20
- package/dist/native/fingerprint.d.cts.map +1 -0
- package/dist/native/fingerprint.d.mts +28 -0
- package/dist/native/fingerprint.d.mts.map +1 -0
- package/dist/native/fingerprint.mjs +36 -42
- package/dist/native/fingerprint.mjs.map +1 -1
- package/dist/native/firebase.cjs +12 -39
- package/dist/native/firebase.cjs.map +1 -1
- package/dist/native/firebase.d.cts +4 -4
- package/dist/native/firebase.d.cts.map +1 -0
- package/dist/native/firebase.d.mts +6 -0
- package/dist/native/firebase.d.mts.map +1 -0
- package/dist/native/firebase.mjs +10 -13
- package/dist/native/firebase.mjs.map +1 -1
- package/dist/native/index.cjs +11 -45
- package/dist/native/index.d.cts +4 -7
- package/dist/native/index.d.mts +4 -0
- package/dist/native/index.mjs +2 -12
- package/dist/native/posthog.cjs +5 -30
- package/dist/native/posthog.cjs.map +1 -1
- package/dist/native/posthog.d.cts +3 -1
- package/dist/native/posthog.d.cts.map +1 -0
- package/dist/native/posthog.d.mts +5 -0
- package/dist/native/posthog.d.mts.map +1 -0
- package/dist/native/posthog.mjs +5 -6
- package/dist/native/posthog.mjs.map +1 -1
- package/dist/native/setup.cjs +91 -129
- package/dist/native/setup.cjs.map +1 -1
- package/dist/native/setup.d.cts +6 -6
- package/dist/native/setup.d.cts.map +1 -0
- package/dist/native/{setup.d.ts → setup.d.mts} +6 -6
- package/dist/native/setup.d.mts.map +1 -0
- package/dist/native/setup.mjs +83 -105
- package/dist/native/setup.mjs.map +1 -1
- package/dist/next/index.cjs +72 -145
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +18 -19
- package/dist/next/index.d.cts.map +1 -0
- package/dist/next/index.d.mts +21 -0
- package/dist/next/index.d.mts.map +1 -0
- package/dist/next/index.mjs +65 -107
- package/dist/next/index.mjs.map +1 -1
- package/dist/react-router/index.cjs +80 -144
- package/dist/react-router/index.cjs.map +1 -1
- package/dist/react-router/index.d.cts +18 -19
- package/dist/react-router/index.d.cts.map +1 -0
- package/dist/react-router/index.d.mts +21 -0
- package/dist/react-router/index.d.mts.map +1 -0
- package/dist/react-router/index.mjs +75 -115
- package/dist/react-router/index.mjs.map +1 -1
- package/dist/schema/index.cjs +188 -233
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +236 -235
- package/dist/schema/index.d.cts.map +1 -0
- package/dist/schema/index.d.mts +325 -0
- package/dist/schema/index.d.mts.map +1 -0
- package/dist/schema/index.mjs +178 -222
- package/dist/schema/index.mjs.map +1 -1
- package/dist/server/index.cjs +9 -40
- package/dist/server/index.d.cts +5 -9
- package/dist/server/index.d.mts +5 -0
- package/dist/server/index.mjs +5 -12
- package/dist/server/linkedin-conversions-api.cjs +66 -95
- package/dist/server/linkedin-conversions-api.cjs.map +1 -1
- package/dist/server/linkedin-conversions-api.d.cts +45 -45
- package/dist/server/linkedin-conversions-api.d.cts.map +1 -0
- package/dist/server/linkedin-conversions-api.d.mts +56 -0
- package/dist/server/linkedin-conversions-api.d.mts.map +1 -0
- package/dist/server/linkedin-conversions-api.mjs +63 -68
- package/dist/server/linkedin-conversions-api.mjs.map +1 -1
- package/dist/server/meta-conversions-api.cjs +157 -265
- package/dist/server/meta-conversions-api.cjs.map +1 -1
- package/dist/server/meta-conversions-api.d.cts +8 -9
- package/dist/server/meta-conversions-api.d.cts.map +1 -0
- package/dist/server/meta-conversions-api.d.mts +10 -0
- package/dist/server/meta-conversions-api.d.mts.map +1 -0
- package/dist/server/meta-conversions-api.mjs +151 -243
- package/dist/server/meta-conversions-api.mjs.map +1 -1
- package/dist/server/openai-conversions-api.cjs +69 -96
- package/dist/server/openai-conversions-api.cjs.map +1 -1
- package/dist/server/openai-conversions-api.d.cts +34 -34
- package/dist/server/openai-conversions-api.d.cts.map +1 -0
- package/dist/server/openai-conversions-api.d.mts +47 -0
- package/dist/server/openai-conversions-api.d.mts.map +1 -0
- package/dist/server/openai-conversions-api.mjs +65 -68
- package/dist/server/openai-conversions-api.mjs.map +1 -1
- package/dist/server/reddit-conversions-api.cjs +64 -91
- package/dist/server/reddit-conversions-api.cjs.map +1 -1
- package/dist/server/reddit-conversions-api.d.cts +61 -61
- package/dist/server/reddit-conversions-api.d.cts.map +1 -0
- package/dist/server/reddit-conversions-api.d.mts +75 -0
- package/dist/server/reddit-conversions-api.d.mts.map +1 -0
- package/dist/server/reddit-conversions-api.mjs +59 -62
- package/dist/server/reddit-conversions-api.mjs.map +1 -1
- package/dist/setup/index.cjs +34 -63
- package/dist/setup/index.cjs.map +1 -1
- package/dist/setup/index.d.cts +30 -30
- package/dist/setup/index.d.cts.map +1 -0
- package/dist/setup/index.d.mts +41 -0
- package/dist/setup/index.d.mts.map +1 -0
- package/dist/setup/index.mjs +31 -36
- package/dist/setup/index.mjs.map +1 -1
- package/dist/setup/session.cjs +70 -106
- package/dist/setup/session.cjs.map +1 -1
- package/dist/setup/session.d.cts +26 -24
- package/dist/setup/session.d.cts.map +1 -0
- package/dist/setup/session.d.mts +31 -0
- package/dist/setup/session.d.mts.map +1 -0
- package/dist/setup/session.mjs +68 -80
- package/dist/setup/session.mjs.map +1 -1
- package/dist/tanstack/index.cjs +86 -156
- package/dist/tanstack/index.cjs.map +1 -1
- package/dist/tanstack/index.d.cts +19 -20
- package/dist/tanstack/index.d.cts.map +1 -0
- package/dist/tanstack/index.d.mts +22 -0
- package/dist/tanstack/index.d.mts.map +1 -0
- package/dist/tanstack/index.mjs +81 -127
- package/dist/tanstack/index.mjs.map +1 -1
- package/dist/third-parties/google-analytics.cjs +18 -43
- package/dist/third-parties/google-analytics.cjs.map +1 -1
- package/dist/third-parties/google-analytics.d.cts +7 -7
- package/dist/third-parties/google-analytics.d.cts.map +1 -0
- package/dist/third-parties/google-analytics.d.mts +12 -0
- package/dist/third-parties/google-analytics.d.mts.map +1 -0
- package/dist/third-parties/google-analytics.mjs +16 -17
- package/dist/third-parties/google-analytics.mjs.map +1 -1
- package/dist/third-parties/ignored-events.cjs +35 -68
- package/dist/third-parties/ignored-events.cjs.map +1 -1
- package/dist/third-parties/ignored-events.d.cts +3 -1
- package/dist/third-parties/ignored-events.d.cts.map +1 -0
- package/dist/third-parties/ignored-events.d.mts +5 -0
- package/dist/third-parties/ignored-events.d.mts.map +1 -0
- package/dist/third-parties/ignored-events.mjs +34 -43
- package/dist/third-parties/ignored-events.mjs.map +1 -1
- package/dist/third-parties/index.cjs +16 -53
- package/dist/third-parties/index.d.cts +6 -12
- package/dist/third-parties/index.d.mts +6 -0
- package/dist/third-parties/index.mjs +1 -14
- package/dist/third-parties/linkedin-insight-tag.cjs +28 -50
- package/dist/third-parties/linkedin-insight-tag.cjs.map +1 -1
- package/dist/third-parties/linkedin-insight-tag.d.cts +8 -9
- package/dist/third-parties/linkedin-insight-tag.d.cts.map +1 -0
- package/dist/third-parties/{linkedin-insight-tag.d.ts → linkedin-insight-tag.d.mts} +8 -9
- package/dist/third-parties/linkedin-insight-tag.d.mts.map +1 -0
- package/dist/third-parties/linkedin-insight-tag.mjs +25 -23
- package/dist/third-parties/linkedin-insight-tag.mjs.map +1 -1
- package/dist/third-parties/meta-pixel.cjs +45 -66
- package/dist/third-parties/meta-pixel.cjs.map +1 -1
- package/dist/third-parties/meta-pixel.d.cts +7 -8
- package/dist/third-parties/meta-pixel.d.cts.map +1 -0
- package/dist/third-parties/meta-pixel.d.mts +12 -0
- package/dist/third-parties/meta-pixel.d.mts.map +1 -0
- package/dist/third-parties/meta-pixel.mjs +41 -38
- package/dist/third-parties/meta-pixel.mjs.map +1 -1
- package/dist/third-parties/openai-pixel.cjs +63 -68
- package/dist/third-parties/openai-pixel.cjs.map +1 -1
- package/dist/third-parties/openai-pixel.d.cts +7 -8
- package/dist/third-parties/openai-pixel.d.cts.map +1 -0
- package/dist/third-parties/{openai-pixel.d.ts → openai-pixel.d.mts} +7 -8
- package/dist/third-parties/openai-pixel.d.mts.map +1 -0
- package/dist/third-parties/openai-pixel.mjs +60 -41
- package/dist/third-parties/openai-pixel.mjs.map +1 -1
- package/dist/third-parties/posthog.cjs +23 -43
- package/dist/third-parties/posthog.cjs.map +1 -1
- package/dist/third-parties/posthog.d.cts +5 -5
- package/dist/third-parties/posthog.d.cts.map +1 -0
- package/dist/third-parties/{posthog.d.ts → posthog.d.mts} +5 -5
- package/dist/third-parties/posthog.d.mts.map +1 -0
- package/dist/third-parties/posthog.mjs +20 -16
- package/dist/third-parties/posthog.mjs.map +1 -1
- package/dist/third-parties/reddit-pixel.cjs +37 -58
- package/dist/third-parties/reddit-pixel.cjs.map +1 -1
- package/dist/third-parties/reddit-pixel.d.cts +7 -8
- package/dist/third-parties/reddit-pixel.d.cts.map +1 -0
- package/dist/third-parties/reddit-pixel.d.mts +12 -0
- package/dist/third-parties/reddit-pixel.d.mts.map +1 -0
- package/dist/third-parties/reddit-pixel.mjs +33 -30
- package/dist/third-parties/reddit-pixel.mjs.map +1 -1
- package/dist/track/fbq.cjs +179 -135
- package/dist/track/fbq.cjs.map +1 -1
- package/dist/track/fbq.d.cts +234 -233
- package/dist/track/fbq.d.cts.map +1 -0
- package/dist/track/fbq.d.mts +280 -0
- package/dist/track/fbq.d.mts.map +1 -0
- package/dist/track/fbq.mjs +176 -108
- package/dist/track/fbq.mjs.map +1 -1
- package/dist/track/gtag.cjs +63 -86
- package/dist/track/gtag.cjs.map +1 -1
- package/dist/track/gtag.d.cts +682 -682
- package/dist/track/gtag.d.cts.map +1 -0
- package/dist/track/gtag.d.mts +762 -0
- package/dist/track/gtag.d.mts.map +1 -0
- package/dist/track/gtag.mjs +62 -61
- package/dist/track/gtag.mjs.map +1 -1
- package/dist/track/index.cjs +111 -136
- package/dist/track/index.cjs.map +1 -1
- package/dist/track/index.d.cts +8 -8
- package/dist/track/index.d.cts.map +1 -0
- package/dist/track/{index.d.ts → index.d.mts} +8 -8
- package/dist/track/index.d.mts.map +1 -0
- package/dist/track/index.mjs +105 -106
- package/dist/track/index.mjs.map +1 -1
- package/dist/track/lintrk.cjs +0 -19
- package/dist/track/lintrk.d.cts +12 -10
- package/dist/track/lintrk.d.cts.map +1 -0
- package/dist/track/lintrk.d.mts +14 -0
- package/dist/track/lintrk.d.mts.map +1 -0
- package/dist/track/lintrk.mjs +1 -1
- package/dist/track/oaiq.cjs +153 -146
- package/dist/track/oaiq.cjs.map +1 -1
- package/dist/track/oaiq.d.cts +65 -64
- package/dist/track/oaiq.d.cts.map +1 -0
- package/dist/track/oaiq.d.mts +112 -0
- package/dist/track/oaiq.d.mts.map +1 -0
- package/dist/track/oaiq.mjs +149 -118
- package/dist/track/oaiq.mjs.map +1 -1
- package/dist/track/rdt.cjs +66 -110
- package/dist/track/rdt.cjs.map +1 -1
- package/dist/track/rdt.d.cts +74 -73
- package/dist/track/rdt.d.cts.map +1 -0
- package/dist/track/rdt.d.mts +97 -0
- package/dist/track/rdt.d.mts.map +1 -0
- package/dist/track/rdt.mjs +63 -83
- package/dist/track/rdt.mjs.map +1 -1
- package/dist/track/types.cjs +0 -19
- package/dist/track/types.d.cts +140 -111
- package/dist/track/types.d.cts.map +1 -0
- package/dist/track/types.d.mts +171 -0
- package/dist/track/types.d.mts.map +1 -0
- package/dist/track/types.mjs +1 -1
- package/dist/utils/field.cjs +8 -32
- package/dist/utils/field.cjs.map +1 -1
- package/dist/utils/field.d.cts +3 -1
- package/dist/utils/field.d.cts.map +1 -0
- package/dist/utils/{field.d.ts → field.d.mts} +3 -1
- package/dist/utils/field.d.mts.map +1 -0
- package/dist/utils/field.mjs +7 -7
- package/dist/utils/field.mjs.map +1 -1
- package/dist/utils/stripe.cjs +25 -49
- package/dist/utils/stripe.cjs.map +1 -1
- package/dist/utils/stripe.d.cts +3 -1
- package/dist/utils/stripe.d.cts.map +1 -0
- package/dist/utils/{stripe.d.ts → stripe.d.mts} +3 -1
- package/dist/utils/stripe.d.mts.map +1 -0
- package/dist/utils/stripe.mjs +23 -23
- package/dist/utils/stripe.mjs.map +1 -1
- package/dist/visitor/index.cjs +54 -86
- package/dist/visitor/index.cjs.map +1 -1
- package/dist/visitor/index.d.cts +4 -5
- package/dist/visitor/index.d.cts.map +1 -0
- package/dist/visitor/{index.d.ts → index.d.mts} +4 -5
- package/dist/visitor/index.d.mts.map +1 -0
- package/dist/visitor/index.mjs +51 -59
- package/dist/visitor/index.mjs.map +1 -1
- package/dist/visitor/types.cjs +0 -19
- package/dist/visitor/types.d.cts +15 -14
- package/dist/visitor/types.d.cts.map +1 -0
- package/dist/visitor/types.d.mts +21 -0
- package/dist/visitor/types.d.mts.map +1 -0
- package/dist/visitor/types.mjs +1 -1
- package/dist/web/index.cjs +108 -148
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.d.cts +5 -6
- package/dist/web/index.d.cts.map +1 -0
- package/dist/web/index.d.mts +9 -0
- package/dist/web/index.d.mts.map +1 -0
- package/dist/web/index.mjs +101 -109
- package/dist/web/index.mjs.map +1 -1
- package/package.json +102 -49
- package/dist/constants/storage.d.ts +0 -11
- package/dist/feedback/index.d.ts +0 -6
- package/dist/hooks/use-app-analytics.d.ts +0 -3
- package/dist/hooks/use-click-id-persistence.d.ts +0 -3
- package/dist/hooks/use-previous.d.ts +0 -3
- package/dist/hooks/use-track-impression.d.ts +0 -7
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.mjs.map +0 -1
- package/dist/link/index.d.ts +0 -11
- package/dist/native/fingerprint.d.ts +0 -26
- package/dist/native/firebase.d.ts +0 -6
- package/dist/native/index.cjs.map +0 -1
- package/dist/native/index.d.ts +0 -7
- package/dist/native/index.mjs.map +0 -1
- package/dist/native/posthog.d.ts +0 -3
- package/dist/next/index.d.ts +0 -22
- package/dist/react-router/index.d.ts +0 -22
- package/dist/schema/index.d.ts +0 -324
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.d.ts +0 -9
- package/dist/server/index.mjs.map +0 -1
- package/dist/server/linkedin-conversions-api.d.ts +0 -56
- package/dist/server/meta-conversions-api.d.ts +0 -11
- package/dist/server/openai-conversions-api.d.ts +0 -47
- package/dist/server/reddit-conversions-api.d.ts +0 -75
- package/dist/setup/index.d.ts +0 -41
- package/dist/setup/session.d.ts +0 -29
- package/dist/tanstack/index.d.ts +0 -23
- package/dist/third-parties/google-analytics.d.ts +0 -12
- package/dist/third-parties/ignored-events.d.ts +0 -3
- package/dist/third-parties/index.cjs.map +0 -1
- package/dist/third-parties/index.d.ts +0 -12
- package/dist/third-parties/index.mjs.map +0 -1
- package/dist/third-parties/meta-pixel.d.ts +0 -13
- package/dist/third-parties/reddit-pixel.d.ts +0 -13
- package/dist/track/fbq.d.ts +0 -279
- package/dist/track/gtag.d.ts +0 -762
- package/dist/track/lintrk.cjs.map +0 -1
- package/dist/track/lintrk.d.ts +0 -12
- package/dist/track/lintrk.mjs.map +0 -1
- package/dist/track/oaiq.d.ts +0 -111
- package/dist/track/rdt.d.ts +0 -96
- package/dist/track/types.cjs.map +0 -1
- package/dist/track/types.d.ts +0 -142
- package/dist/track/types.mjs.map +0 -1
- package/dist/visitor/types.cjs.map +0 -1
- package/dist/visitor/types.d.ts +0 -20
- package/dist/visitor/types.mjs.map +0 -1
- package/dist/web/index.d.ts +0 -10
|
@@ -1,107 +1,80 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/server/openai-conversions-api.ts
|
|
21
|
-
var openai_conversions_api_exports = {};
|
|
22
|
-
__export(openai_conversions_api_exports, {
|
|
23
|
-
getServerEvent: () => getServerEvent,
|
|
24
|
-
sendEvents: () => sendEvents
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(openai_conversions_api_exports);
|
|
27
|
-
var import_node_crypto = require("crypto");
|
|
28
|
-
var import_utils = require("@shware/utils");
|
|
29
|
-
var import_ignored_events = require("../third-parties/ignored-events.cjs");
|
|
30
|
-
var import_oaiq = require("../track/oaiq.cjs");
|
|
31
|
-
var import_field = require("../utils/field.cjs");
|
|
32
|
-
var ENDPOINT = "https://bzr.openai.com/v1/events";
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_third_parties_ignored_events = require("../third-parties/ignored-events.cjs");
|
|
3
|
+
const require_utils_field = require("../utils/field.cjs");
|
|
4
|
+
const require_track_oaiq = require("../track/oaiq.cjs");
|
|
5
|
+
let _shware_utils = require("@shware/utils");
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
7
|
+
//#region src/server/openai-conversions-api.ts
|
|
8
|
+
/**
|
|
9
|
+
* OpenAI Conversions API
|
|
10
|
+
* https://developers.openai.com/ads/conversions-api
|
|
11
|
+
* https://developers.openai.com/ads/supported-events
|
|
12
|
+
*/
|
|
13
|
+
const ENDPOINT = "https://bzr.openai.com/v1/events";
|
|
33
14
|
function sha256(value) {
|
|
34
|
-
|
|
15
|
+
return (0, node_crypto.createHash)("sha256").update(value).digest("hex");
|
|
35
16
|
}
|
|
36
17
|
function mapActionSource(source) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return "offline";
|
|
44
|
-
default:
|
|
45
|
-
return void 0;
|
|
46
|
-
}
|
|
18
|
+
switch (source) {
|
|
19
|
+
case "web": return "web";
|
|
20
|
+
case "app": return "mobile_app";
|
|
21
|
+
case "offline": return "offline";
|
|
22
|
+
default: return;
|
|
23
|
+
}
|
|
47
24
|
}
|
|
48
25
|
function getUser(data) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return Object.values(user).some((value) => value !== void 0) ? user : void 0;
|
|
26
|
+
const email = require_utils_field.getFirst(data.email)?.trim().toLowerCase();
|
|
27
|
+
const address = require_utils_field.getFirst(data.address);
|
|
28
|
+
const user = {
|
|
29
|
+
email_sha256: email ? sha256(email) : void 0,
|
|
30
|
+
external_id_sha256: data.user_id ? sha256(data.user_id) : void 0,
|
|
31
|
+
country: address?.country?.trim().toUpperCase(),
|
|
32
|
+
city: address?.city?.trim().toLowerCase(),
|
|
33
|
+
zip_code: address?.postal_code,
|
|
34
|
+
ip_address: data.ip_address,
|
|
35
|
+
user_agent: data.user_agent
|
|
36
|
+
};
|
|
37
|
+
return Object.values(user).some((value) => value !== void 0) ? user : void 0;
|
|
62
38
|
}
|
|
63
39
|
function getServerEvent(event, data) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
data: eventData
|
|
76
|
-
};
|
|
40
|
+
const { type, data: eventData } = require_track_oaiq.mapOAIEvent(event.name, event.properties);
|
|
41
|
+
return {
|
|
42
|
+
id: event.tags.idempotency_key ?? event.id.toString(),
|
|
43
|
+
type,
|
|
44
|
+
custom_event_name: type === "custom" ? event.name : void 0,
|
|
45
|
+
timestamp_ms: Date.now(),
|
|
46
|
+
source_url: event.tags.source_url,
|
|
47
|
+
action_source: mapActionSource(event.tags.source),
|
|
48
|
+
user: getUser(data),
|
|
49
|
+
data: eventData
|
|
50
|
+
};
|
|
77
51
|
}
|
|
78
52
|
async function sendEvents(apiKey, pixelId, events, data = {}, validateOnly = false) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
53
|
+
const dto = {
|
|
54
|
+
validate_only: validateOnly,
|
|
55
|
+
events: events.filter((event) => !require_third_parties_ignored_events.IGNORED_EVENTS.includes(event.name)).filter((event) => !require_track_oaiq.NON_AD_EVENTS.includes(event.name)).map((event) => getServerEvent(event, data))
|
|
56
|
+
};
|
|
57
|
+
if (dto.events.length === 0) return;
|
|
58
|
+
try {
|
|
59
|
+
const response = await (0, _shware_utils.fetch)(`${ENDPOINT}?pid=${pixelId}`, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
Accept: "application/json",
|
|
64
|
+
Authorization: `Bearer ${apiKey}`
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify(dto)
|
|
67
|
+
});
|
|
68
|
+
if (response.ok) return;
|
|
69
|
+
const { status } = response;
|
|
70
|
+
const message = await response.text();
|
|
71
|
+
console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error("Failed to send OpenAI conversion, network error:", error);
|
|
74
|
+
}
|
|
101
75
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.getServerEvent = getServerEvent;
|
|
78
|
+
exports.sendEvents = sendEvents;
|
|
79
|
+
|
|
107
80
|
//# sourceMappingURL=openai-conversions-api.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/openai-conversions-api.ts"],"sourcesContent":["/**\n * OpenAI Conversions API\n * https://developers.openai.com/ads/conversions-api\n * https://developers.openai.com/ads/supported-events\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { type EventData, NON_AD_EVENTS, mapOAIEvent } from '../track/oaiq';\nimport type { TrackEvent, TrackTags, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\nconst ENDPOINT = 'https://bzr.openai.com/v1/events';\n\ntype ActionSource =\n | 'web'\n | 'mobile_app'\n | 'offline'\n | 'physical_store'\n | 'phone_call'\n | 'email'\n | 'other';\n\n/**\n * User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex\n * strings; geographic, IP, and user-agent fields are sent as raw values.\n */\nexport interface OpenAIUser {\n email_sha256?: string;\n external_id_sha256?: string;\n /** Two-letter ISO 3166-1 country code (e.g. \"US\"). */\n country?: string;\n city?: string;\n zip_code?: string;\n ip_address?: string;\n user_agent?: string;\n}\n\nexport interface OpenAIEvent {\n /** Unique event id; combined with `type` for deduplication against pixel events. */\n id: string;\n /** Standard event name or `custom`. */\n type: string;\n /** Required when `type` is `custom`. */\n custom_event_name?: string;\n /** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */\n timestamp_ms: number;\n /** Required for `action_source: \"web\"`. */\n source_url?: string;\n action_source?: ActionSource;\n /** OpenAI-provided privacy-preserving identifier. */\n oppref?: string;\n /** When true, opts the event out of personalization. */\n opt_out?: boolean;\n user?: OpenAIUser;\n data: EventData;\n}\n\nexport interface CreateOpenAIEventsDTO {\n /** When true, validates the events without persisting them. */\n validate_only?: boolean;\n events: OpenAIEvent[];\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction mapActionSource(source: TrackTags['source']): ActionSource | undefined {\n switch (source) {\n case 'web':\n return 'web';\n case 'app':\n return 'mobile_app';\n case 'offline':\n return 'offline';\n default:\n return undefined;\n }\n}\n\nfunction getUser(data: UserProvidedData): OpenAIUser | undefined {\n const email = getFirst(data.email)?.trim().toLowerCase();\n const address = getFirst(data.address);\n\n const user: OpenAIUser = {\n email_sha256: email ? sha256(email) : undefined,\n external_id_sha256: data.user_id ? sha256(data.user_id) : undefined,\n country: address?.country?.trim().toUpperCase(),\n city: address?.city?.trim().toLowerCase(),\n zip_code: address?.postal_code,\n ip_address: data.ip_address,\n user_agent: data.user_agent,\n };\n\n return Object.values(user).some((value) => value !== undefined) ? user : undefined;\n}\n\nexport function getServerEvent(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n event: TrackEvent<any>,\n data: UserProvidedData\n): OpenAIEvent {\n const { type, data: eventData } = mapOAIEvent(event.name, event.properties);\n\n return {\n id: event.tags.idempotency_key ?? event.id.toString(),\n type,\n // For custom events the original track name is the OpenAI custom_event_name; this matches\n // the browser pixel so the two deduplicate. Standard events omit it.\n custom_event_name: type === 'custom' ? event.name : undefined,\n timestamp_ms: Date.now(),\n source_url: event.tags.source_url,\n action_source: mapActionSource(event.tags.source),\n user: getUser(data),\n data: eventData,\n };\n}\n\nexport async function sendEvents(\n apiKey: string,\n pixelId: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {},\n validateOnly = false\n) {\n const dto: CreateOpenAIEventsDTO = {\n validate_only: validateOnly,\n events: events\n .filter((event) => !IGNORED_EVENTS.includes(event.name))\n .filter((event) => !NON_AD_EVENTS.includes(event.name))\n .map((event) => getServerEvent(event, data)),\n };\n\n if (dto.events.length === 0) return;\n\n try {\n const response = await fetch(`${ENDPOINT}?pid=${pixelId}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send OpenAI conversion, network error:', error);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-conversions-api.cjs","names":["getFirst","mapOAIEvent","IGNORED_EVENTS","NON_AD_EVENTS"],"sources":["../../src/server/openai-conversions-api.ts"],"sourcesContent":["/**\n * OpenAI Conversions API\n * https://developers.openai.com/ads/conversions-api\n * https://developers.openai.com/ads/supported-events\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { type EventData, NON_AD_EVENTS, mapOAIEvent } from '../track/oaiq';\nimport type { TrackEvent, TrackTags, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\nconst ENDPOINT = 'https://bzr.openai.com/v1/events';\n\ntype ActionSource =\n | 'web'\n | 'mobile_app'\n | 'offline'\n | 'physical_store'\n | 'phone_call'\n | 'email'\n | 'other';\n\n/**\n * User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex\n * strings; geographic, IP, and user-agent fields are sent as raw values.\n */\nexport interface OpenAIUser {\n email_sha256?: string;\n external_id_sha256?: string;\n /** Two-letter ISO 3166-1 country code (e.g. \"US\"). */\n country?: string;\n city?: string;\n zip_code?: string;\n ip_address?: string;\n user_agent?: string;\n}\n\nexport interface OpenAIEvent {\n /** Unique event id; combined with `type` for deduplication against pixel events. */\n id: string;\n /** Standard event name or `custom`. */\n type: string;\n /** Required when `type` is `custom`. */\n custom_event_name?: string;\n /** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */\n timestamp_ms: number;\n /** Required for `action_source: \"web\"`. */\n source_url?: string;\n action_source?: ActionSource;\n /** OpenAI-provided privacy-preserving identifier. */\n oppref?: string;\n /** When true, opts the event out of personalization. */\n opt_out?: boolean;\n user?: OpenAIUser;\n data: EventData;\n}\n\nexport interface CreateOpenAIEventsDTO {\n /** When true, validates the events without persisting them. */\n validate_only?: boolean;\n events: OpenAIEvent[];\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction mapActionSource(source: TrackTags['source']): ActionSource | undefined {\n switch (source) {\n case 'web':\n return 'web';\n case 'app':\n return 'mobile_app';\n case 'offline':\n return 'offline';\n default:\n return undefined;\n }\n}\n\nfunction getUser(data: UserProvidedData): OpenAIUser | undefined {\n const email = getFirst(data.email)?.trim().toLowerCase();\n const address = getFirst(data.address);\n\n const user: OpenAIUser = {\n email_sha256: email ? sha256(email) : undefined,\n external_id_sha256: data.user_id ? sha256(data.user_id) : undefined,\n country: address?.country?.trim().toUpperCase(),\n city: address?.city?.trim().toLowerCase(),\n zip_code: address?.postal_code,\n ip_address: data.ip_address,\n user_agent: data.user_agent,\n };\n\n return Object.values(user).some((value) => value !== undefined) ? user : undefined;\n}\n\nexport function getServerEvent(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n event: TrackEvent<any>,\n data: UserProvidedData\n): OpenAIEvent {\n const { type, data: eventData } = mapOAIEvent(event.name, event.properties);\n\n return {\n id: event.tags.idempotency_key ?? event.id.toString(),\n type,\n // For custom events the original track name is the OpenAI custom_event_name; this matches\n // the browser pixel so the two deduplicate. Standard events omit it.\n custom_event_name: type === 'custom' ? event.name : undefined,\n timestamp_ms: Date.now(),\n source_url: event.tags.source_url,\n action_source: mapActionSource(event.tags.source),\n user: getUser(data),\n data: eventData,\n };\n}\n\nexport async function sendEvents(\n apiKey: string,\n pixelId: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {},\n validateOnly = false\n) {\n const dto: CreateOpenAIEventsDTO = {\n validate_only: validateOnly,\n events: events\n .filter((event) => !IGNORED_EVENTS.includes(event.name))\n .filter((event) => !NON_AD_EVENTS.includes(event.name))\n .map((event) => getServerEvent(event, data)),\n };\n\n if (dto.events.length === 0) return;\n\n try {\n const response = await fetch(`${ENDPOINT}?pid=${pixelId}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send OpenAI conversion, network error:', error);\n }\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,WAAW;AAoDjB,SAAS,OAAO,OAAuB;CACrC,QAAA,GAAA,YAAA,WAAA,CAAkB,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;AAEA,SAAS,gBAAgB,QAAuD;CAC9E,QAAQ,QAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,SACE;CACJ;AACF;AAEA,SAAS,QAAQ,MAAgD;CAC/D,MAAM,QAAQA,oBAAAA,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,YAAY;CACvD,MAAM,UAAUA,oBAAAA,SAAS,KAAK,OAAO;CAErC,MAAM,OAAmB;EACvB,cAAc,QAAQ,OAAO,KAAK,IAAI,KAAA;EACtC,oBAAoB,KAAK,UAAU,OAAO,KAAK,OAAO,IAAI,KAAA;EAC1D,SAAS,SAAS,SAAS,KAAK,CAAC,CAAC,YAAY;EAC9C,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,YAAY;EACxC,UAAU,SAAS;EACnB,YAAY,KAAK;EACjB,YAAY,KAAK;CACnB;CAEA,OAAO,OAAO,OAAO,IAAI,CAAC,CAAC,MAAM,UAAU,UAAU,KAAA,CAAS,IAAI,OAAO,KAAA;AAC3E;AAEA,SAAgB,eAEd,OACA,MACa;CACb,MAAM,EAAE,MAAM,MAAM,cAAcC,mBAAAA,YAAY,MAAM,MAAM,MAAM,UAAU;CAE1E,OAAO;EACL,IAAI,MAAM,KAAK,mBAAmB,MAAM,GAAG,SAAS;EACpD;EAGA,mBAAmB,SAAS,WAAW,MAAM,OAAO,KAAA;EACpD,cAAc,KAAK,IAAI;EACvB,YAAY,MAAM,KAAK;EACvB,eAAe,gBAAgB,MAAM,KAAK,MAAM;EAChD,MAAM,QAAQ,IAAI;EAClB,MAAM;CACR;AACF;AAEA,eAAsB,WACpB,QACA,SAEA,QACA,OAAyB,CAAC,GAC1B,eAAe,OACf;CACA,MAAM,MAA6B;EACjC,eAAe;EACf,QAAQ,OACL,QAAQ,UAAU,CAACC,qCAAAA,eAAe,SAAS,MAAM,IAAI,CAAC,CAAC,CACvD,QAAQ,UAAU,CAACC,mBAAAA,cAAc,SAAS,MAAM,IAAI,CAAC,CAAC,CACtD,KAAK,UAAU,eAAe,OAAO,IAAI,CAAC;CAC/C;CAEA,IAAI,IAAI,OAAO,WAAW,GAAG;CAE7B,IAAI;EACF,MAAM,WAAW,OAAA,GAAA,cAAA,MAAA,CAAY,GAAG,SAAS,OAAO,WAAW;GACzD,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,QAAQ;IACR,eAAe,UAAU;GAC3B;GACA,MAAM,KAAK,UAAU,GAAG;EAC1B,CAAC;EAED,IAAI,SAAS,IAAI;EACjB,MAAM,EAAE,WAAW;EACnB,MAAM,UAAU,MAAM,SAAS,KAAK;EACpC,QAAQ,MAAM,6CAA6C,OAAO,UAAU,SAAS;CACvF,SAAS,OAAO;EACd,QAAQ,MAAM,oDAAoD,KAAK;CACzE;AACF"}
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { TrackEvent, UserProvidedData } from "../track/types.cjs";
|
|
2
|
+
import { EventData } from "../track/oaiq.cjs";
|
|
3
|
+
//#region src/server/openai-conversions-api.d.ts
|
|
5
4
|
type ActionSource = 'web' | 'mobile_app' | 'offline' | 'physical_store' | 'phone_call' | 'email' | 'other';
|
|
6
5
|
/**
|
|
7
6
|
* User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex
|
|
8
7
|
* strings; geographic, IP, and user-agent fields are sent as raw values.
|
|
9
8
|
*/
|
|
10
9
|
interface OpenAIUser {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
email_sha256?: string;
|
|
11
|
+
external_id_sha256?: string;
|
|
12
|
+
/** Two-letter ISO 3166-1 country code (e.g. "US"). */
|
|
13
|
+
country?: string;
|
|
14
|
+
city?: string;
|
|
15
|
+
zip_code?: string;
|
|
16
|
+
ip_address?: string;
|
|
17
|
+
user_agent?: string;
|
|
19
18
|
}
|
|
20
19
|
interface OpenAIEvent {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
/** Unique event id; combined with `type` for deduplication against pixel events. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Standard event name or `custom`. */
|
|
23
|
+
type: string;
|
|
24
|
+
/** Required when `type` is `custom`. */
|
|
25
|
+
custom_event_name?: string;
|
|
26
|
+
/** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */
|
|
27
|
+
timestamp_ms: number;
|
|
28
|
+
/** Required for `action_source: "web"`. */
|
|
29
|
+
source_url?: string;
|
|
30
|
+
action_source?: ActionSource;
|
|
31
|
+
/** OpenAI-provided privacy-preserving identifier. */
|
|
32
|
+
oppref?: string;
|
|
33
|
+
/** When true, opts the event out of personalization. */
|
|
34
|
+
opt_out?: boolean;
|
|
35
|
+
user?: OpenAIUser;
|
|
36
|
+
data: EventData;
|
|
38
37
|
}
|
|
39
38
|
interface CreateOpenAIEventsDTO {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/** When true, validates the events without persisting them. */
|
|
40
|
+
validate_only?: boolean;
|
|
41
|
+
events: OpenAIEvent[];
|
|
43
42
|
}
|
|
44
43
|
declare function getServerEvent(event: TrackEvent<any>, data: UserProvidedData): OpenAIEvent;
|
|
45
44
|
declare function sendEvents(apiKey: string, pixelId: string, events: TrackEvent<any>[], data?: UserProvidedData, validateOnly?: boolean): Promise<void>;
|
|
46
|
-
|
|
47
|
-
export {
|
|
45
|
+
//#endregion
|
|
46
|
+
export { CreateOpenAIEventsDTO, OpenAIEvent, OpenAIUser, getServerEvent, sendEvents };
|
|
47
|
+
//# sourceMappingURL=openai-conversions-api.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-conversions-api.d.cts","names":[],"sources":["../../src/server/openai-conversions-api.ts"],"mappings":";;;KAcK;;;;;UAaY;EACf;EACA;;EAEA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;EACA,gBAAgB;;EAEhB;;EAEA;EACA,OAAO;EACP,MAAM;;UAGS;;EAEf;EACA,QAAQ;;iBAqCM,eAEd,OAAO,iBACP,MAAM,mBACL;iBAiBmB,WACpB,gBACA,iBAEA,QAAQ,mBACR,OAAM,kBACN,yBAAoB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TrackEvent, UserProvidedData } from "../track/types.mjs";
|
|
2
|
+
import { EventData } from "../track/oaiq.mjs";
|
|
3
|
+
//#region src/server/openai-conversions-api.d.ts
|
|
4
|
+
type ActionSource = 'web' | 'mobile_app' | 'offline' | 'physical_store' | 'phone_call' | 'email' | 'other';
|
|
5
|
+
/**
|
|
6
|
+
* User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex
|
|
7
|
+
* strings; geographic, IP, and user-agent fields are sent as raw values.
|
|
8
|
+
*/
|
|
9
|
+
interface OpenAIUser {
|
|
10
|
+
email_sha256?: string;
|
|
11
|
+
external_id_sha256?: string;
|
|
12
|
+
/** Two-letter ISO 3166-1 country code (e.g. "US"). */
|
|
13
|
+
country?: string;
|
|
14
|
+
city?: string;
|
|
15
|
+
zip_code?: string;
|
|
16
|
+
ip_address?: string;
|
|
17
|
+
user_agent?: string;
|
|
18
|
+
}
|
|
19
|
+
interface OpenAIEvent {
|
|
20
|
+
/** Unique event id; combined with `type` for deduplication against pixel events. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Standard event name or `custom`. */
|
|
23
|
+
type: string;
|
|
24
|
+
/** Required when `type` is `custom`. */
|
|
25
|
+
custom_event_name?: string;
|
|
26
|
+
/** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */
|
|
27
|
+
timestamp_ms: number;
|
|
28
|
+
/** Required for `action_source: "web"`. */
|
|
29
|
+
source_url?: string;
|
|
30
|
+
action_source?: ActionSource;
|
|
31
|
+
/** OpenAI-provided privacy-preserving identifier. */
|
|
32
|
+
oppref?: string;
|
|
33
|
+
/** When true, opts the event out of personalization. */
|
|
34
|
+
opt_out?: boolean;
|
|
35
|
+
user?: OpenAIUser;
|
|
36
|
+
data: EventData;
|
|
37
|
+
}
|
|
38
|
+
interface CreateOpenAIEventsDTO {
|
|
39
|
+
/** When true, validates the events without persisting them. */
|
|
40
|
+
validate_only?: boolean;
|
|
41
|
+
events: OpenAIEvent[];
|
|
42
|
+
}
|
|
43
|
+
declare function getServerEvent(event: TrackEvent<any>, data: UserProvidedData): OpenAIEvent;
|
|
44
|
+
declare function sendEvents(apiKey: string, pixelId: string, events: TrackEvent<any>[], data?: UserProvidedData, validateOnly?: boolean): Promise<void>;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { CreateOpenAIEventsDTO, OpenAIEvent, OpenAIUser, getServerEvent, sendEvents };
|
|
47
|
+
//# sourceMappingURL=openai-conversions-api.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-conversions-api.d.mts","names":[],"sources":["../../src/server/openai-conversions-api.ts"],"mappings":";;;KAcK;;;;;UAaY;EACf;EACA;;EAEA;EACA;EACA;EACA;EACA;;UAGe;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;EACA,gBAAgB;;EAEhB;;EAEA;EACA,OAAO;EACP,MAAM;;UAGS;;EAEf;EACA,QAAQ;;iBAqCM,eAEd,OAAO,iBACP,MAAM,mBACL;iBAiBmB,WACpB,gBACA,iBAEA,QAAQ,mBACR,OAAM,kBACN,yBAAoB"}
|
|
@@ -1,81 +1,78 @@
|
|
|
1
|
-
// src/server/openai-conversions-api.ts
|
|
2
|
-
import { createHash } from "crypto";
|
|
3
|
-
import { fetch } from "@shware/utils";
|
|
4
1
|
import { IGNORED_EVENTS } from "../third-parties/ignored-events.mjs";
|
|
5
|
-
import { NON_AD_EVENTS, mapOAIEvent } from "../track/oaiq.mjs";
|
|
6
2
|
import { getFirst } from "../utils/field.mjs";
|
|
7
|
-
|
|
3
|
+
import { NON_AD_EVENTS, mapOAIEvent } from "../track/oaiq.mjs";
|
|
4
|
+
import { fetch } from "@shware/utils";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
//#region src/server/openai-conversions-api.ts
|
|
7
|
+
/**
|
|
8
|
+
* OpenAI Conversions API
|
|
9
|
+
* https://developers.openai.com/ads/conversions-api
|
|
10
|
+
* https://developers.openai.com/ads/supported-events
|
|
11
|
+
*/
|
|
12
|
+
const ENDPOINT = "https://bzr.openai.com/v1/events";
|
|
8
13
|
function sha256(value) {
|
|
9
|
-
|
|
14
|
+
return createHash("sha256").update(value).digest("hex");
|
|
10
15
|
}
|
|
11
16
|
function mapActionSource(source) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return "offline";
|
|
19
|
-
default:
|
|
20
|
-
return void 0;
|
|
21
|
-
}
|
|
17
|
+
switch (source) {
|
|
18
|
+
case "web": return "web";
|
|
19
|
+
case "app": return "mobile_app";
|
|
20
|
+
case "offline": return "offline";
|
|
21
|
+
default: return;
|
|
22
|
+
}
|
|
22
23
|
}
|
|
23
24
|
function getUser(data) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return Object.values(user).some((value) => value !== void 0) ? user : void 0;
|
|
25
|
+
const email = getFirst(data.email)?.trim().toLowerCase();
|
|
26
|
+
const address = getFirst(data.address);
|
|
27
|
+
const user = {
|
|
28
|
+
email_sha256: email ? sha256(email) : void 0,
|
|
29
|
+
external_id_sha256: data.user_id ? sha256(data.user_id) : void 0,
|
|
30
|
+
country: address?.country?.trim().toUpperCase(),
|
|
31
|
+
city: address?.city?.trim().toLowerCase(),
|
|
32
|
+
zip_code: address?.postal_code,
|
|
33
|
+
ip_address: data.ip_address,
|
|
34
|
+
user_agent: data.user_agent
|
|
35
|
+
};
|
|
36
|
+
return Object.values(user).some((value) => value !== void 0) ? user : void 0;
|
|
37
37
|
}
|
|
38
38
|
function getServerEvent(event, data) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
data: eventData
|
|
51
|
-
};
|
|
39
|
+
const { type, data: eventData } = mapOAIEvent(event.name, event.properties);
|
|
40
|
+
return {
|
|
41
|
+
id: event.tags.idempotency_key ?? event.id.toString(),
|
|
42
|
+
type,
|
|
43
|
+
custom_event_name: type === "custom" ? event.name : void 0,
|
|
44
|
+
timestamp_ms: Date.now(),
|
|
45
|
+
source_url: event.tags.source_url,
|
|
46
|
+
action_source: mapActionSource(event.tags.source),
|
|
47
|
+
user: getUser(data),
|
|
48
|
+
data: eventData
|
|
49
|
+
};
|
|
52
50
|
}
|
|
53
51
|
async function sendEvents(apiKey, pixelId, events, data = {}, validateOnly = false) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
52
|
+
const dto = {
|
|
53
|
+
validate_only: validateOnly,
|
|
54
|
+
events: events.filter((event) => !IGNORED_EVENTS.includes(event.name)).filter((event) => !NON_AD_EVENTS.includes(event.name)).map((event) => getServerEvent(event, data))
|
|
55
|
+
};
|
|
56
|
+
if (dto.events.length === 0) return;
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(`${ENDPOINT}?pid=${pixelId}`, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
Accept: "application/json",
|
|
63
|
+
Authorization: `Bearer ${apiKey}`
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify(dto)
|
|
66
|
+
});
|
|
67
|
+
if (response.ok) return;
|
|
68
|
+
const { status } = response;
|
|
69
|
+
const message = await response.text();
|
|
70
|
+
console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error("Failed to send OpenAI conversion, network error:", error);
|
|
73
|
+
}
|
|
76
74
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { getServerEvent, sendEvents };
|
|
77
|
+
|
|
81
78
|
//# sourceMappingURL=openai-conversions-api.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/openai-conversions-api.ts"],"sourcesContent":["/**\n * OpenAI Conversions API\n * https://developers.openai.com/ads/conversions-api\n * https://developers.openai.com/ads/supported-events\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { type EventData, NON_AD_EVENTS, mapOAIEvent } from '../track/oaiq';\nimport type { TrackEvent, TrackTags, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\nconst ENDPOINT = 'https://bzr.openai.com/v1/events';\n\ntype ActionSource =\n | 'web'\n | 'mobile_app'\n | 'offline'\n | 'physical_store'\n | 'phone_call'\n | 'email'\n | 'other';\n\n/**\n * User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex\n * strings; geographic, IP, and user-agent fields are sent as raw values.\n */\nexport interface OpenAIUser {\n email_sha256?: string;\n external_id_sha256?: string;\n /** Two-letter ISO 3166-1 country code (e.g. \"US\"). */\n country?: string;\n city?: string;\n zip_code?: string;\n ip_address?: string;\n user_agent?: string;\n}\n\nexport interface OpenAIEvent {\n /** Unique event id; combined with `type` for deduplication against pixel events. */\n id: string;\n /** Standard event name or `custom`. */\n type: string;\n /** Required when `type` is `custom`. */\n custom_event_name?: string;\n /** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */\n timestamp_ms: number;\n /** Required for `action_source: \"web\"`. */\n source_url?: string;\n action_source?: ActionSource;\n /** OpenAI-provided privacy-preserving identifier. */\n oppref?: string;\n /** When true, opts the event out of personalization. */\n opt_out?: boolean;\n user?: OpenAIUser;\n data: EventData;\n}\n\nexport interface CreateOpenAIEventsDTO {\n /** When true, validates the events without persisting them. */\n validate_only?: boolean;\n events: OpenAIEvent[];\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction mapActionSource(source: TrackTags['source']): ActionSource | undefined {\n switch (source) {\n case 'web':\n return 'web';\n case 'app':\n return 'mobile_app';\n case 'offline':\n return 'offline';\n default:\n return undefined;\n }\n}\n\nfunction getUser(data: UserProvidedData): OpenAIUser | undefined {\n const email = getFirst(data.email)?.trim().toLowerCase();\n const address = getFirst(data.address);\n\n const user: OpenAIUser = {\n email_sha256: email ? sha256(email) : undefined,\n external_id_sha256: data.user_id ? sha256(data.user_id) : undefined,\n country: address?.country?.trim().toUpperCase(),\n city: address?.city?.trim().toLowerCase(),\n zip_code: address?.postal_code,\n ip_address: data.ip_address,\n user_agent: data.user_agent,\n };\n\n return Object.values(user).some((value) => value !== undefined) ? user : undefined;\n}\n\nexport function getServerEvent(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n event: TrackEvent<any>,\n data: UserProvidedData\n): OpenAIEvent {\n const { type, data: eventData } = mapOAIEvent(event.name, event.properties);\n\n return {\n id: event.tags.idempotency_key ?? event.id.toString(),\n type,\n // For custom events the original track name is the OpenAI custom_event_name; this matches\n // the browser pixel so the two deduplicate. Standard events omit it.\n custom_event_name: type === 'custom' ? event.name : undefined,\n timestamp_ms: Date.now(),\n source_url: event.tags.source_url,\n action_source: mapActionSource(event.tags.source),\n user: getUser(data),\n data: eventData,\n };\n}\n\nexport async function sendEvents(\n apiKey: string,\n pixelId: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {},\n validateOnly = false\n) {\n const dto: CreateOpenAIEventsDTO = {\n validate_only: validateOnly,\n events: events\n .filter((event) => !IGNORED_EVENTS.includes(event.name))\n .filter((event) => !NON_AD_EVENTS.includes(event.name))\n .map((event) => getServerEvent(event, data)),\n };\n\n if (dto.events.length === 0) return;\n\n try {\n const response = await fetch(`${ENDPOINT}?pid=${pixelId}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send OpenAI conversion, network error:', error);\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-conversions-api.mjs","names":[],"sources":["../../src/server/openai-conversions-api.ts"],"sourcesContent":["/**\n * OpenAI Conversions API\n * https://developers.openai.com/ads/conversions-api\n * https://developers.openai.com/ads/supported-events\n */\nimport { createHash } from 'node:crypto';\nimport { fetch } from '@shware/utils';\nimport { IGNORED_EVENTS } from '../third-parties/ignored-events';\nimport { type EventData, NON_AD_EVENTS, mapOAIEvent } from '../track/oaiq';\nimport type { TrackEvent, TrackTags, UserProvidedData } from '../track/types';\nimport { getFirst } from '../utils/field';\n\nconst ENDPOINT = 'https://bzr.openai.com/v1/events';\n\ntype ActionSource =\n | 'web'\n | 'mobile_app'\n | 'offline'\n | 'physical_store'\n | 'phone_call'\n | 'email'\n | 'other';\n\n/**\n * User/identity fields. Email and external id must be sent as lowercase 64-char SHA-256 hex\n * strings; geographic, IP, and user-agent fields are sent as raw values.\n */\nexport interface OpenAIUser {\n email_sha256?: string;\n external_id_sha256?: string;\n /** Two-letter ISO 3166-1 country code (e.g. \"US\"). */\n country?: string;\n city?: string;\n zip_code?: string;\n ip_address?: string;\n user_agent?: string;\n}\n\nexport interface OpenAIEvent {\n /** Unique event id; combined with `type` for deduplication against pixel events. */\n id: string;\n /** Standard event name or `custom`. */\n type: string;\n /** Required when `type` is `custom`. */\n custom_event_name?: string;\n /** Event timestamp in ms; must be within 7 days and no more than 10 minutes in the future. */\n timestamp_ms: number;\n /** Required for `action_source: \"web\"`. */\n source_url?: string;\n action_source?: ActionSource;\n /** OpenAI-provided privacy-preserving identifier. */\n oppref?: string;\n /** When true, opts the event out of personalization. */\n opt_out?: boolean;\n user?: OpenAIUser;\n data: EventData;\n}\n\nexport interface CreateOpenAIEventsDTO {\n /** When true, validates the events without persisting them. */\n validate_only?: boolean;\n events: OpenAIEvent[];\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nfunction mapActionSource(source: TrackTags['source']): ActionSource | undefined {\n switch (source) {\n case 'web':\n return 'web';\n case 'app':\n return 'mobile_app';\n case 'offline':\n return 'offline';\n default:\n return undefined;\n }\n}\n\nfunction getUser(data: UserProvidedData): OpenAIUser | undefined {\n const email = getFirst(data.email)?.trim().toLowerCase();\n const address = getFirst(data.address);\n\n const user: OpenAIUser = {\n email_sha256: email ? sha256(email) : undefined,\n external_id_sha256: data.user_id ? sha256(data.user_id) : undefined,\n country: address?.country?.trim().toUpperCase(),\n city: address?.city?.trim().toLowerCase(),\n zip_code: address?.postal_code,\n ip_address: data.ip_address,\n user_agent: data.user_agent,\n };\n\n return Object.values(user).some((value) => value !== undefined) ? user : undefined;\n}\n\nexport function getServerEvent(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n event: TrackEvent<any>,\n data: UserProvidedData\n): OpenAIEvent {\n const { type, data: eventData } = mapOAIEvent(event.name, event.properties);\n\n return {\n id: event.tags.idempotency_key ?? event.id.toString(),\n type,\n // For custom events the original track name is the OpenAI custom_event_name; this matches\n // the browser pixel so the two deduplicate. Standard events omit it.\n custom_event_name: type === 'custom' ? event.name : undefined,\n timestamp_ms: Date.now(),\n source_url: event.tags.source_url,\n action_source: mapActionSource(event.tags.source),\n user: getUser(data),\n data: eventData,\n };\n}\n\nexport async function sendEvents(\n apiKey: string,\n pixelId: string,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n events: TrackEvent<any>[],\n data: UserProvidedData = {},\n validateOnly = false\n) {\n const dto: CreateOpenAIEventsDTO = {\n validate_only: validateOnly,\n events: events\n .filter((event) => !IGNORED_EVENTS.includes(event.name))\n .filter((event) => !NON_AD_EVENTS.includes(event.name))\n .map((event) => getServerEvent(event, data)),\n };\n\n if (dto.events.length === 0) return;\n\n try {\n const response = await fetch(`${ENDPOINT}?pid=${pixelId}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(dto),\n });\n\n if (response.ok) return;\n const { status } = response;\n const message = await response.text();\n console.error(`Failed to send OpenAI conversion, status: ${status}, body: ${message}`);\n } catch (error) {\n console.error('Failed to send OpenAI conversion, network error:', error);\n }\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,WAAW;AAoDjB,SAAS,OAAO,OAAuB;CACrC,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;AAEA,SAAS,gBAAgB,QAAuD;CAC9E,QAAQ,QAAR;EACE,KAAK,OACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,WACH,OAAO;EACT,SACE;CACJ;AACF;AAEA,SAAS,QAAQ,MAAgD;CAC/D,MAAM,QAAQ,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,YAAY;CACvD,MAAM,UAAU,SAAS,KAAK,OAAO;CAErC,MAAM,OAAmB;EACvB,cAAc,QAAQ,OAAO,KAAK,IAAI,KAAA;EACtC,oBAAoB,KAAK,UAAU,OAAO,KAAK,OAAO,IAAI,KAAA;EAC1D,SAAS,SAAS,SAAS,KAAK,CAAC,CAAC,YAAY;EAC9C,MAAM,SAAS,MAAM,KAAK,CAAC,CAAC,YAAY;EACxC,UAAU,SAAS;EACnB,YAAY,KAAK;EACjB,YAAY,KAAK;CACnB;CAEA,OAAO,OAAO,OAAO,IAAI,CAAC,CAAC,MAAM,UAAU,UAAU,KAAA,CAAS,IAAI,OAAO,KAAA;AAC3E;AAEA,SAAgB,eAEd,OACA,MACa;CACb,MAAM,EAAE,MAAM,MAAM,cAAc,YAAY,MAAM,MAAM,MAAM,UAAU;CAE1E,OAAO;EACL,IAAI,MAAM,KAAK,mBAAmB,MAAM,GAAG,SAAS;EACpD;EAGA,mBAAmB,SAAS,WAAW,MAAM,OAAO,KAAA;EACpD,cAAc,KAAK,IAAI;EACvB,YAAY,MAAM,KAAK;EACvB,eAAe,gBAAgB,MAAM,KAAK,MAAM;EAChD,MAAM,QAAQ,IAAI;EAClB,MAAM;CACR;AACF;AAEA,eAAsB,WACpB,QACA,SAEA,QACA,OAAyB,CAAC,GAC1B,eAAe,OACf;CACA,MAAM,MAA6B;EACjC,eAAe;EACf,QAAQ,OACL,QAAQ,UAAU,CAAC,eAAe,SAAS,MAAM,IAAI,CAAC,CAAC,CACvD,QAAQ,UAAU,CAAC,cAAc,SAAS,MAAM,IAAI,CAAC,CAAC,CACtD,KAAK,UAAU,eAAe,OAAO,IAAI,CAAC;CAC/C;CAEA,IAAI,IAAI,OAAO,WAAW,GAAG;CAE7B,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,GAAG,SAAS,OAAO,WAAW;GACzD,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,QAAQ;IACR,eAAe,UAAU;GAC3B;GACA,MAAM,KAAK,UAAU,GAAG;EAC1B,CAAC;EAED,IAAI,SAAS,IAAI;EACjB,MAAM,EAAE,WAAW;EACnB,MAAM,UAAU,MAAM,SAAS,KAAK;EACpC,QAAQ,MAAM,6CAA6C,OAAO,UAAU,SAAS;CACvF,SAAS,OAAO;EACd,QAAQ,MAAM,oDAAoD,KAAK;CACzE;AACF"}
|