@guidelytech/shared 0.9.0 → 0.11.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/dist/chunk-TGIUEYXM.js +1937 -0
- package/dist/chunk-TGIUEYXM.js.map +1 -0
- package/dist/index.cjs +1684 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +773 -3951
- package/dist/index.d.ts +773 -3951
- package/dist/index.js +568 -62
- package/dist/index.js.map +1 -1
- package/dist/runtime-BM5cztmJ.d.cts +5234 -0
- package/dist/runtime-BM5cztmJ.d.ts +5234 -0
- package/dist/runtime.cjs +1212 -6
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +2 -511
- package/dist/runtime.d.ts +2 -511
- package/dist/runtime.js +157 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,9 +21,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
ADVANCE_ON: () => ADVANCE_ON,
|
|
24
|
+
AGENT_METADATA_MAX_BYTES: () => AGENT_METADATA_MAX_BYTES,
|
|
25
|
+
AGENT_METADATA_MAX_KEYS: () => AGENT_METADATA_MAX_KEYS,
|
|
26
|
+
AGENT_OUTCOMES: () => AGENT_OUTCOMES,
|
|
27
|
+
AGENT_TOOL_CALLS_PER_TURN: () => AGENT_TOOL_CALLS_PER_TURN,
|
|
28
|
+
AGENT_TOOL_STATUSES: () => AGENT_TOOL_STATUSES,
|
|
29
|
+
AGENT_TURNS_PER_BATCH: () => AGENT_TURNS_PER_BATCH,
|
|
30
|
+
AGENT_TURN_MAX_TEXT: () => AGENT_TURN_MAX_TEXT,
|
|
31
|
+
AGENT_TURN_ROLES: () => AGENT_TURN_ROLES,
|
|
24
32
|
ANNOTATION_COLORS: () => ANNOTATION_COLORS,
|
|
33
|
+
APP_LIFECYCLE_EVENTS: () => APP_LIFECYCLE_EVENTS,
|
|
25
34
|
ARTICLE_VISIBILITIES: () => ARTICLE_VISIBILITIES,
|
|
26
35
|
AUTOCAPTURE_EVENTS: () => AUTOCAPTURE_EVENTS,
|
|
36
|
+
AgentEventsRequestSchema: () => AgentEventsRequestSchema,
|
|
37
|
+
AgentMetadataSchema: () => AgentMetadataSchema,
|
|
38
|
+
AgentToolCallSchema: () => AgentToolCallSchema,
|
|
39
|
+
AgentTurnInputSchema: () => AgentTurnInputSchema,
|
|
27
40
|
AppearanceSchema: () => AppearanceSchema,
|
|
28
41
|
AuthoringPickSchema: () => AuthoringPickSchema,
|
|
29
42
|
AutocaptureSettingsSchema: () => AutocaptureSettingsSchema,
|
|
@@ -31,9 +44,11 @@ __export(index_exports, {
|
|
|
31
44
|
ButtonSchema: () => ButtonSchema,
|
|
32
45
|
CAPTURE_PARAM: () => CAPTURE_PARAM,
|
|
33
46
|
CAPTURE_SCREENSHOT_MAX_BYTES: () => CAPTURE_SCREENSHOT_MAX_BYTES,
|
|
47
|
+
COMMON_LOCALES: () => COMMON_LOCALES,
|
|
34
48
|
COMPLAINT_EVENTS: () => COMPLAINT_EVENTS,
|
|
35
49
|
COMPLAINT_FIELD_TYPES: () => COMPLAINT_FIELD_TYPES,
|
|
36
50
|
COMPLAINT_STATUSES: () => COMPLAINT_STATUSES,
|
|
51
|
+
CONTROL_VARIANT_ID: () => CONTROL_VARIANT_ID,
|
|
37
52
|
CaptureStepSchema: () => CaptureStepSchema,
|
|
38
53
|
CapturedElementSchema: () => CapturedElementSchema,
|
|
39
54
|
ChecklistConfigSchema: () => ChecklistConfigSchema,
|
|
@@ -42,28 +57,54 @@ __export(index_exports, {
|
|
|
42
57
|
ConversationLookupSchema: () => ConversationLookupSchema,
|
|
43
58
|
ConversationRatingSchema: () => ConversationRatingSchema,
|
|
44
59
|
DEFAULT_CAPTURE_SETTINGS: () => DEFAULT_CAPTURE_SETTINGS,
|
|
60
|
+
DEFAULT_FEATURE_ATTRIBUTE: () => DEFAULT_FEATURE_ATTRIBUTE,
|
|
61
|
+
DEFAULT_LOCALE: () => DEFAULT_LOCALE,
|
|
45
62
|
DEFAULT_PLATFORMS: () => DEFAULT_PLATFORMS,
|
|
46
63
|
EMBED_IFRAME_ATTRS: () => EMBED_IFRAME_ATTRS,
|
|
47
64
|
EVENT_NAMES: () => EVENT_NAMES,
|
|
48
65
|
ErrorTrackingSettingsSchema: () => ErrorTrackingSettingsSchema,
|
|
49
66
|
EventBatchSchema: () => EventBatchSchema,
|
|
67
|
+
FEATURE_ATTRIBUTE_PATTERN: () => FEATURE_ATTRIBUTE_PATTERN,
|
|
68
|
+
FEATURE_RULE_LIMITS: () => FEATURE_RULE_LIMITS,
|
|
69
|
+
FEEDBACK_EVENTS: () => FEEDBACK_EVENTS,
|
|
70
|
+
FEEDBACK_PRIORITIES: () => FEEDBACK_PRIORITIES,
|
|
71
|
+
FEEDBACK_PRIORITY_LABEL: () => FEEDBACK_PRIORITY_LABEL,
|
|
72
|
+
FEEDBACK_PRIORITY_WEIGHT: () => FEEDBACK_PRIORITY_WEIGHT,
|
|
73
|
+
FEEDBACK_STATUSES: () => FEEDBACK_STATUSES,
|
|
74
|
+
FEEDBACK_STATUS_LABEL: () => FEEDBACK_STATUS_LABEL,
|
|
50
75
|
FILE_LINK_CLASS: () => FILE_LINK_CLASS,
|
|
76
|
+
FeedbackCommentSchema: () => FeedbackCommentSchema,
|
|
77
|
+
FeedbackFollowSchema: () => FeedbackFollowSchema,
|
|
78
|
+
FeedbackListRequestSchema: () => FeedbackListRequestSchema,
|
|
79
|
+
FeedbackSimilarSchema: () => FeedbackSimilarSchema,
|
|
80
|
+
FeedbackUpdatesReadSchema: () => FeedbackUpdatesReadSchema,
|
|
81
|
+
FeedbackVisitorSchema: () => FeedbackVisitorSchema,
|
|
82
|
+
FeedbackVoteSchema: () => FeedbackVoteSchema,
|
|
51
83
|
FileComplaintSchema: () => FileComplaintSchema,
|
|
52
84
|
FrequencySchema: () => FrequencySchema,
|
|
53
85
|
GUIDELY_ID_ATTRIBUTE: () => GUIDELY_ID_ATTRIBUTE,
|
|
86
|
+
GUIDE_EXPERIMENT_GOALS: () => GUIDE_EXPERIMENT_GOALS,
|
|
87
|
+
GUIDE_EXPERIMENT_GOAL_LABELS: () => GUIDE_EXPERIMENT_GOAL_LABELS,
|
|
88
|
+
GUIDE_EXPERIMENT_STATUSES: () => GUIDE_EXPERIMENT_STATUSES,
|
|
54
89
|
GUIDE_KINDS: () => GUIDE_KINDS,
|
|
55
90
|
GUIDE_LIFECYCLE_EVENTS: () => GUIDE_LIFECYCLE_EVENTS,
|
|
56
91
|
GUIDE_STATUSES: () => GUIDE_STATUSES,
|
|
57
92
|
GUIDE_TEMPLATES: () => GUIDE_TEMPLATES,
|
|
58
93
|
GUIDE_VISIBILITIES: () => GUIDE_VISIBILITIES,
|
|
59
94
|
GuideConfigSchema: () => GuideConfigSchema,
|
|
95
|
+
GuideLocalizationSchema: () => GuideLocalizationSchema,
|
|
96
|
+
GuideScheduleSchema: () => GuideScheduleSchema,
|
|
60
97
|
GuideStateUpdateSchema: () => GuideStateUpdateSchema,
|
|
98
|
+
GuideThrottlingSchema: () => GuideThrottlingSchema,
|
|
61
99
|
HEATMAP_VIEWPORTS: () => HEATMAP_VIEWPORTS,
|
|
62
100
|
HOWTO_ACTIONS: () => HOWTO_ACTIONS,
|
|
63
101
|
HOWTO_STEP_KINDS: () => HOWTO_STEP_KINDS,
|
|
64
102
|
HowToAnnotationSchema: () => HowToAnnotationSchema,
|
|
65
103
|
IdentifyRequestSchema: () => IdentifyRequestSchema,
|
|
104
|
+
LOCALE_PATTERN: () => LOCALE_PATTERN,
|
|
66
105
|
LOGGED_IN_AUDIENCE: () => LOGGED_IN_AUDIENCE,
|
|
106
|
+
LocaleSchema: () => LocaleSchema,
|
|
107
|
+
LocalizationSettingsSchema: () => LocalizationSettingsSchema,
|
|
67
108
|
MAX_ANNOTATIONS: () => MAX_ANNOTATIONS,
|
|
68
109
|
MAX_COLLECTION_DEPTH: () => MAX_COLLECTION_DEPTH,
|
|
69
110
|
MAX_COMPLAINT_ANSWER_LENGTH: () => MAX_COMPLAINT_ANSWER_LENGTH,
|
|
@@ -71,6 +112,11 @@ __export(index_exports, {
|
|
|
71
112
|
MAX_COMPLAINT_CHOICES: () => MAX_COMPLAINT_CHOICES,
|
|
72
113
|
MAX_COMPLAINT_FIELDS: () => MAX_COMPLAINT_FIELDS,
|
|
73
114
|
MAX_COMPLAINT_LENGTH: () => MAX_COMPLAINT_LENGTH,
|
|
115
|
+
MAX_CUSTOM_CSS: () => MAX_CUSTOM_CSS,
|
|
116
|
+
MAX_FEEDBACK_COMMENT: () => MAX_FEEDBACK_COMMENT,
|
|
117
|
+
MAX_FEEDBACK_DESCRIPTION: () => MAX_FEEDBACK_DESCRIPTION,
|
|
118
|
+
MAX_FEEDBACK_NOTE: () => MAX_FEEDBACK_NOTE,
|
|
119
|
+
MAX_FEEDBACK_TITLE: () => MAX_FEEDBACK_TITLE,
|
|
74
120
|
MAX_MESSAGE_LENGTH: () => MAX_MESSAGE_LENGTH,
|
|
75
121
|
MAX_PROPERTY_BYTES: () => MAX_PROPERTY_BYTES,
|
|
76
122
|
MAX_STACK_FRAMES: () => MAX_STACK_FRAMES,
|
|
@@ -84,8 +130,10 @@ __export(index_exports, {
|
|
|
84
130
|
MESSAGE_AUTHORS: () => MESSAGE_AUTHORS,
|
|
85
131
|
MessengerPageRequestSchema: () => MessengerPageRequestSchema,
|
|
86
132
|
NETWORK_PLUGIN: () => NETWORK_PLUGIN,
|
|
133
|
+
NOISY_DATA_ATTR: () => NOISY_DATA_ATTR,
|
|
87
134
|
NormalizedPointSchema: () => NormalizedPointSchema,
|
|
88
135
|
NormalizedRectSchema: () => NormalizedRectSchema,
|
|
136
|
+
PAGE_RULE_LIMITS: () => PAGE_RULE_LIMITS,
|
|
89
137
|
PATH_ID_PATTERN: () => PATH_ID_PATTERN,
|
|
90
138
|
PDF_BLOCK_CLASS: () => PDF_BLOCK_CLASS,
|
|
91
139
|
PDF_MAX_PAGES: () => PDF_MAX_PAGES,
|
|
@@ -95,6 +143,8 @@ __export(index_exports, {
|
|
|
95
143
|
PostMessageSchema: () => PostMessageSchema,
|
|
96
144
|
ProjectThemeSchema: () => ProjectThemeSchema,
|
|
97
145
|
PublishedGuideSchema: () => PublishedGuideSchema,
|
|
146
|
+
RC_MODULE_IDS: () => RC_MODULE_IDS,
|
|
147
|
+
RC_MODULE_LABELS: () => RC_MODULE_LABELS,
|
|
98
148
|
REPLAY_MAX_COMPRESSED_BYTES: () => REPLAY_MAX_COMPRESSED_BYTES,
|
|
99
149
|
REPLAY_MAX_RAW_BYTES: () => REPLAY_MAX_RAW_BYTES,
|
|
100
150
|
REPLY_TIMES: () => REPLY_TIMES,
|
|
@@ -104,6 +154,9 @@ __export(index_exports, {
|
|
|
104
154
|
ReplaySettingsSchema: () => ReplaySettingsSchema,
|
|
105
155
|
RuleGroupSchema: () => RuleGroupSchema,
|
|
106
156
|
RuleSchema: () => RuleSchema,
|
|
157
|
+
SCOUT_AGENT_ID: () => SCOUT_AGENT_ID,
|
|
158
|
+
SCRIPT_STUB: () => SCRIPT_STUB,
|
|
159
|
+
SCRIPT_STUB_METHODS: () => SCRIPT_STUB_METHODS,
|
|
107
160
|
SDK_API_VERSION: () => SDK_API_VERSION,
|
|
108
161
|
SELECTOR_KINDS: () => SELECTOR_KINDS,
|
|
109
162
|
SENSITIVE_HEADER_PATTERN: () => SENSITIVE_HEADER_PATTERN,
|
|
@@ -113,30 +166,46 @@ __export(index_exports, {
|
|
|
113
166
|
SHARED_VERSION: () => SHARED_VERSION,
|
|
114
167
|
SHOW_ME_CLASS: () => SHOW_ME_CLASS,
|
|
115
168
|
SHOW_ME_HREF_PREFIX: () => SHOW_ME_HREF_PREFIX,
|
|
169
|
+
SNAPSHOT_ATTRS: () => SNAPSHOT_ATTRS,
|
|
170
|
+
SNAPSHOT_LIMITS: () => SNAPSHOT_LIMITS,
|
|
116
171
|
SOURCEMAP_MAX_FILES_PER_UPLOAD: () => SOURCEMAP_MAX_FILES_PER_UPLOAD,
|
|
117
172
|
SOURCEMAP_MAX_FILE_BYTES: () => SOURCEMAP_MAX_FILE_BYTES,
|
|
118
173
|
STATUS_LEVELS: () => STATUS_LEVELS,
|
|
119
174
|
STEP_TYPES: () => STEP_TYPES,
|
|
120
175
|
SURVEY_QUESTION_TYPES: () => SURVEY_QUESTION_TYPES,
|
|
176
|
+
SdkAgentEventsSchema: () => SdkAgentEventsSchema,
|
|
121
177
|
SdkEventSchema: () => SdkEventSchema,
|
|
122
178
|
SelectorStrategySchema: () => SelectorStrategySchema,
|
|
179
|
+
SelectorSyntaxError: () => SelectorSyntaxError,
|
|
123
180
|
StartConversationSchema: () => StartConversationSchema,
|
|
124
181
|
StepBranchSchema: () => StepBranchSchema,
|
|
125
182
|
StepSchema: () => StepSchema,
|
|
183
|
+
SubmitFeedbackSchema: () => SubmitFeedbackSchema,
|
|
126
184
|
SurveyConfigSchema: () => SurveyConfigSchema,
|
|
127
185
|
SurveyQuestionSchema: () => SurveyQuestionSchema,
|
|
128
186
|
SurveyResponseRequestSchema: () => SurveyResponseRequestSchema,
|
|
187
|
+
TAG_PROPERTY_LIMITS: () => TAG_PROPERTY_LIMITS,
|
|
129
188
|
TRIGGER_TYPES: () => TRIGGER_TYPES,
|
|
130
189
|
TargetSchema: () => TargetSchema,
|
|
131
190
|
TriggerSchema: () => TriggerSchema,
|
|
132
191
|
VIDEO_ATTRS: () => VIDEO_ATTRS,
|
|
192
|
+
WCAG_AA_LARGE: () => WCAG_AA_LARGE,
|
|
193
|
+
WCAG_AA_TEXT: () => WCAG_AA_TEXT,
|
|
133
194
|
WS_MAX_MESSAGES_PER_SOCKET: () => WS_MAX_MESSAGES_PER_SOCKET,
|
|
134
195
|
WS_MAX_MESSAGE_BYTES: () => WS_MAX_MESSAGE_BYTES,
|
|
196
|
+
applyGuideTranslations: () => applyGuideTranslations,
|
|
197
|
+
articleTextEntries: () => articleTextEntries,
|
|
198
|
+
assignGuideVariant: () => assignGuideVariant,
|
|
199
|
+
baseLanguage: () => baseLanguage,
|
|
135
200
|
clamp: () => clamp,
|
|
136
201
|
cleanLabel: () => cleanLabel,
|
|
137
202
|
compare: () => compare,
|
|
138
203
|
compareVersions: () => compareVersions,
|
|
139
204
|
complaintReference: () => complaintReference,
|
|
205
|
+
compoundMatches: () => compoundMatches,
|
|
206
|
+
contrastIssues: () => contrastIssues,
|
|
207
|
+
contrastRatio: () => contrastRatio,
|
|
208
|
+
cssSelectorError: () => cssSelectorError,
|
|
140
209
|
defaultGuideConfig: () => defaultGuideConfig,
|
|
141
210
|
defaultStep: () => defaultStep,
|
|
142
211
|
describeCaptureStep: () => describeCaptureStep,
|
|
@@ -144,12 +213,21 @@ __export(index_exports, {
|
|
|
144
213
|
emptyRuleGroup: () => emptyRuleGroup,
|
|
145
214
|
evaluateRule: () => evaluateRule,
|
|
146
215
|
evaluateRules: () => evaluateRules,
|
|
216
|
+
evenWeights: () => evenWeights,
|
|
217
|
+
experimentBucketRules: () => experimentBucketRules,
|
|
218
|
+
experimentSalt: () => experimentSalt,
|
|
219
|
+
featureCssSelectors: () => featureCssSelectors,
|
|
220
|
+
featureRuleError: () => featureRuleError,
|
|
221
|
+
featureRuleMatchesClick: () => featureRuleMatchesClick,
|
|
222
|
+
feedbackReference: () => feedbackReference,
|
|
147
223
|
fingerprintError: () => fingerprintError,
|
|
148
224
|
firstNameFromTraits: () => firstNameFromTraits,
|
|
149
225
|
fnv1a: () => fnv1a,
|
|
150
226
|
foldPathIds: () => foldPathIds,
|
|
151
227
|
getPath: () => getPath,
|
|
228
|
+
guideLocales: () => guideLocales,
|
|
152
229
|
guidePlatforms: () => guidePlatforms,
|
|
230
|
+
guideTextEntries: () => guideTextEntries,
|
|
153
231
|
guidelyIdFromSelector: () => guidelyIdFromSelector,
|
|
154
232
|
hasVideoMedia: () => hasVideoMedia,
|
|
155
233
|
isAllowedEmbedSrc: () => isAllowedEmbedSrc,
|
|
@@ -162,6 +240,12 @@ __export(index_exports, {
|
|
|
162
240
|
isRuleGroup: () => isRuleGroup,
|
|
163
241
|
isSafeMediaUrl: () => isSafeMediaUrl,
|
|
164
242
|
isVideoContentType: () => isVideoContentType,
|
|
243
|
+
localeName: () => localeName,
|
|
244
|
+
localizeAnnouncement: () => localizeAnnouncement,
|
|
245
|
+
localizeArticle: () => localizeArticle,
|
|
246
|
+
localizeGuide: () => localizeGuide,
|
|
247
|
+
localizeResourceCenter: () => localizeResourceCenter,
|
|
248
|
+
matchCssSelector: () => matchCssSelector,
|
|
165
249
|
matchUrlPattern: () => matchUrlPattern,
|
|
166
250
|
matchesAudiences: () => matchesAudiences,
|
|
167
251
|
matchesHelpQuery: () => matchesHelpQuery,
|
|
@@ -169,30 +253,63 @@ __export(index_exports, {
|
|
|
169
253
|
mediaMaxBytes: () => mediaMaxBytes,
|
|
170
254
|
normalizeErrorMessage: () => normalizeErrorMessage,
|
|
171
255
|
normalizeFrameFile: () => normalizeFrameFile,
|
|
256
|
+
normalizeLocale: () => normalizeLocale,
|
|
257
|
+
normalizeSnapshot: () => normalizeSnapshot,
|
|
258
|
+
orderedModules: () => orderedModules,
|
|
172
259
|
pageLabel: () => pageLabel,
|
|
173
260
|
pageName: () => pageName,
|
|
261
|
+
pagePattern: () => pagePattern,
|
|
262
|
+
pageRuleError: () => pageRuleError,
|
|
263
|
+
pageRuleMatches: () => pageRuleMatches,
|
|
264
|
+
pageRulesMatch: () => pageRulesMatch,
|
|
174
265
|
pageTerms: () => pageTerms,
|
|
266
|
+
parseCssSelector: () => parseCssSelector,
|
|
267
|
+
parseCsvRows: () => parseCsvRows,
|
|
268
|
+
parseHexColor: () => parseHexColor,
|
|
175
269
|
parseStack: () => parseStack,
|
|
270
|
+
parseTranslationCsv: () => parseTranslationCsv,
|
|
271
|
+
parseXliff: () => parseXliff,
|
|
272
|
+
propertyAttributeAllowed: () => propertyAttributeAllowed,
|
|
273
|
+
queryConditionRegex: () => queryConditionRegex,
|
|
176
274
|
randomId: () => randomId,
|
|
275
|
+
readableTextOn: () => readableTextOn,
|
|
276
|
+
relativeLuminance: () => relativeLuminance,
|
|
177
277
|
resolveCaptureSettings: () => resolveCaptureSettings,
|
|
278
|
+
resolveLocale: () => resolveLocale,
|
|
279
|
+
resourceCenterLocales: () => resourceCenterLocales,
|
|
178
280
|
resourceCenterSections: () => resourceCenterSections,
|
|
281
|
+
resourceCenterTextEntries: () => resourceCenterTextEntries,
|
|
179
282
|
rolloutBucket: () => rolloutBucket,
|
|
180
283
|
safeRegExp: () => safeRegExp,
|
|
284
|
+
sanitizeCustomCss: () => sanitizeCustomCss,
|
|
181
285
|
sanitizeProperties: () => sanitizeProperties,
|
|
286
|
+
scopeCustomCss: () => scopeCustomCss,
|
|
182
287
|
screenPath: () => screenPath,
|
|
288
|
+
scriptSnippet: () => scriptSnippet,
|
|
183
289
|
servedArticleAudiences: () => servedArticleAudiences,
|
|
184
290
|
showMeHref: () => showMeHref,
|
|
185
291
|
showMeKeyFromHref: () => showMeKeyFromHref,
|
|
186
292
|
showMeKeys: () => showMeKeys,
|
|
187
293
|
slugify: () => slugify,
|
|
294
|
+
snapshotFromSelector: () => snapshotFromSelector,
|
|
295
|
+
stableStringify: () => stableStringify,
|
|
188
296
|
stripOrigin: () => stripOrigin,
|
|
189
297
|
supportsPlatform: () => supportsPlatform,
|
|
190
298
|
templateConfig: () => templateConfig,
|
|
191
299
|
toEmbedUrl: () => toEmbedUrl,
|
|
300
|
+
toTranslationCsv: () => toTranslationCsv,
|
|
301
|
+
toXliff: () => toXliff,
|
|
302
|
+
translationCoverage: () => translationCoverage,
|
|
303
|
+
unreadAnnouncements: () => unreadAnnouncements,
|
|
192
304
|
validateGuideConfig: () => validateGuideConfig,
|
|
305
|
+
variantProblems: () => variantProblems,
|
|
306
|
+
variantRanges: () => variantRanges,
|
|
307
|
+
visibleAnnouncements: () => visibleAnnouncements,
|
|
193
308
|
visibleArticleIds: () => visibleArticleIds,
|
|
194
309
|
visibleButtons: () => visibleButtons,
|
|
195
310
|
visitorAudiences: () => visitorAudiences,
|
|
311
|
+
visitorLocales: () => visitorLocales,
|
|
312
|
+
withExperimentBucket: () => withExperimentBucket,
|
|
196
313
|
withVisibility: () => withVisibility
|
|
197
314
|
});
|
|
198
315
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -387,17 +504,21 @@ var RULE_FIELDS = [
|
|
|
387
504
|
"datetime.dayOfWeek",
|
|
388
505
|
"datetime.hour",
|
|
389
506
|
"rollout.percentage",
|
|
507
|
+
/** Guide A/B tests: the visitor's 0-99 bucket for the salt in `key` (see guide-experiments.ts). */
|
|
508
|
+
"experiment.bucket",
|
|
390
509
|
"environment",
|
|
391
510
|
"locale",
|
|
392
511
|
"app.platform",
|
|
393
512
|
"app.screen",
|
|
394
|
-
"app.version"
|
|
513
|
+
"app.version",
|
|
514
|
+
"page.views",
|
|
515
|
+
"feature.clicks"
|
|
395
516
|
];
|
|
396
517
|
function isRuleGroup(r) {
|
|
397
518
|
return r.rules !== void 0;
|
|
398
519
|
}
|
|
399
|
-
function emptyRuleGroup(
|
|
400
|
-
return { id, op: "and", rules: [] };
|
|
520
|
+
function emptyRuleGroup(id2 = "root") {
|
|
521
|
+
return { id: id2, op: "and", rules: [] };
|
|
401
522
|
}
|
|
402
523
|
function has(set, v) {
|
|
403
524
|
if (!set) return false;
|
|
@@ -451,6 +572,8 @@ function resolveField(rule, ctx) {
|
|
|
451
572
|
return ctx.now.getHours();
|
|
452
573
|
case "rollout.percentage":
|
|
453
574
|
return rolloutBucket(ctx.userId || ctx.anonymousId, ctx.rolloutSalt || "guidely");
|
|
575
|
+
case "experiment.bucket":
|
|
576
|
+
return rule.key ? rolloutBucket(ctx.userId || ctx.anonymousId, rule.key) : void 0;
|
|
454
577
|
case "environment":
|
|
455
578
|
return ctx.environment;
|
|
456
579
|
case "locale":
|
|
@@ -461,6 +584,9 @@ function resolveField(rule, ctx) {
|
|
|
461
584
|
return ctx.screen;
|
|
462
585
|
case "app.version":
|
|
463
586
|
return ctx.appVersion;
|
|
587
|
+
case "page.views":
|
|
588
|
+
case "feature.clicks":
|
|
589
|
+
return rule.key ? ctx.tagUsage?.[rule.key] ?? 0 : 0;
|
|
464
590
|
default:
|
|
465
591
|
return void 0;
|
|
466
592
|
}
|
|
@@ -560,7 +686,7 @@ function evaluateRules(group, ctx) {
|
|
|
560
686
|
const value = group.op === "and" ? results.every(Boolean) : results.some(Boolean);
|
|
561
687
|
return group.negate ? !value : value;
|
|
562
688
|
}
|
|
563
|
-
var SERVER_ASSISTED_FIELDS = ["audience.member", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed"];
|
|
689
|
+
var SERVER_ASSISTED_FIELDS = ["audience.member", "guide.completed", "guide.dismissed", "guide.seen", "checklist.completed", "page.views", "feature.clicks"];
|
|
564
690
|
var GUIDE_VISIBILITIES = ["everyone", "identified", "anonymous"];
|
|
565
691
|
function withVisibility(targeting, visibility) {
|
|
566
692
|
if (!visibility || visibility === "everyone") return targeting;
|
|
@@ -592,6 +718,57 @@ var RuleGroupSchema = import_zod.z.lazy(
|
|
|
592
718
|
|
|
593
719
|
// src/guide.ts
|
|
594
720
|
var import_zod2 = require("zod");
|
|
721
|
+
|
|
722
|
+
// src/contrast.ts
|
|
723
|
+
var WCAG_AA_TEXT = 4.5;
|
|
724
|
+
var WCAG_AA_LARGE = 3;
|
|
725
|
+
function channel(c) {
|
|
726
|
+
const s = c / 255;
|
|
727
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
728
|
+
}
|
|
729
|
+
function parseHexColor(hex) {
|
|
730
|
+
if (!hex) return null;
|
|
731
|
+
const m = hex.trim().match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);
|
|
732
|
+
if (!m) return null;
|
|
733
|
+
const h = m[1].length === 3 ? m[1].split("").map((c) => c + c).join("") : m[1];
|
|
734
|
+
return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
|
|
735
|
+
}
|
|
736
|
+
function relativeLuminance(hex) {
|
|
737
|
+
const rgb = parseHexColor(hex);
|
|
738
|
+
if (!rgb) return null;
|
|
739
|
+
return 0.2126 * channel(rgb[0]) + 0.7152 * channel(rgb[1]) + 0.0722 * channel(rgb[2]);
|
|
740
|
+
}
|
|
741
|
+
function contrastRatio(a, b) {
|
|
742
|
+
const la = relativeLuminance(a);
|
|
743
|
+
const lb = relativeLuminance(b);
|
|
744
|
+
if (la === null || lb === null) return null;
|
|
745
|
+
const [hi, lo] = la > lb ? [la, lb] : [lb, la];
|
|
746
|
+
return Math.round((hi + 0.05) / (lo + 0.05) * 100) / 100;
|
|
747
|
+
}
|
|
748
|
+
function readableTextOn(background) {
|
|
749
|
+
const white = contrastRatio(background, "#ffffff") ?? 0;
|
|
750
|
+
const dark = contrastRatio(background, "#111827") ?? 0;
|
|
751
|
+
return white >= dark ? "#ffffff" : "#111827";
|
|
752
|
+
}
|
|
753
|
+
function contrastIssues(colors) {
|
|
754
|
+
const issues = [];
|
|
755
|
+
const { primaryColor, backgroundColor, textColor } = colors;
|
|
756
|
+
if (textColor && backgroundColor) {
|
|
757
|
+
const r = contrastRatio(textColor, backgroundColor);
|
|
758
|
+
if (r !== null && r < WCAG_AA_TEXT) issues.push({ pair: "text", ratio: r, required: WCAG_AA_TEXT, message: `Text on the background has a contrast of ${r}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });
|
|
759
|
+
}
|
|
760
|
+
if (primaryColor) {
|
|
761
|
+
const label = contrastRatio(primaryColor, readableTextOn(primaryColor));
|
|
762
|
+
if (label !== null && label < WCAG_AA_TEXT) issues.push({ pair: "button", ratio: label, required: WCAG_AA_TEXT, message: `Button labels on the primary colour have a contrast of ${label}:1; WCAG AA needs ${WCAG_AA_TEXT}:1.` });
|
|
763
|
+
if (backgroundColor) {
|
|
764
|
+
const link = contrastRatio(primaryColor, backgroundColor);
|
|
765
|
+
if (link !== null && link < WCAG_AA_LARGE) issues.push({ pair: "link", ratio: link, required: WCAG_AA_LARGE, message: `The primary colour on the background (links, outlined buttons) has a contrast of ${link}:1; WCAG AA needs ${WCAG_AA_LARGE}:1.` });
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return issues;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// src/guide.ts
|
|
595
772
|
var GUIDE_KINDS = ["flow", "modal", "tooltip", "banner", "checklist", "survey", "announcement"];
|
|
596
773
|
var GUIDE_STATUSES = ["draft", "published", "paused", "archived"];
|
|
597
774
|
var STEP_TYPES = ["modal", "tooltip", "popover", "spotlight", "hotspot", "banner", "slideout", "checklist", "custom", "survey"];
|
|
@@ -640,6 +817,8 @@ var StepSchema = import_zod2.z.object({
|
|
|
640
817
|
/** Sanitized HTML body (links, images, lists, formatting). */
|
|
641
818
|
body: import_zod2.z.string().max(2e4).default(""),
|
|
642
819
|
imageUrl: import_zod2.z.string().url().max(2e3).optional().or(import_zod2.z.literal("")),
|
|
820
|
+
/** Alternative text for `imageUrl` (screen readers); empty = decorative. */
|
|
821
|
+
imageAlt: import_zod2.z.string().max(300).optional(),
|
|
643
822
|
buttons: import_zod2.z.array(ButtonSchema).max(6).default([]),
|
|
644
823
|
target: TargetSchema.optional(),
|
|
645
824
|
placement: import_zod2.z.enum(PLACEMENTS).default("auto"),
|
|
@@ -666,7 +845,12 @@ var StepSchema = import_zod2.z.object({
|
|
|
666
845
|
/** Hotspot pulse dot settings. */
|
|
667
846
|
hotspot: import_zod2.z.object({ size: import_zod2.z.number().int().min(8).max(40).default(14), pulse: import_zod2.z.boolean().default(true), openOn: import_zod2.z.enum(["click", "hover"]).default("click") }).optional(),
|
|
668
847
|
/** Custom step: arbitrary sanitized HTML with no chrome. */
|
|
669
|
-
customHtml: import_zod2.z.string().max(5e4).optional()
|
|
848
|
+
customHtml: import_zod2.z.string().max(5e4).optional(),
|
|
849
|
+
/**
|
|
850
|
+
* Code block (custom steps only): JavaScript run on the web when the step shows, only while the
|
|
851
|
+
* workspace allows code blocks (an admin setting, off by default). Mobile SDKs never receive it.
|
|
852
|
+
*/
|
|
853
|
+
code: import_zod2.z.string().max(2e4).optional()
|
|
670
854
|
});
|
|
671
855
|
var TRIGGER_TYPES = ["page_load", "url_match", "event", "element_click", "element_visible", "manual", "delay", "after_guide", "segment_enter"];
|
|
672
856
|
var TriggerSchema = import_zod2.z.object({
|
|
@@ -688,7 +872,9 @@ var FrequencySchema = import_zod2.z.object({
|
|
|
688
872
|
/** Guide ids that must not be active at the same time. */
|
|
689
873
|
mutuallyExclusiveWith: import_zod2.z.array(import_zod2.z.string()).max(50).default([]),
|
|
690
874
|
/** Re-show if dismissed (otherwise dismissal counts as completion for frequency). */
|
|
691
|
-
reshowAfterDismiss: import_zod2.z.boolean().default(false)
|
|
875
|
+
reshowAfterDismiss: import_zod2.z.boolean().default(false),
|
|
876
|
+
/** Bypass the project's guide throttling (always eligible as far as throttling goes). */
|
|
877
|
+
ignoreThrottling: import_zod2.z.boolean().optional()
|
|
692
878
|
});
|
|
693
879
|
var AppearanceSchema = import_zod2.z.object({
|
|
694
880
|
theme: import_zod2.z.enum(["light", "dark", "auto"]).default("auto"),
|
|
@@ -700,7 +886,9 @@ var AppearanceSchema = import_zod2.z.object({
|
|
|
700
886
|
overlayOpacity: import_zod2.z.number().min(0).max(1).optional(),
|
|
701
887
|
zIndex: import_zod2.z.number().int().min(1).max(2147483647).optional(),
|
|
702
888
|
preset: import_zod2.z.string().max(50).optional(),
|
|
703
|
-
animation: import_zod2.z.enum(["fade", "slide", "none"]).default("fade")
|
|
889
|
+
animation: import_zod2.z.enum(["fade", "slide", "none"]).default("fade"),
|
|
890
|
+
/** Custom CSS scoped to this guide's container (sanitized; see custom-css.ts). Web only. */
|
|
891
|
+
customCss: import_zod2.z.string().max(2e4).optional()
|
|
704
892
|
});
|
|
705
893
|
var ChecklistTaskSchema = import_zod2.z.object({
|
|
706
894
|
id: import_zod2.z.string().min(1),
|
|
@@ -747,6 +935,26 @@ var SurveyConfigSchema = import_zod2.z.object({
|
|
|
747
935
|
startAt: import_zod2.z.string().datetime().optional(),
|
|
748
936
|
endAt: import_zod2.z.string().datetime().optional()
|
|
749
937
|
});
|
|
938
|
+
var GuideScheduleSchema = import_zod2.z.object({
|
|
939
|
+
startAt: import_zod2.z.string().datetime().optional(),
|
|
940
|
+
endAt: import_zod2.z.string().datetime().optional(),
|
|
941
|
+
timezone: import_zod2.z.string().max(64).optional()
|
|
942
|
+
});
|
|
943
|
+
var LOCALE_PATTERN = /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8}){0,2}$/;
|
|
944
|
+
var LocaleSchema = import_zod2.z.string().regex(LOCALE_PATTERN, "Use a language code such as fr or pt-BR").max(20);
|
|
945
|
+
var GuideLocalizationSchema = import_zod2.z.object({
|
|
946
|
+
translations: import_zod2.z.record(LocaleSchema, import_zod2.z.record(import_zod2.z.string().max(200), import_zod2.z.string().max(5e4))).default({})
|
|
947
|
+
});
|
|
948
|
+
var LocalizationSettingsSchema = import_zod2.z.object({
|
|
949
|
+
defaultLocale: LocaleSchema.default("en"),
|
|
950
|
+
locales: import_zod2.z.array(LocaleSchema).max(50).default([])
|
|
951
|
+
});
|
|
952
|
+
var GuideThrottlingSchema = import_zod2.z.object({
|
|
953
|
+
enabled: import_zod2.z.boolean().default(false),
|
|
954
|
+
maxGuides: import_zod2.z.number().int().min(1).max(50).default(1),
|
|
955
|
+
windowHours: import_zod2.z.number().int().min(1).max(720).default(24),
|
|
956
|
+
minGapMinutes: import_zod2.z.number().int().min(0).max(10080).default(0)
|
|
957
|
+
});
|
|
750
958
|
var GuideConfigSchema = import_zod2.z.object({
|
|
751
959
|
steps: import_zod2.z.array(StepSchema).max(50).default([]),
|
|
752
960
|
/** Everyone, only identified (logged-in) users, or only anonymous visitors; applied on top of `targeting`. */
|
|
@@ -760,7 +968,11 @@ var GuideConfigSchema = import_zod2.z.object({
|
|
|
760
968
|
/** Restrict guide to url pattern(s) (applied before trigger). On mobile these match the screen path `/<Screen>`. */
|
|
761
969
|
urlPatterns: import_zod2.z.array(import_zod2.z.string().max(500)).max(20).default([]),
|
|
762
970
|
/** Platforms that receive this guide. Guides created before mobile support are web-only. */
|
|
763
|
-
platforms: import_zod2.z.array(import_zod2.z.enum(PLATFORMS)).max(PLATFORMS.length).default(["web"])
|
|
971
|
+
platforms: import_zod2.z.array(import_zod2.z.enum(PLATFORMS)).max(PLATFORMS.length).default(["web"]),
|
|
972
|
+
/** Start / end window for any guide kind (surveys also honour `survey.startAt` / `endAt`). */
|
|
973
|
+
schedule: GuideScheduleSchema.optional(),
|
|
974
|
+
/** Translations (see localization.ts). */
|
|
975
|
+
localization: GuideLocalizationSchema.optional()
|
|
764
976
|
});
|
|
765
977
|
function defaultGuideConfig(kind) {
|
|
766
978
|
return GuideConfigSchema.parse({
|
|
@@ -794,7 +1006,7 @@ function defaultStep(type, overrides = {}) {
|
|
|
794
1006
|
function visibleButtons(step, canGoBack) {
|
|
795
1007
|
return canGoBack ? step.buttons : step.buttons.filter((b) => b.action !== "back");
|
|
796
1008
|
}
|
|
797
|
-
function validateGuideConfig(kind, config) {
|
|
1009
|
+
function validateGuideConfig(kind, config, theme) {
|
|
798
1010
|
const issues = [];
|
|
799
1011
|
if (kind === "checklist") {
|
|
800
1012
|
if (!config.checklist || config.checklist.tasks.length === 0) issues.push({ level: "error", message: "Checklist needs at least one task." });
|
|
@@ -831,6 +1043,15 @@ function validateGuideConfig(kind, config) {
|
|
|
831
1043
|
if (config.trigger.type === "element_click" && !config.trigger.value) issues.push({ level: "error", message: "Element click trigger needs a selector." });
|
|
832
1044
|
if (config.trigger.type === "url_match" && !config.trigger.value) issues.push({ level: "error", message: "URL trigger needs a pattern." });
|
|
833
1045
|
if (config.frequency.mode === "interval" && !config.frequency.intervalHours) issues.push({ level: "error", message: "Interval frequency needs an interval in hours." });
|
|
1046
|
+
const sched = config.schedule;
|
|
1047
|
+
if (sched?.startAt && sched.endAt && Date.parse(sched.endAt) <= Date.parse(sched.startAt)) issues.push({ level: "error", message: "The schedule ends before it starts." });
|
|
1048
|
+
if (sched?.endAt && Date.parse(sched.endAt) < Date.now()) issues.push({ level: "warning", message: "The schedule has already ended, so nobody will see this guide." });
|
|
1049
|
+
config.steps.forEach((step, i) => {
|
|
1050
|
+
if (step.code && step.type !== "custom") issues.push({ level: "error", stepId: step.id, message: `Step ${i + 1}: code blocks can only run in custom steps.` });
|
|
1051
|
+
if (step.code && mobile) issues.push({ level: "warning", stepId: step.id, message: `Step ${i + 1} runs a code block; mobile apps skip it.` });
|
|
1052
|
+
});
|
|
1053
|
+
const colors = { primaryColor: config.appearance.primaryColor ?? theme?.primaryColor, backgroundColor: config.appearance.backgroundColor ?? theme?.backgroundColor, textColor: config.appearance.textColor ?? theme?.textColor };
|
|
1054
|
+
for (const c of contrastIssues(colors)) issues.push({ level: "warning", message: `Low contrast: ${c.message}` });
|
|
834
1055
|
return issues;
|
|
835
1056
|
}
|
|
836
1057
|
var ProjectThemeSchema = import_zod2.z.object({
|
|
@@ -840,7 +1061,9 @@ var ProjectThemeSchema = import_zod2.z.object({
|
|
|
840
1061
|
borderRadius: import_zod2.z.number().int().min(0).max(32).default(12),
|
|
841
1062
|
fontFamily: import_zod2.z.string().max(200).default("Inter, system-ui, -apple-system, sans-serif"),
|
|
842
1063
|
logoUrl: import_zod2.z.string().max(2e3).optional(),
|
|
843
|
-
brandName: import_zod2.z.string().max(100).optional()
|
|
1064
|
+
brandName: import_zod2.z.string().max(100).optional(),
|
|
1065
|
+
/** Custom CSS applied to every guide's container (sanitized and scoped like guide CSS). Web only. */
|
|
1066
|
+
customCss: import_zod2.z.string().max(2e4).optional()
|
|
844
1067
|
});
|
|
845
1068
|
|
|
846
1069
|
// src/events.ts
|
|
@@ -856,8 +1079,8 @@ function sanitizeProperties(props) {
|
|
|
856
1079
|
for (const [k, v] of Object.entries(props)) {
|
|
857
1080
|
if (SENSITIVE_PROPERTY_PATTERN.test(k)) continue;
|
|
858
1081
|
if (typeof v === "function" || typeof v === "symbol") continue;
|
|
859
|
-
const
|
|
860
|
-
size += k.length + (
|
|
1082
|
+
const str2 = typeof v === "string" ? v : JSON.stringify(v ?? null);
|
|
1083
|
+
size += k.length + (str2?.length ?? 0);
|
|
861
1084
|
if (size > MAX_PROPERTY_BYTES) break;
|
|
862
1085
|
out[k.slice(0, 100)] = typeof v === "string" ? v.slice(0, 1e3) : v;
|
|
863
1086
|
}
|
|
@@ -937,9 +1160,15 @@ var EVENT_NAMES = [
|
|
|
937
1160
|
"exception",
|
|
938
1161
|
"heatmap",
|
|
939
1162
|
// Feature flags: a user was bucketed into an experiment variation (properties: experimentKey, variationId, flagKey).
|
|
940
|
-
"experiment_viewed"
|
|
1163
|
+
"experiment_viewed",
|
|
1164
|
+
// Mobile app lifecycle (mobile/SPEC.md "Product analytics"): installs, updates, opens and backgrounding.
|
|
1165
|
+
"app_install",
|
|
1166
|
+
"app_update",
|
|
1167
|
+
"app_open",
|
|
1168
|
+
"app_background"
|
|
941
1169
|
];
|
|
942
|
-
var AUTOCAPTURE_EVENTS = ["page_view", "page_leave", "click", "rage_click", "exception", "heatmap"];
|
|
1170
|
+
var AUTOCAPTURE_EVENTS = ["page_view", "page_leave", "click", "rage_click", "exception", "heatmap", "app_install", "app_update", "app_open", "app_background"];
|
|
1171
|
+
var APP_LIFECYCLE_EVENTS = ["app_install", "app_update", "app_open", "app_background"];
|
|
943
1172
|
var GUIDE_LIFECYCLE_EVENTS = ["guide_viewed", "guide_started", "step_viewed", "step_completed", "guide_completed", "guide_skipped", "guide_dismissed", "guide_abandoned"];
|
|
944
1173
|
var SdkEventSchema = import_zod3.z.object({
|
|
945
1174
|
eventId: import_zod3.z.string().min(8).max(64),
|
|
@@ -1007,7 +1236,9 @@ var AuthoringPickSchema = import_zod4.z.object({
|
|
|
1007
1236
|
selectors: import_zod4.z.array(import_zod4.z.object({ kind: import_zod4.z.string(), value: import_zod4.z.string().max(1e3), label: import_zod4.z.string().max(200).optional() })).max(10),
|
|
1008
1237
|
textSnapshot: import_zod4.z.string().max(200).optional(),
|
|
1009
1238
|
url: import_zod4.z.string().max(2e3).optional(),
|
|
1010
|
-
rect: import_zod4.z.object({ x: import_zod4.z.number(), y: import_zod4.z.number(), width: import_zod4.z.number(), height: import_zod4.z.number() }).optional()
|
|
1239
|
+
rect: import_zod4.z.object({ x: import_zod4.z.number(), y: import_zod4.z.number(), width: import_zod4.z.number(), height: import_zod4.z.number() }).optional(),
|
|
1240
|
+
/** Compact snapshot of the picked element (tag mode: feature rules are proposed from it). */
|
|
1241
|
+
elementSnapshot: import_zod4.z.record(import_zod4.z.unknown()).optional()
|
|
1011
1242
|
});
|
|
1012
1243
|
var PublishedGuideSchema = import_zod4.z.object({
|
|
1013
1244
|
id: import_zod4.z.string(),
|
|
@@ -1085,22 +1316,153 @@ var FileComplaintSchema = import_zod6.z.object({
|
|
|
1085
1316
|
}).optional().nullable()
|
|
1086
1317
|
});
|
|
1087
1318
|
|
|
1088
|
-
// src/
|
|
1319
|
+
// src/agents.ts
|
|
1089
1320
|
var import_zod7 = require("zod");
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
var
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1321
|
+
|
|
1322
|
+
// src/agents-limits.ts
|
|
1323
|
+
var AGENT_TURN_ROLES = ["user", "assistant", "tool", "system"];
|
|
1324
|
+
var AGENT_OUTCOMES = ["success", "failure", "escalated", "abandoned"];
|
|
1325
|
+
var AGENT_TOOL_STATUSES = ["ok", "error"];
|
|
1326
|
+
var AGENT_TURN_MAX_TEXT = 2e4;
|
|
1327
|
+
var AGENT_TURNS_PER_BATCH = 100;
|
|
1328
|
+
var AGENT_TOOL_CALLS_PER_TURN = 50;
|
|
1329
|
+
var AGENT_METADATA_MAX_KEYS = 30;
|
|
1330
|
+
var AGENT_METADATA_MAX_BYTES = 4096;
|
|
1331
|
+
var SCOUT_AGENT_ID = "scout";
|
|
1332
|
+
|
|
1333
|
+
// src/agents.ts
|
|
1334
|
+
var ENVIRONMENTS = ["development", "staging", "production"];
|
|
1335
|
+
var AgentToolCallSchema = import_zod7.z.object({
|
|
1336
|
+
name: import_zod7.z.string().trim().min(1).max(100),
|
|
1337
|
+
status: import_zod7.z.enum(AGENT_TOOL_STATUSES).optional(),
|
|
1338
|
+
latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional()
|
|
1339
|
+
}).strip();
|
|
1340
|
+
var AgentMetadataSchema = import_zod7.z.record(import_zod7.z.string().max(100), import_zod7.z.unknown()).transform((m) => {
|
|
1341
|
+
const out = {};
|
|
1342
|
+
let size = 0;
|
|
1343
|
+
for (const [k, v] of Object.entries(m)) {
|
|
1344
|
+
const key = k.trim();
|
|
1345
|
+
if (!key || key.startsWith("$") || SENSITIVE_PROPERTY_PATTERN.test(key)) continue;
|
|
1346
|
+
if (!(typeof v === "string" || typeof v === "boolean" || v === null || typeof v === "number" && Number.isFinite(v))) continue;
|
|
1347
|
+
const value = typeof v === "string" ? v.slice(0, 500) : v;
|
|
1348
|
+
size += key.length + String(value).length;
|
|
1349
|
+
if (size > AGENT_METADATA_MAX_BYTES || Object.keys(out).length >= AGENT_METADATA_MAX_KEYS) break;
|
|
1350
|
+
out[key] = value;
|
|
1351
|
+
}
|
|
1352
|
+
return out;
|
|
1353
|
+
});
|
|
1354
|
+
var id = (max) => import_zod7.z.string().trim().min(1).max(max);
|
|
1355
|
+
var optionalId = (max) => import_zod7.z.string().trim().max(max).optional().nullable().transform((v) => v || null);
|
|
1356
|
+
var AgentTurnInputSchema = import_zod7.z.object({
|
|
1357
|
+
type: import_zod7.z.literal("agent.conversation").optional(),
|
|
1358
|
+
conversationId: id(128),
|
|
1359
|
+
agentId: id(64).refine((v) => v.toLowerCase() !== SCOUT_AGENT_ID, { message: `"${SCOUT_AGENT_ID}" is reserved for Guidely's built-in Scout agent` }),
|
|
1360
|
+
agentName: import_zod7.z.string().trim().max(100).optional(),
|
|
1361
|
+
turnId: import_zod7.z.string().trim().min(1).max(128).optional(),
|
|
1362
|
+
role: import_zod7.z.enum(AGENT_TURN_ROLES),
|
|
1363
|
+
text: import_zod7.z.string().max(AGENT_TURN_MAX_TEXT).default(""),
|
|
1364
|
+
toolCalls: import_zod7.z.array(AgentToolCallSchema).max(AGENT_TOOL_CALLS_PER_TURN).default([]),
|
|
1365
|
+
latencyMs: import_zod7.z.number().int().min(0).max(36e5).optional(),
|
|
1366
|
+
outcome: import_zod7.z.enum(AGENT_OUTCOMES).optional(),
|
|
1367
|
+
taskSuccess: import_zod7.z.boolean().optional(),
|
|
1368
|
+
occurredAt: import_zod7.z.string().datetime({ offset: true }).optional(),
|
|
1369
|
+
userId: optionalId(256),
|
|
1370
|
+
anonymousId: optionalId(128),
|
|
1371
|
+
accountId: optionalId(256),
|
|
1372
|
+
sessionId: optionalId(128),
|
|
1373
|
+
metadata: AgentMetadataSchema.default({})
|
|
1374
|
+
});
|
|
1375
|
+
var turns = import_zod7.z.array(AgentTurnInputSchema).min(1).max(AGENT_TURNS_PER_BATCH);
|
|
1376
|
+
var sdkInfo = import_zod7.z.object({ name: import_zod7.z.string().max(60), version: import_zod7.z.string().max(30) }).optional();
|
|
1377
|
+
var SdkAgentEventsSchema = import_zod7.z.object({ turns, sdk: sdkInfo });
|
|
1378
|
+
var AgentEventsRequestSchema = import_zod7.z.preprocess(
|
|
1379
|
+
(v) => {
|
|
1380
|
+
if (Array.isArray(v)) return { turns: v };
|
|
1381
|
+
if (v && typeof v === "object" && !("turns" in v)) {
|
|
1382
|
+
const { environment, ...turn } = v;
|
|
1383
|
+
return { turns: [turn], environment };
|
|
1384
|
+
}
|
|
1385
|
+
return v;
|
|
1386
|
+
},
|
|
1387
|
+
import_zod7.z.object({ turns, environment: import_zod7.z.enum(ENVIRONMENTS).default("production"), sdk: sdkInfo })
|
|
1388
|
+
);
|
|
1389
|
+
|
|
1390
|
+
// src/feedback.ts
|
|
1391
|
+
var import_zod8 = require("zod");
|
|
1392
|
+
|
|
1393
|
+
// src/feedback-limits.ts
|
|
1394
|
+
var FEEDBACK_STATUSES = ["new", "under_review", "planned", "in_progress", "released", "declined"];
|
|
1395
|
+
var FEEDBACK_STATUS_LABEL = {
|
|
1396
|
+
new: "New",
|
|
1397
|
+
under_review: "Under review",
|
|
1398
|
+
planned: "Planned",
|
|
1399
|
+
in_progress: "In progress",
|
|
1400
|
+
released: "Released",
|
|
1401
|
+
declined: "Declined"
|
|
1402
|
+
};
|
|
1403
|
+
var FEEDBACK_PRIORITIES = ["nice_to_have", "important", "critical"];
|
|
1404
|
+
var FEEDBACK_PRIORITY_LABEL = { nice_to_have: "Nice to have", important: "Important", critical: "Critical" };
|
|
1405
|
+
var FEEDBACK_PRIORITY_WEIGHT = { nice_to_have: 1, important: 2, critical: 3 };
|
|
1406
|
+
var FEEDBACK_EVENTS = ["request.created", "request.status_changed", "request.voted"];
|
|
1407
|
+
var MAX_FEEDBACK_TITLE = 140;
|
|
1408
|
+
var MAX_FEEDBACK_DESCRIPTION = 4e3;
|
|
1409
|
+
var MAX_FEEDBACK_COMMENT = 2e3;
|
|
1410
|
+
var MAX_FEEDBACK_NOTE = 500;
|
|
1411
|
+
var feedbackReference = (number) => `#${number}`;
|
|
1412
|
+
|
|
1413
|
+
// src/feedback.ts
|
|
1414
|
+
var visitor = {
|
|
1415
|
+
anonymousId: import_zod8.z.string().min(1).max(128),
|
|
1416
|
+
userId: import_zod8.z.string().max(256).optional().nullable()
|
|
1417
|
+
};
|
|
1418
|
+
var FeedbackListRequestSchema = import_zod8.z.object({
|
|
1419
|
+
...visitor,
|
|
1420
|
+
q: import_zod8.z.string().trim().max(200).optional(),
|
|
1421
|
+
sort: import_zod8.z.enum(["top", "new", "trending"]).default("top"),
|
|
1422
|
+
status: import_zod8.z.enum(FEEDBACK_STATUSES).optional(),
|
|
1423
|
+
/** "open" = not released or declined. */
|
|
1424
|
+
filter: import_zod8.z.enum(["open", "all", "mine", "following"]).default("open"),
|
|
1425
|
+
productArea: import_zod8.z.string().trim().max(60).optional(),
|
|
1426
|
+
page: import_zod8.z.number().int().min(1).max(100).default(1)
|
|
1427
|
+
});
|
|
1428
|
+
var FeedbackVisitorSchema = import_zod8.z.object(visitor);
|
|
1429
|
+
var SubmitFeedbackSchema = import_zod8.z.object({
|
|
1430
|
+
...visitor,
|
|
1431
|
+
title: import_zod8.z.string().trim().min(3, "Give your idea a short title").max(MAX_FEEDBACK_TITLE),
|
|
1432
|
+
description: import_zod8.z.string().trim().max(MAX_FEEDBACK_DESCRIPTION).default(""),
|
|
1433
|
+
productArea: import_zod8.z.string().trim().max(60).optional().nullable(),
|
|
1434
|
+
priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
|
|
1435
|
+
/** Filed from this Scout conversation (Scout offered it). */
|
|
1436
|
+
conversationId: import_zod8.z.string().min(1).max(64).optional().nullable(),
|
|
1437
|
+
pageUrl: import_zod8.z.string().max(2e3).optional()
|
|
1438
|
+
});
|
|
1439
|
+
var FeedbackVoteSchema = import_zod8.z.object({
|
|
1440
|
+
...visitor,
|
|
1441
|
+
priority: import_zod8.z.enum(FEEDBACK_PRIORITIES).default("nice_to_have"),
|
|
1442
|
+
note: import_zod8.z.string().trim().max(MAX_FEEDBACK_NOTE).optional(),
|
|
1443
|
+
conversationId: import_zod8.z.string().min(1).max(64).optional().nullable()
|
|
1444
|
+
});
|
|
1445
|
+
var FeedbackFollowSchema = import_zod8.z.object({ ...visitor, follow: import_zod8.z.boolean() });
|
|
1446
|
+
var FeedbackCommentSchema = import_zod8.z.object({ ...visitor, body: import_zod8.z.string().trim().min(1).max(MAX_FEEDBACK_COMMENT) });
|
|
1447
|
+
var FeedbackSimilarSchema = import_zod8.z.object({ ...visitor, title: import_zod8.z.string().trim().min(3).max(MAX_FEEDBACK_TITLE) });
|
|
1448
|
+
var FeedbackUpdatesReadSchema = import_zod8.z.object({ ...visitor, ids: import_zod8.z.array(import_zod8.z.string().min(1).max(64)).max(100).optional() });
|
|
1449
|
+
|
|
1450
|
+
// src/capture.ts
|
|
1451
|
+
var import_zod9 = require("zod");
|
|
1452
|
+
var AutocaptureSettingsSchema = import_zod9.z.object({ pageviews: import_zod9.z.boolean(), pageLeave: import_zod9.z.boolean(), clicks: import_zod9.z.boolean(), rageClicks: import_zod9.z.boolean(), heatmaps: import_zod9.z.boolean(), mouseMovement: import_zod9.z.boolean(), appLifecycle: import_zod9.z.boolean() }).partial();
|
|
1453
|
+
var ErrorTrackingSettingsSchema = import_zod9.z.object({ enabled: import_zod9.z.boolean() }).partial();
|
|
1454
|
+
var ReplaySettingsSchema = import_zod9.z.object({
|
|
1455
|
+
enabled: import_zod9.z.boolean(),
|
|
1456
|
+
sampleRate: import_zod9.z.number().int().min(0).max(100),
|
|
1457
|
+
recordConsole: import_zod9.z.boolean(),
|
|
1458
|
+
recordNetwork: import_zod9.z.boolean(),
|
|
1459
|
+
recordNetworkPayloads: import_zod9.z.boolean(),
|
|
1460
|
+
maskAllText: import_zod9.z.boolean(),
|
|
1461
|
+
blockSelectors: import_zod9.z.array(import_zod9.z.string().min(1).max(200)).max(50),
|
|
1462
|
+
retentionDays: import_zod9.z.number().int().min(1).max(365)
|
|
1101
1463
|
}).partial();
|
|
1102
1464
|
var DEFAULT_CAPTURE_SETTINGS = {
|
|
1103
|
-
autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true },
|
|
1465
|
+
autocapture: { pageviews: true, pageLeave: true, clicks: true, rageClicks: true, heatmaps: true, mouseMovement: true, appLifecycle: true },
|
|
1104
1466
|
errorTracking: { enabled: true },
|
|
1105
1467
|
replay: { enabled: false, sampleRate: 100, recordConsole: true, recordNetwork: true, recordNetworkPayloads: false, maskAllText: false, blockSelectors: [], retentionDays: 30 }
|
|
1106
1468
|
};
|
|
@@ -1118,18 +1480,18 @@ function resolveCaptureSettings(settings) {
|
|
|
1118
1480
|
};
|
|
1119
1481
|
}
|
|
1120
1482
|
var HEATMAP_VIEWPORTS = { mobile: [0, 767], tablet: [768, 1279], desktop: [1280, 1e5] };
|
|
1121
|
-
var ReplayChunkSchema =
|
|
1122
|
-
sessionId:
|
|
1123
|
-
windowId:
|
|
1124
|
-
seq:
|
|
1125
|
-
anonymousId:
|
|
1126
|
-
userId:
|
|
1483
|
+
var ReplayChunkSchema = import_zod9.z.object({
|
|
1484
|
+
sessionId: import_zod9.z.string().min(1).max(128),
|
|
1485
|
+
windowId: import_zod9.z.string().min(1).max(64),
|
|
1486
|
+
seq: import_zod9.z.number().int().min(0).max(1e6),
|
|
1487
|
+
anonymousId: import_zod9.z.string().min(1).max(128),
|
|
1488
|
+
userId: import_zod9.z.string().max(256).optional().nullable(),
|
|
1127
1489
|
/** rrweb `eventWithTime` objects, in order. */
|
|
1128
|
-
events:
|
|
1129
|
-
url:
|
|
1130
|
-
device:
|
|
1131
|
-
viewport:
|
|
1132
|
-
sdk:
|
|
1490
|
+
events: import_zod9.z.array(import_zod9.z.object({ type: import_zod9.z.number().int(), timestamp: import_zod9.z.number() }).passthrough()).min(1).max(5e4),
|
|
1491
|
+
url: import_zod9.z.string().max(2e3).optional(),
|
|
1492
|
+
device: import_zod9.z.object({ type: import_zod9.z.string().max(20), browser: import_zod9.z.string().max(40).optional(), os: import_zod9.z.string().max(40).optional() }).optional(),
|
|
1493
|
+
viewport: import_zod9.z.object({ width: import_zod9.z.number().int().min(0).max(1e5), height: import_zod9.z.number().int().min(0).max(1e5) }).optional(),
|
|
1494
|
+
sdk: import_zod9.z.object({ name: import_zod9.z.string().max(60), version: import_zod9.z.string().max(30) }).optional()
|
|
1133
1495
|
});
|
|
1134
1496
|
var REPLAY_MAX_COMPRESSED_BYTES = 2 * 1024 * 1024;
|
|
1135
1497
|
var REPLAY_MAX_RAW_BYTES = 16 * 1024 * 1024;
|
|
@@ -1313,8 +1675,8 @@ var GUIDE_TEMPLATES = [
|
|
|
1313
1675
|
}
|
|
1314
1676
|
}
|
|
1315
1677
|
];
|
|
1316
|
-
function templateConfig(
|
|
1317
|
-
const t = GUIDE_TEMPLATES.find((x) => x.id ===
|
|
1678
|
+
function templateConfig(id2) {
|
|
1679
|
+
const t = GUIDE_TEMPLATES.find((x) => x.id === id2);
|
|
1318
1680
|
if (!t) return null;
|
|
1319
1681
|
return { template: t, config: GuideConfigSchema.parse(t.config) };
|
|
1320
1682
|
}
|
|
@@ -1374,19 +1736,19 @@ function parseStart(v) {
|
|
|
1374
1736
|
if (!m || !m[0]) return 0;
|
|
1375
1737
|
return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);
|
|
1376
1738
|
}
|
|
1377
|
-
function youtube(
|
|
1378
|
-
if (!YOUTUBE_ID.test(
|
|
1739
|
+
function youtube(id2, start) {
|
|
1740
|
+
if (!YOUTUBE_ID.test(id2)) return null;
|
|
1379
1741
|
return {
|
|
1380
1742
|
provider: "youtube",
|
|
1381
|
-
src: `https://www.youtube-nocookie.com/embed/${
|
|
1382
|
-
watchUrl: `https://www.youtube.com/watch?v=${
|
|
1743
|
+
src: `https://www.youtube-nocookie.com/embed/${id2}${start ? `?start=${start}` : ""}`,
|
|
1744
|
+
watchUrl: `https://www.youtube.com/watch?v=${id2}${start ? `&t=${start}s` : ""}`,
|
|
1383
1745
|
title: "YouTube video"
|
|
1384
1746
|
};
|
|
1385
1747
|
}
|
|
1386
|
-
function vimeo(
|
|
1387
|
-
if (!VIMEO_ID.test(
|
|
1748
|
+
function vimeo(id2, hash) {
|
|
1749
|
+
if (!VIMEO_ID.test(id2) || hash !== null && !VIMEO_HASH.test(hash)) return null;
|
|
1388
1750
|
const h = hash ? hash.toLowerCase() : null;
|
|
1389
|
-
return { provider: "vimeo", src: `https://player.vimeo.com/video/${
|
|
1751
|
+
return { provider: "vimeo", src: `https://player.vimeo.com/video/${id2}${h ? `?h=${h}` : ""}`, watchUrl: `https://vimeo.com/${id2}${h ? `/${h}` : ""}`, title: "Vimeo video" };
|
|
1390
1752
|
}
|
|
1391
1753
|
function toEmbedUrl(input) {
|
|
1392
1754
|
const u = parseUrl(input);
|
|
@@ -1412,16 +1774,16 @@ function toEmbedUrl(input) {
|
|
|
1412
1774
|
return parts[0] === "video" && parts.length === 2 ? vimeo(parts[1], u.searchParams.get("h")) : null;
|
|
1413
1775
|
case "loom.com":
|
|
1414
1776
|
if ((parts[0] === "share" || parts[0] === "embed") && parts.length === 2 && LOOM_ID.test(parts[1])) {
|
|
1415
|
-
const
|
|
1416
|
-
return { provider: "loom", src: `https://www.loom.com/embed/${
|
|
1777
|
+
const id2 = parts[1].toLowerCase();
|
|
1778
|
+
return { provider: "loom", src: `https://www.loom.com/embed/${id2}`, watchUrl: `https://www.loom.com/share/${id2}`, title: "Loom video" };
|
|
1417
1779
|
}
|
|
1418
1780
|
return null;
|
|
1419
1781
|
default: {
|
|
1420
|
-
let
|
|
1421
|
-
if (host === "fast.wistia.net" || host === "fast.wistia.com")
|
|
1422
|
-
else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host))
|
|
1423
|
-
if (!
|
|
1424
|
-
return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${
|
|
1782
|
+
let id2;
|
|
1783
|
+
if (host === "fast.wistia.net" || host === "fast.wistia.com") id2 = parts[0] === "embed" && parts[1] === "iframe" && parts.length === 3 ? parts[2] : void 0;
|
|
1784
|
+
else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host)) id2 = parts[0] === "medias" && parts.length === 2 ? parts[1] : void 0;
|
|
1785
|
+
if (!id2 || !WISTIA_ID.test(id2)) return null;
|
|
1786
|
+
return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${id2}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id2}`, title: "Wistia video" };
|
|
1425
1787
|
}
|
|
1426
1788
|
}
|
|
1427
1789
|
}
|
|
@@ -1452,7 +1814,7 @@ var MAX_COLLECTION_DEPTH = 3;
|
|
|
1452
1814
|
function matchesAudiences(required, member) {
|
|
1453
1815
|
if (!required || required.length === 0) return true;
|
|
1454
1816
|
if (!member) return false;
|
|
1455
|
-
const has2 = member instanceof Set ? (
|
|
1817
|
+
const has2 = member instanceof Set ? (id2) => member.has(id2) : (id2) => member.includes(id2);
|
|
1456
1818
|
return required.some(has2);
|
|
1457
1819
|
}
|
|
1458
1820
|
function resourceCenterSections(collections, articles, member) {
|
|
@@ -1506,7 +1868,7 @@ function servedArticleAudiences(audienceIds, visibility) {
|
|
|
1506
1868
|
return visibility === "identified" && audienceIds.length === 0 ? [LOGGED_IN_AUDIENCE] : [...audienceIds];
|
|
1507
1869
|
}
|
|
1508
1870
|
function visitorAudiences(audienceIds, identified) {
|
|
1509
|
-
const ids = audienceIds.filter((
|
|
1871
|
+
const ids = audienceIds.filter((id2) => id2 !== LOGGED_IN_AUDIENCE);
|
|
1510
1872
|
return identified ? [...ids, LOGGED_IN_AUDIENCE] : ids;
|
|
1511
1873
|
}
|
|
1512
1874
|
function visibleArticleIds(collections, articles, member) {
|
|
@@ -1542,9 +1904,35 @@ function matchesHelpQuery(text, query) {
|
|
|
1542
1904
|
const have = words(hay);
|
|
1543
1905
|
return terms.every((t) => have.some((w) => w.startsWith(t) || t.length > 3 && t.endsWith("s") && w.startsWith(t.slice(0, -1))));
|
|
1544
1906
|
}
|
|
1907
|
+
var RC_MODULE_IDS = ["announcements", "search", "checklists", "guides", "articles", "links", "faqs"];
|
|
1908
|
+
var RC_MODULE_LABELS = {
|
|
1909
|
+
announcements: "What's new",
|
|
1910
|
+
search: "Search",
|
|
1911
|
+
checklists: "Checklists",
|
|
1912
|
+
guides: "Guides & tours",
|
|
1913
|
+
articles: "Articles",
|
|
1914
|
+
links: "Links",
|
|
1915
|
+
faqs: "FAQs"
|
|
1916
|
+
};
|
|
1917
|
+
function orderedModules(modules) {
|
|
1918
|
+
const known = (modules ?? []).filter((m, i, all) => RC_MODULE_IDS.includes(m.id) && all.findIndex((x) => x.id === m.id) === i);
|
|
1919
|
+
const missing = RC_MODULE_IDS.filter((id2) => !known.some((m) => m.id === id2)).map((id2) => ({ id: id2, enabled: true }));
|
|
1920
|
+
return [...known, ...missing];
|
|
1921
|
+
}
|
|
1922
|
+
function visibleAnnouncements(items, member, now = Date.now()) {
|
|
1923
|
+
return (items ?? []).filter((a) => {
|
|
1924
|
+
const t = Date.parse(a.publishedAt);
|
|
1925
|
+
return !Number.isNaN(t) && t <= now && matchesAudiences(a.audienceIds, member);
|
|
1926
|
+
}).sort((a, b) => Date.parse(b.publishedAt) - Date.parse(a.publishedAt));
|
|
1927
|
+
}
|
|
1928
|
+
function unreadAnnouncements(items, lastSeenAt) {
|
|
1929
|
+
const seen = lastSeenAt ? Date.parse(lastSeenAt) : NaN;
|
|
1930
|
+
if (Number.isNaN(seen)) return items.length;
|
|
1931
|
+
return items.filter((a) => Date.parse(a.publishedAt) > seen).length;
|
|
1932
|
+
}
|
|
1545
1933
|
|
|
1546
1934
|
// src/howto.ts
|
|
1547
|
-
var
|
|
1935
|
+
var import_zod10 = require("zod");
|
|
1548
1936
|
|
|
1549
1937
|
// src/howto-limits.ts
|
|
1550
1938
|
var CAPTURE_PARAM = "guidely_capture";
|
|
@@ -1553,36 +1941,36 @@ var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
|
|
|
1553
1941
|
// src/howto.ts
|
|
1554
1942
|
var HOWTO_STEP_KINDS = ["action", "text", "heading", "tip", "alert"];
|
|
1555
1943
|
var HOWTO_ACTIONS = ["click", "type", "select", "navigate"];
|
|
1556
|
-
var NormalizedRectSchema =
|
|
1557
|
-
x:
|
|
1558
|
-
y:
|
|
1559
|
-
width:
|
|
1560
|
-
height:
|
|
1944
|
+
var NormalizedRectSchema = import_zod10.z.object({
|
|
1945
|
+
x: import_zod10.z.number().min(0).max(1),
|
|
1946
|
+
y: import_zod10.z.number().min(0).max(1),
|
|
1947
|
+
width: import_zod10.z.number().min(0).max(1),
|
|
1948
|
+
height: import_zod10.z.number().min(0).max(1)
|
|
1561
1949
|
});
|
|
1562
|
-
var CapturedElementSchema =
|
|
1950
|
+
var CapturedElementSchema = import_zod10.z.object({
|
|
1563
1951
|
/** Visible name: aria-label, associated label, text, placeholder, alt or title. */
|
|
1564
|
-
label:
|
|
1952
|
+
label: import_zod10.z.string().max(200).default(""),
|
|
1565
1953
|
/** button, link, tab, menuitem, checkbox, radio, field, dropdown, option, element… */
|
|
1566
|
-
role:
|
|
1567
|
-
tag:
|
|
1954
|
+
role: import_zod10.z.string().max(40).default("element"),
|
|
1955
|
+
tag: import_zod10.z.string().max(40).default("")
|
|
1568
1956
|
});
|
|
1569
|
-
var CaptureStepSchema =
|
|
1957
|
+
var CaptureStepSchema = import_zod10.z.object({
|
|
1570
1958
|
/** Random id from the SDK; a retried upload with the same id is stored once. */
|
|
1571
|
-
clientId:
|
|
1572
|
-
action:
|
|
1573
|
-
url:
|
|
1574
|
-
pageTitle:
|
|
1959
|
+
clientId: import_zod10.z.string().min(1).max(64),
|
|
1960
|
+
action: import_zod10.z.enum(HOWTO_ACTIONS),
|
|
1961
|
+
url: import_zod10.z.string().max(2e3),
|
|
1962
|
+
pageTitle: import_zod10.z.string().max(300).default(""),
|
|
1575
1963
|
element: CapturedElementSchema.optional(),
|
|
1576
1964
|
/** Typed text or chosen option; absent when it was sensitive (`valueRedacted`). */
|
|
1577
|
-
value:
|
|
1578
|
-
valueRedacted:
|
|
1965
|
+
value: import_zod10.z.string().max(200).optional(),
|
|
1966
|
+
valueRedacted: import_zod10.z.boolean().default(false),
|
|
1579
1967
|
/** Selectors for the element, so the step can later become an interactive tour step. */
|
|
1580
|
-
selectors:
|
|
1968
|
+
selectors: import_zod10.z.array(SelectorStrategySchema).max(10).default([]),
|
|
1581
1969
|
/** Where the element sits in the screenshot. */
|
|
1582
1970
|
highlight: NormalizedRectSchema.optional(),
|
|
1583
1971
|
/** Number of regions the SDK blurred in the screenshot before upload. */
|
|
1584
|
-
redactions:
|
|
1585
|
-
occurredAt:
|
|
1972
|
+
redactions: import_zod10.z.number().int().min(0).max(1e3).default(0),
|
|
1973
|
+
occurredAt: import_zod10.z.string().datetime().optional()
|
|
1586
1974
|
});
|
|
1587
1975
|
function quoted(s) {
|
|
1588
1976
|
const t = (s ?? "").replace(/\s+/g, " ").trim();
|
|
@@ -1653,12 +2041,12 @@ function hostAndPath(url) {
|
|
|
1653
2041
|
return url.slice(0, 80);
|
|
1654
2042
|
}
|
|
1655
2043
|
}
|
|
1656
|
-
var NormalizedPointSchema =
|
|
2044
|
+
var NormalizedPointSchema = import_zod10.z.object({ x: import_zod10.z.number().min(0).max(1), y: import_zod10.z.number().min(0).max(1) });
|
|
1657
2045
|
var ANNOTATION_COLORS = ["brand", "red", "amber", "green", "black", "white"];
|
|
1658
|
-
var HowToAnnotationSchema =
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
2046
|
+
var HowToAnnotationSchema = import_zod10.z.discriminatedUnion("type", [
|
|
2047
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("arrow"), from: NormalizedPointSchema, to: NormalizedPointSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
|
|
2048
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("text"), at: NormalizedPointSchema, text: import_zod10.z.string().trim().min(1).max(120), color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") }),
|
|
2049
|
+
import_zod10.z.object({ id: import_zod10.z.string().min(1).max(32), type: import_zod10.z.literal("box"), rect: NormalizedRectSchema, color: import_zod10.z.enum(ANNOTATION_COLORS).default("brand") })
|
|
1662
2050
|
]);
|
|
1663
2051
|
var MAX_ANNOTATIONS = 30;
|
|
1664
2052
|
|
|
@@ -1686,21 +2074,1128 @@ function pageLabel(path) {
|
|
|
1686
2074
|
}
|
|
1687
2075
|
function firstNameFromTraits(traits) {
|
|
1688
2076
|
if (!traits) return null;
|
|
1689
|
-
const
|
|
1690
|
-
const first =
|
|
2077
|
+
const pick2 = (v) => typeof v === "string" ? v.trim() : "";
|
|
2078
|
+
const first = pick2(traits.firstName) || pick2(traits.first_name) || pick2(traits.firstname) || pick2(traits.name).split(/\s+/)[0] || "";
|
|
1691
2079
|
if (!first || first.length > 40 || first.includes("@") || !/\p{L}/u.test(first)) return null;
|
|
1692
2080
|
return first;
|
|
1693
2081
|
}
|
|
1694
2082
|
|
|
2083
|
+
// src/tagging.ts
|
|
2084
|
+
var SNAPSHOT_LIMITS = { classes: 8, className: 60, attrs: 6, attrValue: 100, ancestors: 5, hosts: 3, tag: 40, id: 80 };
|
|
2085
|
+
var SNAPSHOT_ATTRS = ["role", "name", "type", "aria-label", "title", "alt", "for", "href"];
|
|
2086
|
+
var NOISY_DATA_ATTR = /^data-(state|v-|react|radix|headlessui|svelte|orientation|highlighted|focus|key|index|side|align|disabled|selected|active|open|rbd|dnd|sveltekit|guidely-(mask|ignore|block))/i;
|
|
2087
|
+
var DEFAULT_FEATURE_ATTRIBUTE = "data-guidely-feature";
|
|
2088
|
+
var FEATURE_ATTRIBUTE_PATTERN = /^data-[a-z0-9][a-z0-9_.-]{0,60}$/;
|
|
2089
|
+
function str(v, max) {
|
|
2090
|
+
return typeof v === "string" && v ? v.slice(0, max) : void 0;
|
|
2091
|
+
}
|
|
2092
|
+
function cleanNode(raw) {
|
|
2093
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2094
|
+
const r = raw;
|
|
2095
|
+
const t = str(r.t, SNAPSHOT_LIMITS.tag)?.toLowerCase();
|
|
2096
|
+
if (!t || !/^[a-z][a-z0-9-]*$/.test(t)) return null;
|
|
2097
|
+
const node = { t };
|
|
2098
|
+
const id2 = str(r.id, SNAPSHOT_LIMITS.id);
|
|
2099
|
+
if (id2) node.id = id2;
|
|
2100
|
+
if (Array.isArray(r.c)) {
|
|
2101
|
+
const c = r.c.filter((x) => typeof x === "string" && !!x && x.length <= SNAPSHOT_LIMITS.className && !/\s/.test(x)).slice(0, SNAPSHOT_LIMITS.classes);
|
|
2102
|
+
if (c.length) node.c = c;
|
|
2103
|
+
}
|
|
2104
|
+
if (r.a && typeof r.a === "object" && !Array.isArray(r.a)) {
|
|
2105
|
+
const a = {};
|
|
2106
|
+
for (const [k, v] of Object.entries(r.a)) {
|
|
2107
|
+
if (Object.keys(a).length >= SNAPSHOT_LIMITS.attrs) break;
|
|
2108
|
+
const key = k.toLowerCase();
|
|
2109
|
+
if (typeof v !== "string" || !(key.startsWith("data-") || SNAPSHOT_ATTRS.includes(key)) || key === "value" || key.length > 60) continue;
|
|
2110
|
+
a[key] = v.slice(0, SNAPSHOT_LIMITS.attrValue);
|
|
2111
|
+
}
|
|
2112
|
+
if (Object.keys(a).length) node.a = a;
|
|
2113
|
+
}
|
|
2114
|
+
if (typeof r.n === "number" && Number.isInteger(r.n) && r.n >= 1 && r.n <= 1e4) node.n = r.n;
|
|
2115
|
+
return node;
|
|
2116
|
+
}
|
|
2117
|
+
function normalizeSnapshot(raw) {
|
|
2118
|
+
const el = cleanNode(raw);
|
|
2119
|
+
if (!el) return null;
|
|
2120
|
+
const r = raw;
|
|
2121
|
+
const out = el;
|
|
2122
|
+
if (Array.isArray(r.p)) {
|
|
2123
|
+
const p = r.p.slice(0, SNAPSHOT_LIMITS.ancestors).map(cleanNode);
|
|
2124
|
+
const cut = p.indexOf(null);
|
|
2125
|
+
const list = cut === -1 ? p : p.slice(0, cut);
|
|
2126
|
+
if (list.length) out.p = list;
|
|
2127
|
+
}
|
|
2128
|
+
if (Array.isArray(r.h)) {
|
|
2129
|
+
const h = r.h.slice(0, SNAPSHOT_LIMITS.hosts).map(cleanNode).filter((x) => !!x);
|
|
2130
|
+
if (h.length) out.h = h;
|
|
2131
|
+
}
|
|
2132
|
+
return out;
|
|
2133
|
+
}
|
|
2134
|
+
function stableStringify(v) {
|
|
2135
|
+
if (Array.isArray(v)) return `[${v.map(stableStringify).join(",")}]`;
|
|
2136
|
+
if (v && typeof v === "object") {
|
|
2137
|
+
const o = v;
|
|
2138
|
+
return `{${Object.keys(o).filter((k) => o[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(o[k])}`).join(",")}}`;
|
|
2139
|
+
}
|
|
2140
|
+
return JSON.stringify(v ?? null);
|
|
2141
|
+
}
|
|
2142
|
+
var SelectorSyntaxError = class extends Error {
|
|
2143
|
+
};
|
|
2144
|
+
var IDENT_START = /[A-Za-z_\u00a0-\uffff-]/;
|
|
2145
|
+
var IDENT_CHAR = /[A-Za-z0-9_\u00a0-\uffff-]/;
|
|
2146
|
+
function parseCssSelector(input) {
|
|
2147
|
+
const s = input.trim();
|
|
2148
|
+
if (!s) throw new SelectorSyntaxError("Empty selector");
|
|
2149
|
+
if (s.length > 1e3) throw new SelectorSyntaxError("Selector is too long");
|
|
2150
|
+
let i = 0;
|
|
2151
|
+
const peek = () => s[i];
|
|
2152
|
+
const eof = () => i >= s.length;
|
|
2153
|
+
const fail = (msg) => {
|
|
2154
|
+
throw new SelectorSyntaxError(`${msg} at position ${i + 1}`);
|
|
2155
|
+
};
|
|
2156
|
+
const ws = () => {
|
|
2157
|
+
let any = false;
|
|
2158
|
+
while (!eof() && /\s/.test(s[i])) {
|
|
2159
|
+
i++;
|
|
2160
|
+
any = true;
|
|
2161
|
+
}
|
|
2162
|
+
return any;
|
|
2163
|
+
};
|
|
2164
|
+
const escape = () => {
|
|
2165
|
+
i++;
|
|
2166
|
+
const hex = /^[0-9a-fA-F]{1,6}/.exec(s.slice(i));
|
|
2167
|
+
if (hex) {
|
|
2168
|
+
i += hex[0].length;
|
|
2169
|
+
if (s[i] === " ") i++;
|
|
2170
|
+
return String.fromCodePoint(parseInt(hex[0], 16));
|
|
2171
|
+
}
|
|
2172
|
+
if (eof()) fail("Unfinished escape");
|
|
2173
|
+
return s[i++];
|
|
2174
|
+
};
|
|
2175
|
+
const ident = () => {
|
|
2176
|
+
let out = "";
|
|
2177
|
+
if (s[i] === "\\") out += escape();
|
|
2178
|
+
else if (!eof() && IDENT_START.test(s[i])) out += s[i++];
|
|
2179
|
+
else fail("Expected a name");
|
|
2180
|
+
while (!eof()) {
|
|
2181
|
+
if (s[i] === "\\") out += escape();
|
|
2182
|
+
else if (IDENT_CHAR.test(s[i])) out += s[i++];
|
|
2183
|
+
else break;
|
|
2184
|
+
}
|
|
2185
|
+
return out;
|
|
2186
|
+
};
|
|
2187
|
+
const quoted2 = () => {
|
|
2188
|
+
const q = s[i++];
|
|
2189
|
+
let out = "";
|
|
2190
|
+
while (!eof() && s[i] !== q) {
|
|
2191
|
+
if (s[i] === "\\") out += escape();
|
|
2192
|
+
else out += s[i++];
|
|
2193
|
+
}
|
|
2194
|
+
if (eof()) fail("Unterminated string");
|
|
2195
|
+
i++;
|
|
2196
|
+
return out;
|
|
2197
|
+
};
|
|
2198
|
+
const compound = () => {
|
|
2199
|
+
const c = { classes: [], attrs: [] };
|
|
2200
|
+
let any = false;
|
|
2201
|
+
if (peek() === "*") {
|
|
2202
|
+
i++;
|
|
2203
|
+
any = true;
|
|
2204
|
+
} else if (!eof() && (IDENT_START.test(peek()) || peek() === "\\")) {
|
|
2205
|
+
c.tag = ident().toLowerCase();
|
|
2206
|
+
any = true;
|
|
2207
|
+
}
|
|
2208
|
+
for (; ; ) {
|
|
2209
|
+
const ch = peek();
|
|
2210
|
+
if (ch === "#") {
|
|
2211
|
+
i++;
|
|
2212
|
+
c.id = ident();
|
|
2213
|
+
} else if (ch === ".") {
|
|
2214
|
+
i++;
|
|
2215
|
+
c.classes.push(ident());
|
|
2216
|
+
} else if (ch === "[") {
|
|
2217
|
+
i++;
|
|
2218
|
+
ws();
|
|
2219
|
+
const name = ident().toLowerCase();
|
|
2220
|
+
ws();
|
|
2221
|
+
let op = "exists";
|
|
2222
|
+
let value;
|
|
2223
|
+
let insensitive = false;
|
|
2224
|
+
if (peek() !== "]") {
|
|
2225
|
+
const m = /^(=|\^=|\$=|\*=|~=|\|=)/.exec(s.slice(i));
|
|
2226
|
+
if (!m) fail("Unsupported attribute operator");
|
|
2227
|
+
op = m[1];
|
|
2228
|
+
i += m[1].length;
|
|
2229
|
+
ws();
|
|
2230
|
+
value = peek() === '"' || peek() === "'" ? quoted2() : ident();
|
|
2231
|
+
ws();
|
|
2232
|
+
if (peek() === "i" || peek() === "I") {
|
|
2233
|
+
i++;
|
|
2234
|
+
insensitive = true;
|
|
2235
|
+
ws();
|
|
2236
|
+
} else if (peek() === "s" || peek() === "S") {
|
|
2237
|
+
i++;
|
|
2238
|
+
ws();
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
if (peek() !== "]") fail("Expected ]");
|
|
2242
|
+
i++;
|
|
2243
|
+
c.attrs.push({ name, op, ...value !== void 0 ? { value } : {}, ...insensitive ? { insensitive } : {} });
|
|
2244
|
+
} else if (ch === ":") {
|
|
2245
|
+
i++;
|
|
2246
|
+
if (peek() === ":") fail("Pseudo-elements are not supported");
|
|
2247
|
+
const name = ident().toLowerCase();
|
|
2248
|
+
if (name === "first-of-type") c.nth = { a: 0, b: 1 };
|
|
2249
|
+
else if (name === "nth-of-type") {
|
|
2250
|
+
if (peek() !== "(") fail("Expected (");
|
|
2251
|
+
i++;
|
|
2252
|
+
ws();
|
|
2253
|
+
const m = /^(odd|even|\d+)/i.exec(s.slice(i));
|
|
2254
|
+
if (!m) fail("Only :nth-of-type(n), odd or even are supported");
|
|
2255
|
+
i += m[0].length;
|
|
2256
|
+
ws();
|
|
2257
|
+
if (peek() !== ")") fail("Expected )");
|
|
2258
|
+
i++;
|
|
2259
|
+
const v = m[0].toLowerCase();
|
|
2260
|
+
c.nth = v === "odd" ? { a: 2, b: 1 } : v === "even" ? { a: 2, b: 0 } : { a: 0, b: Number(v) };
|
|
2261
|
+
} else fail(`Unsupported pseudo-class :${name}`);
|
|
2262
|
+
} else break;
|
|
2263
|
+
any = true;
|
|
2264
|
+
}
|
|
2265
|
+
return any ? c : null;
|
|
2266
|
+
};
|
|
2267
|
+
const list = [];
|
|
2268
|
+
for (; ; ) {
|
|
2269
|
+
ws();
|
|
2270
|
+
const sel = { compounds: [], combinators: [] };
|
|
2271
|
+
const first = compound();
|
|
2272
|
+
if (!first) fail("Expected a selector");
|
|
2273
|
+
sel.compounds.push(first);
|
|
2274
|
+
for (; ; ) {
|
|
2275
|
+
const hadWs = ws();
|
|
2276
|
+
if (eof() || peek() === ",") break;
|
|
2277
|
+
let comb = " ";
|
|
2278
|
+
if (s.startsWith(">>>", i)) {
|
|
2279
|
+
comb = ">>>";
|
|
2280
|
+
i += 3;
|
|
2281
|
+
ws();
|
|
2282
|
+
} else if (peek() === ">") {
|
|
2283
|
+
comb = ">";
|
|
2284
|
+
i++;
|
|
2285
|
+
ws();
|
|
2286
|
+
} else if (peek() === "+" || peek() === "~") fail("Sibling combinators are not supported");
|
|
2287
|
+
else if (!hadWs) fail("Unexpected character");
|
|
2288
|
+
const next = compound();
|
|
2289
|
+
if (!next) fail("Expected a selector after the combinator");
|
|
2290
|
+
sel.compounds.push(next);
|
|
2291
|
+
sel.combinators.push(comb);
|
|
2292
|
+
}
|
|
2293
|
+
list.push(sel);
|
|
2294
|
+
if (eof()) break;
|
|
2295
|
+
i++;
|
|
2296
|
+
}
|
|
2297
|
+
return list;
|
|
2298
|
+
}
|
|
2299
|
+
function cssSelectorError(selector) {
|
|
2300
|
+
try {
|
|
2301
|
+
parseCssSelector(selector);
|
|
2302
|
+
return null;
|
|
2303
|
+
} catch (e) {
|
|
2304
|
+
return e instanceof Error ? e.message : "Invalid selector";
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
function attrMatches(test, node) {
|
|
2308
|
+
let actual;
|
|
2309
|
+
if (test.name === "id") actual = node.id;
|
|
2310
|
+
else if (test.name === "class") actual = node.c?.join(" ");
|
|
2311
|
+
else actual = node.a?.[test.name];
|
|
2312
|
+
if (actual === void 0) return false;
|
|
2313
|
+
if (test.op === "exists") return true;
|
|
2314
|
+
let v = test.value ?? "";
|
|
2315
|
+
if (test.insensitive) {
|
|
2316
|
+
actual = actual.toLowerCase();
|
|
2317
|
+
v = v.toLowerCase();
|
|
2318
|
+
}
|
|
2319
|
+
switch (test.op) {
|
|
2320
|
+
case "=":
|
|
2321
|
+
return actual === v;
|
|
2322
|
+
case "^=":
|
|
2323
|
+
return !!v && actual.startsWith(v);
|
|
2324
|
+
case "$=":
|
|
2325
|
+
return !!v && actual.endsWith(v);
|
|
2326
|
+
case "*=":
|
|
2327
|
+
return !!v && actual.includes(v);
|
|
2328
|
+
case "~=":
|
|
2329
|
+
return !!v && actual.split(/\s+/).includes(v);
|
|
2330
|
+
case "|=":
|
|
2331
|
+
return actual === v || actual.startsWith(`${v}-`);
|
|
2332
|
+
default:
|
|
2333
|
+
return false;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
function compoundMatches(c, node) {
|
|
2337
|
+
if (c.tag && c.tag !== node.t) return false;
|
|
2338
|
+
if (c.id !== void 0 && node.id !== c.id) return false;
|
|
2339
|
+
for (const cls of c.classes) if (!node.c?.includes(cls)) return false;
|
|
2340
|
+
for (const a of c.attrs) if (!attrMatches(a, node)) return false;
|
|
2341
|
+
if (c.nth) {
|
|
2342
|
+
if (!node.n) return false;
|
|
2343
|
+
const { a, b } = c.nth;
|
|
2344
|
+
if (a === 0 ? node.n !== b : (node.n - b) % a !== 0 || (node.n - b) / a < 0) return false;
|
|
2345
|
+
}
|
|
2346
|
+
return true;
|
|
2347
|
+
}
|
|
2348
|
+
function chainMatches(compounds, combinators, nodes, ci = compounds.length - 1, ni = 0) {
|
|
2349
|
+
if (!compoundMatches(compounds[ci], nodes[ni])) return false;
|
|
2350
|
+
if (ci === 0) return true;
|
|
2351
|
+
const comb = combinators[ci - 1];
|
|
2352
|
+
if (comb === ">") return ni + 1 < nodes.length && chainMatches(compounds, combinators, nodes, ci - 1, ni + 1);
|
|
2353
|
+
for (let k = ni + 1; k < nodes.length; k++) if (chainMatches(compounds, combinators, nodes, ci - 1, k)) return true;
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
function complexMatches(sel, snap) {
|
|
2357
|
+
const segments = [{ compounds: [sel.compounds[0]], combinators: [] }];
|
|
2358
|
+
sel.combinators.forEach((comb, k) => {
|
|
2359
|
+
const next = sel.compounds[k + 1];
|
|
2360
|
+
if (comb === ">>>") segments.push({ compounds: [next], combinators: [] });
|
|
2361
|
+
else {
|
|
2362
|
+
const seg = segments[segments.length - 1];
|
|
2363
|
+
seg.compounds.push(next);
|
|
2364
|
+
seg.combinators.push(comb);
|
|
2365
|
+
}
|
|
2366
|
+
});
|
|
2367
|
+
const last = segments.pop();
|
|
2368
|
+
const nodes = [snap, ...snap.p ?? []];
|
|
2369
|
+
if (!chainMatches(last.compounds, last.combinators, nodes)) return false;
|
|
2370
|
+
const hosts = snap.h ?? [];
|
|
2371
|
+
let from = 0;
|
|
2372
|
+
for (let k = segments.length - 1; k >= 0; k--) {
|
|
2373
|
+
const target = segments[k].compounds[segments[k].compounds.length - 1];
|
|
2374
|
+
let found = -1;
|
|
2375
|
+
for (let j = from; j < hosts.length; j++) {
|
|
2376
|
+
if (compoundMatches(target, hosts[j])) {
|
|
2377
|
+
found = j;
|
|
2378
|
+
break;
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
if (found === -1) return false;
|
|
2382
|
+
from = found + 1;
|
|
2383
|
+
}
|
|
2384
|
+
return true;
|
|
2385
|
+
}
|
|
2386
|
+
var parsedCache = /* @__PURE__ */ new Map();
|
|
2387
|
+
function matchCssSelector(selector, snap) {
|
|
2388
|
+
let list;
|
|
2389
|
+
if (typeof selector === "string") {
|
|
2390
|
+
if (!parsedCache.has(selector)) {
|
|
2391
|
+
if (parsedCache.size > 500) parsedCache.clear();
|
|
2392
|
+
try {
|
|
2393
|
+
parsedCache.set(selector, parseCssSelector(selector));
|
|
2394
|
+
} catch {
|
|
2395
|
+
parsedCache.set(selector, null);
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
list = parsedCache.get(selector);
|
|
2399
|
+
} else list = selector;
|
|
2400
|
+
return !!list && list.some((sel) => complexMatches(sel, snap));
|
|
2401
|
+
}
|
|
2402
|
+
function nodeOfCompound(c) {
|
|
2403
|
+
const node = { t: c.tag ?? "*" };
|
|
2404
|
+
if (c.id) node.id = c.id;
|
|
2405
|
+
if (c.classes.length) node.c = c.classes.slice(0, SNAPSHOT_LIMITS.classes);
|
|
2406
|
+
const a = {};
|
|
2407
|
+
for (const t of c.attrs) if (t.op === "=" && t.value !== void 0) a[t.name] = t.value;
|
|
2408
|
+
if (Object.keys(a).length) node.a = a;
|
|
2409
|
+
if (c.nth && c.nth.a === 0) node.n = c.nth.b;
|
|
2410
|
+
return node;
|
|
2411
|
+
}
|
|
2412
|
+
function snapshotFromSelector(selector, tag) {
|
|
2413
|
+
let list;
|
|
2414
|
+
try {
|
|
2415
|
+
list = parseCssSelector(selector);
|
|
2416
|
+
} catch {
|
|
2417
|
+
return null;
|
|
2418
|
+
}
|
|
2419
|
+
if (list.length !== 1) return null;
|
|
2420
|
+
const sel = list[0];
|
|
2421
|
+
const segments = [[sel.compounds[0]]];
|
|
2422
|
+
sel.combinators.forEach((comb, k) => {
|
|
2423
|
+
if (comb === ">>>") segments.push([sel.compounds[k + 1]]);
|
|
2424
|
+
else segments[segments.length - 1].push(sel.compounds[k + 1]);
|
|
2425
|
+
});
|
|
2426
|
+
const own = segments.pop();
|
|
2427
|
+
const el = nodeOfCompound(own[own.length - 1]);
|
|
2428
|
+
if (el.t === "*" && tag && /^[a-z][a-z0-9-]*$/i.test(tag)) el.t = tag.toLowerCase();
|
|
2429
|
+
const snap = el;
|
|
2430
|
+
const p = own.slice(0, -1).reverse().map(nodeOfCompound);
|
|
2431
|
+
if (p.length) snap.p = p.slice(0, SNAPSHOT_LIMITS.ancestors);
|
|
2432
|
+
const h = segments.reverse().map((seg) => nodeOfCompound(seg[seg.length - 1]));
|
|
2433
|
+
if (h.length) snap.h = h.slice(0, SNAPSHOT_LIMITS.hosts);
|
|
2434
|
+
return snap;
|
|
2435
|
+
}
|
|
2436
|
+
var PAGE_RULE_LIMITS = { rules: 20, value: 500, query: 5 };
|
|
2437
|
+
var escapeRe = (s) => s.replace(/[.+?^${}()|[\]\\*]/g, "\\$&");
|
|
2438
|
+
function globToRegex(pattern) {
|
|
2439
|
+
let out = "";
|
|
2440
|
+
for (let k = 0; k < pattern.length; k++) {
|
|
2441
|
+
const ch = pattern[k];
|
|
2442
|
+
if (ch === "*") {
|
|
2443
|
+
if (pattern[k + 1] === "*") {
|
|
2444
|
+
out += ".*";
|
|
2445
|
+
k++;
|
|
2446
|
+
} else out += "[^/]*";
|
|
2447
|
+
} else if (ch === ":" && (k === 0 || pattern[k - 1] === "/") && /[A-Za-z_]/.test(pattern[k + 1] ?? "")) {
|
|
2448
|
+
let j = k + 1;
|
|
2449
|
+
while (j < pattern.length && /[\w]/.test(pattern[j])) j++;
|
|
2450
|
+
out += "[^/]+";
|
|
2451
|
+
k = j - 1;
|
|
2452
|
+
} else out += escapeRe(ch);
|
|
2453
|
+
}
|
|
2454
|
+
return out;
|
|
2455
|
+
}
|
|
2456
|
+
function pagePattern(raw) {
|
|
2457
|
+
let p = raw.trim();
|
|
2458
|
+
const query = [];
|
|
2459
|
+
const hash = p.indexOf("#");
|
|
2460
|
+
if (hash !== -1) p = p.slice(0, hash);
|
|
2461
|
+
const q = p.indexOf("?");
|
|
2462
|
+
if (q !== -1) {
|
|
2463
|
+
for (const part of p.slice(q + 1).split("&")) {
|
|
2464
|
+
if (!part) continue;
|
|
2465
|
+
const eq = part.indexOf("=");
|
|
2466
|
+
const name = decodeSafe(eq === -1 ? part : part.slice(0, eq));
|
|
2467
|
+
const value = eq === -1 ? void 0 : decodeSafe(part.slice(eq + 1));
|
|
2468
|
+
if (!name) continue;
|
|
2469
|
+
query.push(value === void 0 || value === "*" ? { name, op: "exists" } : { name, op: "equals", value });
|
|
2470
|
+
}
|
|
2471
|
+
p = p.slice(0, q);
|
|
2472
|
+
}
|
|
2473
|
+
let target = "path";
|
|
2474
|
+
if (p.startsWith("//*")) p = p.slice(3);
|
|
2475
|
+
let prefix = "";
|
|
2476
|
+
const abs = /^(https?:)?\/\/([^/]+)(.*)$/i.exec(p);
|
|
2477
|
+
if (abs) {
|
|
2478
|
+
target = "url";
|
|
2479
|
+
prefix = `https?://${globToRegex(abs[2].toLowerCase())}`;
|
|
2480
|
+
p = abs[3] || "/";
|
|
2481
|
+
}
|
|
2482
|
+
if (!p.startsWith("/")) p = `/${p}`;
|
|
2483
|
+
const body = p.length > 1 && p.endsWith("/") ? p.slice(0, -1) : p;
|
|
2484
|
+
const src = body === "/" ? "/?" : `${globToRegex(body)}/?`;
|
|
2485
|
+
return { source: `^${prefix}${src}$`, target, query: query.slice(0, PAGE_RULE_LIMITS.query) };
|
|
2486
|
+
}
|
|
2487
|
+
function decodeSafe(s) {
|
|
2488
|
+
try {
|
|
2489
|
+
return decodeURIComponent(s.replace(/\+/g, " "));
|
|
2490
|
+
} catch {
|
|
2491
|
+
return s;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
function queryConditionRegex(c) {
|
|
2495
|
+
const name = escapeRe(c.name);
|
|
2496
|
+
switch (c.op) {
|
|
2497
|
+
case "equals":
|
|
2498
|
+
return `[?&]${name}=${escapeRe(encodeLoose(c.value ?? ""))}(&|#|$)`;
|
|
2499
|
+
case "contains":
|
|
2500
|
+
return `[?&]${name}=[^&#]*${escapeRe(encodeLoose(c.value ?? ""))}`;
|
|
2501
|
+
default:
|
|
2502
|
+
return `[?&]${name}(=|&|#|$)`;
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
function encodeLoose(v) {
|
|
2506
|
+
return encodeURIComponent(v).replace(/%2F/gi, "/").replace(/%3A/gi, ":").replace(/%2C/gi, ",").replace(/%40/gi, "@");
|
|
2507
|
+
}
|
|
2508
|
+
function pathOnly(ctx) {
|
|
2509
|
+
if (ctx.path) return ctx.path.split("?")[0] || "/";
|
|
2510
|
+
if (!ctx.url) return null;
|
|
2511
|
+
try {
|
|
2512
|
+
return new URL(ctx.url, "http://x.invalid").pathname;
|
|
2513
|
+
} catch {
|
|
2514
|
+
return null;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
function regexOrNull(source) {
|
|
2518
|
+
try {
|
|
2519
|
+
return new RegExp(source, "i");
|
|
2520
|
+
} catch {
|
|
2521
|
+
return null;
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
function pageRuleMatches(rule, ctx) {
|
|
2525
|
+
const path = pathOnly(ctx);
|
|
2526
|
+
if (rule.type === "title") {
|
|
2527
|
+
const t = (ctx.title ?? "").toLowerCase();
|
|
2528
|
+
const v = rule.value.toLowerCase();
|
|
2529
|
+
return !!t && (rule.op === "contains" ? t.includes(v) : t === v);
|
|
2530
|
+
}
|
|
2531
|
+
if (rule.type === "regex") {
|
|
2532
|
+
const re2 = regexOrNull(rule.value);
|
|
2533
|
+
return !!re2 && path !== null && re2.test(path);
|
|
2534
|
+
}
|
|
2535
|
+
const pat = pagePattern(rule.value);
|
|
2536
|
+
const re = regexOrNull(pat.source);
|
|
2537
|
+
if (!re) return false;
|
|
2538
|
+
let subject = path;
|
|
2539
|
+
if (pat.target === "url") {
|
|
2540
|
+
if (!ctx.url) return false;
|
|
2541
|
+
subject = ctx.url.split(/[?#]/)[0];
|
|
2542
|
+
}
|
|
2543
|
+
if (subject === null || !re.test(subject)) return false;
|
|
2544
|
+
const conds = [...pat.query, ...rule.query ?? []];
|
|
2545
|
+
for (const c of conds) {
|
|
2546
|
+
const hit = !!ctx.url && new RegExp(queryConditionRegex(c), "i").test(ctx.url);
|
|
2547
|
+
if (c.op === "absent" ? hit : !hit) return false;
|
|
2548
|
+
}
|
|
2549
|
+
return true;
|
|
2550
|
+
}
|
|
2551
|
+
function pageRulesMatch(rules, ctx) {
|
|
2552
|
+
const include = rules.filter((r) => !r.exclude);
|
|
2553
|
+
if (!include.length || !include.some((r) => pageRuleMatches(r, ctx))) return false;
|
|
2554
|
+
return !rules.some((r) => r.exclude && pageRuleMatches(r, ctx));
|
|
2555
|
+
}
|
|
2556
|
+
function pageRuleError(rule) {
|
|
2557
|
+
const v = rule.value?.trim();
|
|
2558
|
+
if (!v) return "A rule needs a value";
|
|
2559
|
+
if (v.length > PAGE_RULE_LIMITS.value) return "The rule is too long";
|
|
2560
|
+
if (rule.type === "regex") {
|
|
2561
|
+
if (!regexOrNull(v)) return `"${v}" is not a valid regular expression`;
|
|
2562
|
+
if (/\(\?[<=!]/.test(v) || /\\[1-9]/.test(v)) return "Look-arounds and back-references are not supported";
|
|
2563
|
+
}
|
|
2564
|
+
if (rule.type === "url" && !regexOrNull(pagePattern(v).source)) return `"${v}" is not a valid URL rule`;
|
|
2565
|
+
for (const q of rule.query ?? []) if (!/^[A-Za-z0-9_.\-[\]]{1,60}$/.test(q.name)) return `"${q.name}" is not a query parameter name`;
|
|
2566
|
+
return null;
|
|
2567
|
+
}
|
|
2568
|
+
var FEATURE_RULE_LIMITS = { rules: 20, value: 1e3 };
|
|
2569
|
+
function globMatch(pattern, value) {
|
|
2570
|
+
const re = new RegExp(`^${pattern.split("*").map(escapeRe).join(".*")}$`, "s");
|
|
2571
|
+
return re.test(value);
|
|
2572
|
+
}
|
|
2573
|
+
function featureRuleMatchesClick(rule, click, css) {
|
|
2574
|
+
if (!rule.selector && !rule.text && !rule.tag && !rule.href) return false;
|
|
2575
|
+
if (rule.selector) {
|
|
2576
|
+
const sel = click.selector ?? "";
|
|
2577
|
+
const v = rule.selector.value;
|
|
2578
|
+
const ok = rule.selector.op === "css" ? css(v) : rule.selector.op === "exact" ? sel === v : rule.selector.op === "prefix" ? sel.startsWith(v) : rule.selector.op === "contains" ? sel.includes(v) : globMatch(v, sel);
|
|
2579
|
+
if (!ok) return false;
|
|
2580
|
+
}
|
|
2581
|
+
if (rule.text) {
|
|
2582
|
+
const t = (click.text ?? "").toLowerCase();
|
|
2583
|
+
const v = rule.text.value.toLowerCase();
|
|
2584
|
+
if (rule.text.op === "contains" ? !t.includes(v) : t !== v) return false;
|
|
2585
|
+
}
|
|
2586
|
+
if (rule.tag && (click.tag ?? "").toLowerCase() !== rule.tag.toLowerCase()) return false;
|
|
2587
|
+
if (rule.href) {
|
|
2588
|
+
const h = click.href ?? "";
|
|
2589
|
+
const v = rule.href.value;
|
|
2590
|
+
if (rule.href.op === "equals" ? h !== v : rule.href.op === "prefix" ? !h.startsWith(v) : !h.includes(v)) return false;
|
|
2591
|
+
}
|
|
2592
|
+
if (rule.platform && (click.platform ?? "web") !== rule.platform) return false;
|
|
2593
|
+
return true;
|
|
2594
|
+
}
|
|
2595
|
+
function featureRuleError(rule) {
|
|
2596
|
+
if (!rule.selector && !rule.text && !rule.tag && !rule.href) return "A feature rule needs a selector, text, tag or link condition";
|
|
2597
|
+
if (rule.selector) {
|
|
2598
|
+
const v = rule.selector.value?.trim();
|
|
2599
|
+
if (!v) return "The selector is empty";
|
|
2600
|
+
if (v.length > FEATURE_RULE_LIMITS.value) return "The selector is too long";
|
|
2601
|
+
if (rule.selector.op === "css") {
|
|
2602
|
+
const err = cssSelectorError(v);
|
|
2603
|
+
if (err) return `Unsupported CSS selector: ${err}`;
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
if (rule.text && !rule.text.value.trim()) return "The text condition is empty";
|
|
2607
|
+
if (rule.href && !rule.href.value.trim()) return "The link condition is empty";
|
|
2608
|
+
if (rule.tag && !/^[a-z][a-z0-9-]{0,40}$/i.test(rule.tag)) return "The tag is not an element name";
|
|
2609
|
+
if (rule.page?.pattern) return pageRuleError({ type: "url", value: rule.page.pattern });
|
|
2610
|
+
return null;
|
|
2611
|
+
}
|
|
2612
|
+
function featureCssSelectors(rules) {
|
|
2613
|
+
const out = [];
|
|
2614
|
+
for (const r of rules) {
|
|
2615
|
+
if (r.exclude || !r.selector) continue;
|
|
2616
|
+
if ((r.selector.op === "css" || r.selector.op === "exact") && !cssSelectorError(r.selector.value)) out.push(r.selector.value);
|
|
2617
|
+
}
|
|
2618
|
+
return out;
|
|
2619
|
+
}
|
|
2620
|
+
var TAG_PROPERTY_LIMITS = { perTag: 10, total: 50, value: 100 };
|
|
2621
|
+
function propertyAttributeAllowed(name) {
|
|
2622
|
+
const n = name.toLowerCase();
|
|
2623
|
+
if (n === "value" || n.startsWith("on") || n === "style" || n === "srcdoc") return false;
|
|
2624
|
+
return /^[a-z][a-z0-9_:.-]{0,60}$/.test(n);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
// src/snippet.ts
|
|
2628
|
+
var SCRIPT_STUB_METHODS = [
|
|
2629
|
+
"identify",
|
|
2630
|
+
"track",
|
|
2631
|
+
"page",
|
|
2632
|
+
"reset",
|
|
2633
|
+
"setAccount",
|
|
2634
|
+
"updateTraits",
|
|
2635
|
+
"setConsent",
|
|
2636
|
+
"setLocale",
|
|
2637
|
+
"startGuide",
|
|
2638
|
+
"stopGuide",
|
|
2639
|
+
"dismissGuide",
|
|
2640
|
+
"openMessenger",
|
|
2641
|
+
"closeMessenger",
|
|
2642
|
+
"showNewMessage",
|
|
2643
|
+
"openResourceCenter",
|
|
2644
|
+
"closeResourceCenter",
|
|
2645
|
+
"openChecklist",
|
|
2646
|
+
"closeChecklist",
|
|
2647
|
+
"completeChecklistTask",
|
|
2648
|
+
"openComplaint",
|
|
2649
|
+
"openIdeas",
|
|
2650
|
+
"captureException",
|
|
2651
|
+
"agentConversation",
|
|
2652
|
+
"trackAgentTurn",
|
|
2653
|
+
"on"
|
|
2654
|
+
];
|
|
2655
|
+
var SCRIPT_STUB = `!function(w){if(w.Guidely)return;var g=w.Guidely={_q:[]},c=g._c={};function q(o,k){o[k]=function(){g._q.push([o===c?1:0,k,[].slice.call(arguments)])}}q(g,"init");"${SCRIPT_STUB_METHODS.join(" ")}".split(" ").forEach(function(k){q(c,k)});c.isFeatureEnabled=function(k,f){return!!f};c.getFeatureValue=function(k,f){return f};g.get=function(){return c}}(window);`;
|
|
2656
|
+
function scriptSnippet(scriptUrl, initOptions) {
|
|
2657
|
+
return `<script>
|
|
2658
|
+
${SCRIPT_STUB}
|
|
2659
|
+
Guidely.init(${initOptions});
|
|
2660
|
+
</script>
|
|
2661
|
+
<script src="${scriptUrl}" async></script>`;
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
// src/localization.ts
|
|
2665
|
+
var DEFAULT_LOCALE = "en";
|
|
2666
|
+
var COMMON_LOCALES = [
|
|
2667
|
+
{ code: "en", name: "English" },
|
|
2668
|
+
{ code: "en-GB", name: "English (UK)" },
|
|
2669
|
+
{ code: "fr", name: "French" },
|
|
2670
|
+
{ code: "fr-CA", name: "French (Canada)" },
|
|
2671
|
+
{ code: "de", name: "German" },
|
|
2672
|
+
{ code: "es", name: "Spanish" },
|
|
2673
|
+
{ code: "es-MX", name: "Spanish (Mexico)" },
|
|
2674
|
+
{ code: "it", name: "Italian" },
|
|
2675
|
+
{ code: "pt", name: "Portuguese" },
|
|
2676
|
+
{ code: "pt-BR", name: "Portuguese (Brazil)" },
|
|
2677
|
+
{ code: "nl", name: "Dutch" },
|
|
2678
|
+
{ code: "sv", name: "Swedish" },
|
|
2679
|
+
{ code: "da", name: "Danish" },
|
|
2680
|
+
{ code: "nb", name: "Norwegian" },
|
|
2681
|
+
{ code: "fi", name: "Finnish" },
|
|
2682
|
+
{ code: "pl", name: "Polish" },
|
|
2683
|
+
{ code: "cs", name: "Czech" },
|
|
2684
|
+
{ code: "tr", name: "Turkish" },
|
|
2685
|
+
{ code: "ru", name: "Russian" },
|
|
2686
|
+
{ code: "uk", name: "Ukrainian" },
|
|
2687
|
+
{ code: "ar", name: "Arabic" },
|
|
2688
|
+
{ code: "he", name: "Hebrew" },
|
|
2689
|
+
{ code: "hi", name: "Hindi" },
|
|
2690
|
+
{ code: "ja", name: "Japanese" },
|
|
2691
|
+
{ code: "ko", name: "Korean" },
|
|
2692
|
+
{ code: "zh-Hans", name: "Chinese (Simplified)" },
|
|
2693
|
+
{ code: "zh-Hant", name: "Chinese (Traditional)" },
|
|
2694
|
+
{ code: "id", name: "Indonesian" },
|
|
2695
|
+
{ code: "th", name: "Thai" },
|
|
2696
|
+
{ code: "vi", name: "Vietnamese" }
|
|
2697
|
+
];
|
|
2698
|
+
function localeName(code) {
|
|
2699
|
+
const exact = COMMON_LOCALES.find((l) => l.code.toLowerCase() === code.toLowerCase());
|
|
2700
|
+
if (exact) return exact.name;
|
|
2701
|
+
const base = COMMON_LOCALES.find((l) => l.code.toLowerCase() === baseLanguage(code));
|
|
2702
|
+
return base ? `${base.name} (${code})` : code;
|
|
2703
|
+
}
|
|
2704
|
+
function normalizeLocale(input) {
|
|
2705
|
+
if (typeof input !== "string") return "";
|
|
2706
|
+
const parts = input.trim().replace(/_/g, "-").split("-").filter(Boolean);
|
|
2707
|
+
if (!parts.length || !/^[a-zA-Z]{2,3}$/.test(parts[0])) return "";
|
|
2708
|
+
return parts.slice(0, 3).map((p, i) => i === 0 ? p.toLowerCase() : p.length === 4 ? p[0].toUpperCase() + p.slice(1).toLowerCase() : p.length === 2 ? p.toUpperCase() : p).join("-");
|
|
2709
|
+
}
|
|
2710
|
+
function baseLanguage(locale) {
|
|
2711
|
+
return normalizeLocale(locale).split("-")[0] ?? "";
|
|
2712
|
+
}
|
|
2713
|
+
function resolveLocale(requested, available, defaultLocale = DEFAULT_LOCALE) {
|
|
2714
|
+
const def = normalizeLocale(defaultLocale) || DEFAULT_LOCALE;
|
|
2715
|
+
const avail = available.map(normalizeLocale).filter(Boolean);
|
|
2716
|
+
const all = [def, ...avail.filter((a) => a.toLowerCase() !== def.toLowerCase())];
|
|
2717
|
+
for (const raw of requested) {
|
|
2718
|
+
const want = normalizeLocale(raw);
|
|
2719
|
+
if (!want) continue;
|
|
2720
|
+
const exact = all.find((a) => a.toLowerCase() === want.toLowerCase());
|
|
2721
|
+
if (exact) return exact;
|
|
2722
|
+
const base = baseLanguage(want);
|
|
2723
|
+
const sameBase = all.find((a) => a.toLowerCase() === base) ?? all.find((a) => baseLanguage(a) === base);
|
|
2724
|
+
if (sameBase) return sameBase;
|
|
2725
|
+
}
|
|
2726
|
+
return def;
|
|
2727
|
+
}
|
|
2728
|
+
function visitorLocales(explicit, traits, platform = []) {
|
|
2729
|
+
const out = [];
|
|
2730
|
+
const push = (v) => {
|
|
2731
|
+
const n = normalizeLocale(v);
|
|
2732
|
+
if (n && !out.includes(n)) out.push(n);
|
|
2733
|
+
};
|
|
2734
|
+
push(explicit);
|
|
2735
|
+
push(traits?.language);
|
|
2736
|
+
push(traits?.locale);
|
|
2737
|
+
for (const p of platform) push(p);
|
|
2738
|
+
return out;
|
|
2739
|
+
}
|
|
2740
|
+
function guideTextEntries(config) {
|
|
2741
|
+
const out = [];
|
|
2742
|
+
const add = (key, source, kind, label) => {
|
|
2743
|
+
if (source && source.trim()) out.push({ key, source, kind, label });
|
|
2744
|
+
};
|
|
2745
|
+
config.steps.forEach((s, i) => {
|
|
2746
|
+
const at = `Step ${i + 1}`;
|
|
2747
|
+
add(`steps.${s.id}.title`, s.title, "text", `${at} \xB7 Title`);
|
|
2748
|
+
add(`steps.${s.id}.body`, s.body, "html", `${at} \xB7 Body`);
|
|
2749
|
+
add(`steps.${s.id}.customHtml`, s.customHtml, "html", `${at} \xB7 Custom HTML`);
|
|
2750
|
+
add(`steps.${s.id}.imageAlt`, s.imageAlt, "text", `${at} \xB7 Image description`);
|
|
2751
|
+
s.buttons.forEach((b) => add(`steps.${s.id}.buttons.${b.id}.label`, b.label, "text", `${at} \xB7 Button \u201C${b.label}\u201D`));
|
|
2752
|
+
});
|
|
2753
|
+
const c = config.checklist;
|
|
2754
|
+
if (c) {
|
|
2755
|
+
add("checklist.launcherLabel", c.launcherLabel, "text", "Checklist \xB7 Launcher label");
|
|
2756
|
+
add("checklist.completionTitle", c.completionTitle, "text", "Checklist \xB7 Completion title");
|
|
2757
|
+
add("checklist.completionBody", c.completionBody, "html", "Checklist \xB7 Completion message");
|
|
2758
|
+
c.tasks.forEach((t, i) => {
|
|
2759
|
+
add(`checklist.tasks.${t.id}.title`, t.title, "text", `Task ${i + 1} \xB7 Title`);
|
|
2760
|
+
add(`checklist.tasks.${t.id}.description`, t.description, "html", `Task ${i + 1} \xB7 Description`);
|
|
2761
|
+
});
|
|
2762
|
+
}
|
|
2763
|
+
const sv = config.survey;
|
|
2764
|
+
if (sv) {
|
|
2765
|
+
sv.questions.forEach((q, i) => {
|
|
2766
|
+
const at = `Question ${i + 1}`;
|
|
2767
|
+
add(`survey.questions.${q.id}.title`, q.title, "text", `${at} \xB7 Question`);
|
|
2768
|
+
add(`survey.questions.${q.id}.description`, q.description, "text", `${at} \xB7 Description`);
|
|
2769
|
+
add(`survey.questions.${q.id}.placeholder`, q.placeholder, "text", `${at} \xB7 Placeholder`);
|
|
2770
|
+
add(`survey.questions.${q.id}.lowLabel`, q.lowLabel, "text", `${at} \xB7 Low label`);
|
|
2771
|
+
add(`survey.questions.${q.id}.highLabel`, q.highLabel, "text", `${at} \xB7 High label`);
|
|
2772
|
+
q.options.forEach((o) => add(`survey.questions.${q.id}.options.${o.id}.label`, o.label, "text", `${at} \xB7 Option \u201C${o.label}\u201D`));
|
|
2773
|
+
});
|
|
2774
|
+
add("survey.thankYouTitle", sv.thankYouTitle, "text", "Survey \xB7 Thank-you title");
|
|
2775
|
+
add("survey.thankYouBody", sv.thankYouBody, "html", "Survey \xB7 Thank-you message");
|
|
2776
|
+
}
|
|
2777
|
+
return out;
|
|
2778
|
+
}
|
|
2779
|
+
function guideLocales(config) {
|
|
2780
|
+
const t = config.localization?.translations ?? {};
|
|
2781
|
+
return Object.keys(t).filter((l) => Object.values(t[l] ?? {}).some((v) => typeof v === "string" && v.trim() !== ""));
|
|
2782
|
+
}
|
|
2783
|
+
function pick(map, key, fallback) {
|
|
2784
|
+
const v = map?.[key];
|
|
2785
|
+
return typeof v === "string" && v.trim() !== "" ? v : fallback;
|
|
2786
|
+
}
|
|
2787
|
+
function applyGuideTranslations(config, map) {
|
|
2788
|
+
if (!map || !Object.keys(map).length) return config;
|
|
2789
|
+
return {
|
|
2790
|
+
...config,
|
|
2791
|
+
steps: config.steps.map((s) => ({
|
|
2792
|
+
...s,
|
|
2793
|
+
title: pick(map, `steps.${s.id}.title`, s.title),
|
|
2794
|
+
body: pick(map, `steps.${s.id}.body`, s.body),
|
|
2795
|
+
customHtml: pick(map, `steps.${s.id}.customHtml`, s.customHtml),
|
|
2796
|
+
imageAlt: pick(map, `steps.${s.id}.imageAlt`, s.imageAlt),
|
|
2797
|
+
buttons: s.buttons.map((b) => ({ ...b, label: pick(map, `steps.${s.id}.buttons.${b.id}.label`, b.label) }))
|
|
2798
|
+
})),
|
|
2799
|
+
checklist: config.checklist ? {
|
|
2800
|
+
...config.checklist,
|
|
2801
|
+
launcherLabel: pick(map, "checklist.launcherLabel", config.checklist.launcherLabel),
|
|
2802
|
+
completionTitle: pick(map, "checklist.completionTitle", config.checklist.completionTitle),
|
|
2803
|
+
completionBody: pick(map, "checklist.completionBody", config.checklist.completionBody),
|
|
2804
|
+
tasks: config.checklist.tasks.map((t) => ({ ...t, title: pick(map, `checklist.tasks.${t.id}.title`, t.title), description: pick(map, `checklist.tasks.${t.id}.description`, t.description) }))
|
|
2805
|
+
} : config.checklist,
|
|
2806
|
+
survey: config.survey ? {
|
|
2807
|
+
...config.survey,
|
|
2808
|
+
thankYouTitle: pick(map, "survey.thankYouTitle", config.survey.thankYouTitle),
|
|
2809
|
+
thankYouBody: pick(map, "survey.thankYouBody", config.survey.thankYouBody),
|
|
2810
|
+
questions: config.survey.questions.map((q) => ({
|
|
2811
|
+
...q,
|
|
2812
|
+
title: pick(map, `survey.questions.${q.id}.title`, q.title),
|
|
2813
|
+
description: pick(map, `survey.questions.${q.id}.description`, q.description),
|
|
2814
|
+
placeholder: pick(map, `survey.questions.${q.id}.placeholder`, q.placeholder),
|
|
2815
|
+
lowLabel: pick(map, `survey.questions.${q.id}.lowLabel`, q.lowLabel),
|
|
2816
|
+
highLabel: pick(map, `survey.questions.${q.id}.highLabel`, q.highLabel),
|
|
2817
|
+
options: q.options.map((o) => ({ ...o, label: pick(map, `survey.questions.${q.id}.options.${o.id}.label`, o.label) }))
|
|
2818
|
+
}))
|
|
2819
|
+
} : config.survey
|
|
2820
|
+
};
|
|
2821
|
+
}
|
|
2822
|
+
function localizeGuide(guide, requested, defaultLocale = DEFAULT_LOCALE) {
|
|
2823
|
+
const translations = guide.config.localization?.translations ?? {};
|
|
2824
|
+
const locale = resolveLocale(requested, guideLocales(guide.config), defaultLocale);
|
|
2825
|
+
const key = Object.keys(translations).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());
|
|
2826
|
+
if (!key) return { ...guide, locale };
|
|
2827
|
+
return { ...guide, locale, config: applyGuideTranslations(guide.config, translations[key]) };
|
|
2828
|
+
}
|
|
2829
|
+
function translationCoverage(entries, map, locale) {
|
|
2830
|
+
const keys = new Set(entries.map((e) => e.key));
|
|
2831
|
+
const missing = entries.filter((e) => !pick(map, e.key, void 0)).map((e) => e.key);
|
|
2832
|
+
const stale = Object.keys(map ?? {}).filter((k) => !keys.has(k) && (map?.[k] ?? "").trim() !== "");
|
|
2833
|
+
return { locale, total: entries.length, translated: entries.length - missing.length, missing, stale };
|
|
2834
|
+
}
|
|
2835
|
+
function resourceCenterTextEntries(rc) {
|
|
2836
|
+
const out = [];
|
|
2837
|
+
const add = (key, source, kind, label) => {
|
|
2838
|
+
if (source && source.trim()) out.push({ key, source, kind, label });
|
|
2839
|
+
};
|
|
2840
|
+
add("title", rc.title, "text", "Title");
|
|
2841
|
+
add("launcher.label", rc.launcher?.label, "text", "Launcher label");
|
|
2842
|
+
rc.collections.forEach((c) => {
|
|
2843
|
+
add(`collections.${c.id}.name`, c.name, "text", `Collection \u201C${c.name}\u201D`);
|
|
2844
|
+
add(`collections.${c.id}.description`, c.description, "text", `Collection \u201C${c.name}\u201D \xB7 Description`);
|
|
2845
|
+
});
|
|
2846
|
+
rc.links.forEach((l) => add(`links.${l.id}.label`, l.label, "text", `Link \u201C${l.label}\u201D`));
|
|
2847
|
+
rc.faqs.forEach((f, i) => {
|
|
2848
|
+
add(`faqs.${f.id}.question`, f.question, "text", `FAQ ${i + 1} \xB7 Question`);
|
|
2849
|
+
add(`faqs.${f.id}.answer`, f.answer, "html", `FAQ ${i + 1} \xB7 Answer`);
|
|
2850
|
+
});
|
|
2851
|
+
return out;
|
|
2852
|
+
}
|
|
2853
|
+
function articleTextEntries(a) {
|
|
2854
|
+
const out = [];
|
|
2855
|
+
if (a.title.trim()) out.push({ key: "title", source: a.title, kind: "text", label: "Title" });
|
|
2856
|
+
if (a.summary?.trim()) out.push({ key: "summary", source: a.summary, kind: "text", label: "Summary" });
|
|
2857
|
+
if (a.body?.trim()) out.push({ key: "body", source: a.body, kind: "html", label: "Body" });
|
|
2858
|
+
return out;
|
|
2859
|
+
}
|
|
2860
|
+
function resourceCenterLocales(rc) {
|
|
2861
|
+
const set = new Set(Object.keys(rc.translations ?? {}));
|
|
2862
|
+
for (const a of rc.articles) for (const l of Object.keys(a.translations ?? {})) set.add(l);
|
|
2863
|
+
for (const a of rc.announcements ?? []) for (const l of Object.keys(a.translations ?? {})) set.add(l);
|
|
2864
|
+
return [...set];
|
|
2865
|
+
}
|
|
2866
|
+
function translationFor(map, locale) {
|
|
2867
|
+
if (!map) return void 0;
|
|
2868
|
+
const key = Object.keys(map).find((l) => normalizeLocale(l).toLowerCase() === locale.toLowerCase());
|
|
2869
|
+
return key ? map[key] : void 0;
|
|
2870
|
+
}
|
|
2871
|
+
function localizeArticle(a, locale) {
|
|
2872
|
+
const t = translationFor(a.translations, locale);
|
|
2873
|
+
if (!t) return a;
|
|
2874
|
+
const body = t.body?.trim() ? t.body : a.body;
|
|
2875
|
+
return { ...a, title: t.title?.trim() ? t.title : a.title, summary: t.summary?.trim() ? t.summary : a.summary, body, ...t.bodyOmitted ? { bodyOmitted: true } : {} };
|
|
2876
|
+
}
|
|
2877
|
+
function localizeAnnouncement(a, locale) {
|
|
2878
|
+
const t = translationFor(a.translations, locale);
|
|
2879
|
+
if (!t) return a;
|
|
2880
|
+
return { ...a, title: t.title?.trim() ? t.title : a.title, body: t.body?.trim() ? t.body : a.body };
|
|
2881
|
+
}
|
|
2882
|
+
function localizeResourceCenter(rc, requested, defaultLocale = DEFAULT_LOCALE) {
|
|
2883
|
+
const locale = resolveLocale(requested, resourceCenterLocales(rc), defaultLocale);
|
|
2884
|
+
if (locale.toLowerCase() === normalizeLocale(defaultLocale).toLowerCase()) return { ...rc, locale };
|
|
2885
|
+
const map = translationFor(rc.translations, locale);
|
|
2886
|
+
return {
|
|
2887
|
+
...rc,
|
|
2888
|
+
locale,
|
|
2889
|
+
title: pick(map, "title", rc.title),
|
|
2890
|
+
launcher: { ...rc.launcher, label: pick(map, "launcher.label", rc.launcher.label) },
|
|
2891
|
+
collections: rc.collections.map((c) => ({ ...c, name: pick(map, `collections.${c.id}.name`, c.name), description: pick(map, `collections.${c.id}.description`, c.description) })),
|
|
2892
|
+
links: rc.links.map((l) => ({ ...l, label: pick(map, `links.${l.id}.label`, l.label) })),
|
|
2893
|
+
faqs: rc.faqs.map((f) => ({ ...f, question: pick(map, `faqs.${f.id}.question`, f.question), answer: pick(map, `faqs.${f.id}.answer`, f.answer) })),
|
|
2894
|
+
articles: rc.articles.map((a) => localizeArticle(a, locale)),
|
|
2895
|
+
announcements: rc.announcements?.map((a) => localizeAnnouncement(a, locale))
|
|
2896
|
+
};
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
// src/guide-experiments.ts
|
|
2900
|
+
var CONTROL_VARIANT_ID = "control";
|
|
2901
|
+
var GUIDE_EXPERIMENT_STATUSES = ["draft", "running", "completed"];
|
|
2902
|
+
var GUIDE_EXPERIMENT_GOALS = ["guide_completed", "event", "page_visit", "click_text"];
|
|
2903
|
+
var GUIDE_EXPERIMENT_GOAL_LABELS = {
|
|
2904
|
+
guide_completed: "Completes the guide",
|
|
2905
|
+
event: "Tracks an event",
|
|
2906
|
+
page_visit: "Visits a page",
|
|
2907
|
+
click_text: "Clicks an element with text"
|
|
2908
|
+
};
|
|
2909
|
+
function experimentSalt(experimentId) {
|
|
2910
|
+
return `gx:${experimentId}`;
|
|
2911
|
+
}
|
|
2912
|
+
function variantRanges(variants) {
|
|
2913
|
+
let at = 0;
|
|
2914
|
+
return variants.map((v) => {
|
|
2915
|
+
const from = at;
|
|
2916
|
+
at = Math.min(100, at + Math.max(0, Math.round(v.weight)));
|
|
2917
|
+
return { id: v.id, from, to: at };
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
function assignGuideVariant(variants, experimentId, subject) {
|
|
2921
|
+
const bucket = rolloutBucket(subject, experimentSalt(experimentId));
|
|
2922
|
+
return variantRanges(variants).find((r) => bucket >= r.from && bucket < r.to)?.id ?? null;
|
|
2923
|
+
}
|
|
2924
|
+
function experimentBucketRules(salt, from, to) {
|
|
2925
|
+
return [
|
|
2926
|
+
{ id: "experiment-from", field: "experiment.bucket", key: salt, op: "gte", value: from },
|
|
2927
|
+
{ id: "experiment-to", field: "experiment.bucket", key: salt, op: "lt", value: to }
|
|
2928
|
+
];
|
|
2929
|
+
}
|
|
2930
|
+
function withExperimentBucket(targeting, salt, from, to) {
|
|
2931
|
+
return { id: "experiment", op: "and", rules: [...experimentBucketRules(salt, from, to), targeting] };
|
|
2932
|
+
}
|
|
2933
|
+
function variantProblems(variants) {
|
|
2934
|
+
const problems = [];
|
|
2935
|
+
if (variants.length < 2) problems.push("An A/B test needs at least two variants.");
|
|
2936
|
+
if (variants.length > 5) problems.push("An A/B test can have at most five variants.");
|
|
2937
|
+
const guides = variants.filter((v) => v.guideId);
|
|
2938
|
+
if (guides.length === 0) problems.push("At least one variant must show a guide.");
|
|
2939
|
+
if (variants.filter((v) => !v.guideId).length > 1) problems.push("Only one variant can be the control group (no guide).");
|
|
2940
|
+
if (new Set(guides.map((v) => v.guideId)).size !== guides.length) problems.push("Each variant needs its own guide.");
|
|
2941
|
+
if (new Set(variants.map((v) => v.id)).size !== variants.length) problems.push("Variant ids must be unique.");
|
|
2942
|
+
if (variants.some((v) => !Number.isInteger(v.weight) || v.weight < 1)) problems.push("Every variant needs a whole-number share of at least 1%.");
|
|
2943
|
+
const total = variants.reduce((s, v) => s + v.weight, 0);
|
|
2944
|
+
if (total !== 100) problems.push(`Traffic shares must add up to 100% (now ${total}%).`);
|
|
2945
|
+
return problems;
|
|
2946
|
+
}
|
|
2947
|
+
function evenWeights(n) {
|
|
2948
|
+
if (n <= 0) return [];
|
|
2949
|
+
const base = Math.floor(100 / n);
|
|
2950
|
+
return Array.from({ length: n }, (_, i) => base + (i < 100 - base * n ? 1 : 0));
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
// src/custom-css.ts
|
|
2954
|
+
var MAX_CUSTOM_CSS = 2e4;
|
|
2955
|
+
var BLOCKED_AT_RULES = /^@(import|charset|namespace|document|-moz-document)\b/i;
|
|
2956
|
+
var ALLOWED_AT_RULES = /^@(media|supports|container|layer|keyframes|-webkit-keyframes|font-face)\b/i;
|
|
2957
|
+
function splitBlocks(css) {
|
|
2958
|
+
const out = [];
|
|
2959
|
+
let i = 0;
|
|
2960
|
+
const n = css.length;
|
|
2961
|
+
while (i < n) {
|
|
2962
|
+
let prelude = "";
|
|
2963
|
+
let quote = null;
|
|
2964
|
+
while (i < n) {
|
|
2965
|
+
const ch = css[i];
|
|
2966
|
+
if (quote) {
|
|
2967
|
+
prelude += ch;
|
|
2968
|
+
if (ch === "\\") prelude += css[++i] ?? "";
|
|
2969
|
+
else if (ch === quote) quote = null;
|
|
2970
|
+
} else if (ch === '"' || ch === "'") {
|
|
2971
|
+
quote = ch;
|
|
2972
|
+
prelude += ch;
|
|
2973
|
+
} else if (ch === "{") break;
|
|
2974
|
+
else if (ch === ";") {
|
|
2975
|
+
prelude = "";
|
|
2976
|
+
} else if (ch === "}") {
|
|
2977
|
+
prelude = "";
|
|
2978
|
+
} else prelude += ch;
|
|
2979
|
+
i++;
|
|
2980
|
+
}
|
|
2981
|
+
if (i >= n) break;
|
|
2982
|
+
i++;
|
|
2983
|
+
let depth = 1;
|
|
2984
|
+
let body = "";
|
|
2985
|
+
quote = null;
|
|
2986
|
+
while (i < n && depth > 0) {
|
|
2987
|
+
const ch = css[i];
|
|
2988
|
+
if (quote) {
|
|
2989
|
+
body += ch;
|
|
2990
|
+
if (ch === "\\") body += css[++i] ?? "";
|
|
2991
|
+
else if (ch === quote) quote = null;
|
|
2992
|
+
} else if (ch === '"' || ch === "'") {
|
|
2993
|
+
quote = ch;
|
|
2994
|
+
body += ch;
|
|
2995
|
+
} else if (ch === "{") {
|
|
2996
|
+
depth++;
|
|
2997
|
+
body += ch;
|
|
2998
|
+
} else if (ch === "}") {
|
|
2999
|
+
depth--;
|
|
3000
|
+
if (depth > 0) body += ch;
|
|
3001
|
+
} else body += ch;
|
|
3002
|
+
i++;
|
|
3003
|
+
}
|
|
3004
|
+
out.push({ prelude: prelude.trim(), body });
|
|
3005
|
+
}
|
|
3006
|
+
return out;
|
|
3007
|
+
}
|
|
3008
|
+
function splitSelectors(list) {
|
|
3009
|
+
const out = [];
|
|
3010
|
+
let depth = 0;
|
|
3011
|
+
let cur = "";
|
|
3012
|
+
for (const ch of list) {
|
|
3013
|
+
if (ch === "(" || ch === "[") depth++;
|
|
3014
|
+
else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
|
|
3015
|
+
if (ch === "," && depth === 0) {
|
|
3016
|
+
out.push(cur.trim());
|
|
3017
|
+
cur = "";
|
|
3018
|
+
} else cur += ch;
|
|
3019
|
+
}
|
|
3020
|
+
if (cur.trim()) out.push(cur.trim());
|
|
3021
|
+
return out;
|
|
3022
|
+
}
|
|
3023
|
+
function safeUrl(raw) {
|
|
3024
|
+
const u = raw.trim().replace(/^['"]|['"]$/g, "").trim();
|
|
3025
|
+
return /^https:\/\//i.test(u) || /^data:image\/(png|jpe?g|gif|webp|svg\+xml)[;,]/i.test(u);
|
|
3026
|
+
}
|
|
3027
|
+
function cleanDeclarations(body) {
|
|
3028
|
+
return body.replace(/url\(([^)]*)\)/gi, (m, inner) => safeUrl(inner) ? m : "none").replace(/expression\s*\(/gi, "(").replace(/javascript\s*:/gi, "").replace(/(^|[;{\s])(-moz-binding|behavior)\s*:[^;]*;?/gi, "$1").replace(/[{}]/g, "").trim();
|
|
3029
|
+
}
|
|
3030
|
+
function sanitizeCustomCss(input) {
|
|
3031
|
+
if (!input) return "";
|
|
3032
|
+
let css = String(input).slice(0, MAX_CUSTOM_CSS);
|
|
3033
|
+
css = css.replace(/\/\*[\s\S]*?\*\//g, "").replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1\s*>/gi, "").replace(/<\/?[a-z!][^>]*>/gi, "").replace(/</g, "");
|
|
3034
|
+
return render(splitBlocks(css), 0);
|
|
3035
|
+
}
|
|
3036
|
+
function render(blocks, depth) {
|
|
3037
|
+
const parts = [];
|
|
3038
|
+
for (const b of blocks) {
|
|
3039
|
+
if (!b.prelude) continue;
|
|
3040
|
+
if (b.prelude.startsWith("@")) {
|
|
3041
|
+
if (BLOCKED_AT_RULES.test(b.prelude) || !ALLOWED_AT_RULES.test(b.prelude)) continue;
|
|
3042
|
+
if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) {
|
|
3043
|
+
const inner = /^@font-face/i.test(b.prelude) ? cleanDeclarations(b.body) : splitBlocks(b.body).map((k) => `${k.prelude}{${cleanDeclarations(k.body)}}`).join("");
|
|
3044
|
+
parts.push(`${b.prelude}{${inner}}`);
|
|
3045
|
+
} else if (depth < 3) parts.push(`${b.prelude}{${render(splitBlocks(b.body), depth + 1)}}`);
|
|
3046
|
+
continue;
|
|
3047
|
+
}
|
|
3048
|
+
const selectors = splitSelectors(b.prelude).filter((s) => !/:host|::slotted|::part/i.test(s));
|
|
3049
|
+
if (!selectors.length) continue;
|
|
3050
|
+
parts.push(`${selectors.join(",")}{${cleanDeclarations(b.body)}}`);
|
|
3051
|
+
}
|
|
3052
|
+
return parts.join("\n");
|
|
3053
|
+
}
|
|
3054
|
+
function scopeCustomCss(css, scope) {
|
|
3055
|
+
return scopeBlocks(splitBlocks(sanitizeCustomCss(css)), scope, 0);
|
|
3056
|
+
}
|
|
3057
|
+
function scopeBlocks(blocks, scope, depth) {
|
|
3058
|
+
const parts = [];
|
|
3059
|
+
for (const b of blocks) {
|
|
3060
|
+
if (b.prelude.startsWith("@")) {
|
|
3061
|
+
if (/^@(-webkit-)?keyframes|^@font-face/i.test(b.prelude)) parts.push(`${b.prelude}{${b.body}}`);
|
|
3062
|
+
else if (depth < 3) parts.push(`${b.prelude}{${scopeBlocks(splitBlocks(b.body), scope, depth + 1)}}`);
|
|
3063
|
+
continue;
|
|
3064
|
+
}
|
|
3065
|
+
const sels = splitSelectors(b.prelude).map((s) => {
|
|
3066
|
+
const self = s.match(/^(:root|html|body|:scope|&)(?![\w-])(.*)$/i);
|
|
3067
|
+
if (self) return `${scope}${self[2] ?? ""}`;
|
|
3068
|
+
return `${scope} ${s}`;
|
|
3069
|
+
});
|
|
3070
|
+
parts.push(`${sels.join(",")}{${b.body}}`);
|
|
3071
|
+
}
|
|
3072
|
+
return parts.join("\n");
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
// src/translation-files.ts
|
|
3076
|
+
function xmlEscape(s) {
|
|
3077
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
3078
|
+
}
|
|
3079
|
+
function xmlUnescape(s) {
|
|
3080
|
+
return s.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, (_, c) => c.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")).replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d))).replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(parseInt(h, 16))).replace(/&/g, "&");
|
|
3081
|
+
}
|
|
3082
|
+
function toXliff(units, opts) {
|
|
3083
|
+
const body = units.map(
|
|
3084
|
+
(u) => ` <trans-unit id="${xmlEscape(u.key)}">
|
|
3085
|
+
<source>${xmlEscape(u.source)}</source>
|
|
3086
|
+
<target${u.target ? "" : ' state="needs-translation"'}>${xmlEscape(u.target)}</target>${u.note ? `
|
|
3087
|
+
<note>${xmlEscape(u.note)}</note>` : ""}
|
|
3088
|
+
</trans-unit>`
|
|
3089
|
+
).join("\n");
|
|
3090
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
3091
|
+
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
|
3092
|
+
<file original="${xmlEscape(opts.original)}" source-language="${xmlEscape(opts.sourceLocale)}" target-language="${xmlEscape(opts.targetLocale)}" datatype="html">
|
|
3093
|
+
<body>
|
|
3094
|
+
${body}
|
|
3095
|
+
</body>
|
|
3096
|
+
</file>
|
|
3097
|
+
</xliff>
|
|
3098
|
+
`;
|
|
3099
|
+
}
|
|
3100
|
+
function parseXliff(xml) {
|
|
3101
|
+
const target = xml.match(/target-language="([^"]+)"/)?.[1] ?? xml.match(/\btrgLang="([^"]+)"/)?.[1];
|
|
3102
|
+
const entries = {};
|
|
3103
|
+
for (const m of xml.matchAll(/<(trans-unit|unit)\b[^>]*\bid="([^"]*)"[^>]*>([\s\S]*?)<\/\1>/g)) {
|
|
3104
|
+
const key = xmlUnescape(m[2]);
|
|
3105
|
+
const t = m[3].match(/<target\b[^>]*>([\s\S]*?)<\/target>/);
|
|
3106
|
+
const text = t ? xmlUnescape(t[1]) : "";
|
|
3107
|
+
if (key && text.trim()) entries[key] = text;
|
|
3108
|
+
}
|
|
3109
|
+
return { targetLocale: target ? xmlUnescape(target) : void 0, entries };
|
|
3110
|
+
}
|
|
3111
|
+
function csvCell(s) {
|
|
3112
|
+
return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
3113
|
+
}
|
|
3114
|
+
function toTranslationCsv(units, targetLocale) {
|
|
3115
|
+
const rows = [["key", "context", "source", targetLocale], ...units.map((u) => [u.key, u.note ?? "", u.source, u.target])];
|
|
3116
|
+
return rows.map((r) => r.map(csvCell).join(",")).join("\r\n") + "\r\n";
|
|
3117
|
+
}
|
|
3118
|
+
function parseCsvRows(text) {
|
|
3119
|
+
const rows = [];
|
|
3120
|
+
let row = [];
|
|
3121
|
+
let cell = "";
|
|
3122
|
+
let quoted2 = false;
|
|
3123
|
+
const src = text.replace(/^\uFEFF/, "");
|
|
3124
|
+
for (let i = 0; i < src.length; i++) {
|
|
3125
|
+
const ch = src[i];
|
|
3126
|
+
if (quoted2) {
|
|
3127
|
+
if (ch === '"') {
|
|
3128
|
+
if (src[i + 1] === '"') {
|
|
3129
|
+
cell += '"';
|
|
3130
|
+
i++;
|
|
3131
|
+
} else quoted2 = false;
|
|
3132
|
+
} else cell += ch;
|
|
3133
|
+
} else if (ch === '"') quoted2 = true;
|
|
3134
|
+
else if (ch === ",") {
|
|
3135
|
+
row.push(cell);
|
|
3136
|
+
cell = "";
|
|
3137
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
3138
|
+
if (ch === "\r" && src[i + 1] === "\n") i++;
|
|
3139
|
+
row.push(cell);
|
|
3140
|
+
rows.push(row);
|
|
3141
|
+
row = [];
|
|
3142
|
+
cell = "";
|
|
3143
|
+
} else cell += ch;
|
|
3144
|
+
}
|
|
3145
|
+
if (cell !== "" || row.length) {
|
|
3146
|
+
row.push(cell);
|
|
3147
|
+
rows.push(row);
|
|
3148
|
+
}
|
|
3149
|
+
return rows.filter((r) => r.some((c) => c.trim() !== ""));
|
|
3150
|
+
}
|
|
3151
|
+
function parseTranslationCsv(text) {
|
|
3152
|
+
const [header, ...rows] = parseCsvRows(text);
|
|
3153
|
+
if (!header) return { entries: {} };
|
|
3154
|
+
const names = header.map((h) => h.trim());
|
|
3155
|
+
const lower = names.map((h) => h.toLowerCase());
|
|
3156
|
+
const keyCol = lower.indexOf("key");
|
|
3157
|
+
if (keyCol < 0) return { entries: {} };
|
|
3158
|
+
let targetCol = lower.indexOf("target");
|
|
3159
|
+
if (targetCol < 0) {
|
|
3160
|
+
for (let i = names.length - 1; i >= 0; i--) {
|
|
3161
|
+
if (!["key", "context", "source", "label", "note"].includes(lower[i])) {
|
|
3162
|
+
targetCol = i;
|
|
3163
|
+
break;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
if (targetCol < 0) return { entries: {} };
|
|
3168
|
+
const entries = {};
|
|
3169
|
+
for (const r of rows) {
|
|
3170
|
+
const key = (r[keyCol] ?? "").trim();
|
|
3171
|
+
const value = r[targetCol] ?? "";
|
|
3172
|
+
if (key && value.trim()) entries[key] = value;
|
|
3173
|
+
}
|
|
3174
|
+
return { targetLocale: lower[targetCol] === "target" ? void 0 : names[targetCol], entries };
|
|
3175
|
+
}
|
|
3176
|
+
|
|
1695
3177
|
// src/index.ts
|
|
1696
3178
|
var SDK_API_VERSION = "v1";
|
|
1697
|
-
var SHARED_VERSION = "0.
|
|
3179
|
+
var SHARED_VERSION = "0.11.0";
|
|
1698
3180
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1699
3181
|
0 && (module.exports = {
|
|
1700
3182
|
ADVANCE_ON,
|
|
3183
|
+
AGENT_METADATA_MAX_BYTES,
|
|
3184
|
+
AGENT_METADATA_MAX_KEYS,
|
|
3185
|
+
AGENT_OUTCOMES,
|
|
3186
|
+
AGENT_TOOL_CALLS_PER_TURN,
|
|
3187
|
+
AGENT_TOOL_STATUSES,
|
|
3188
|
+
AGENT_TURNS_PER_BATCH,
|
|
3189
|
+
AGENT_TURN_MAX_TEXT,
|
|
3190
|
+
AGENT_TURN_ROLES,
|
|
1701
3191
|
ANNOTATION_COLORS,
|
|
3192
|
+
APP_LIFECYCLE_EVENTS,
|
|
1702
3193
|
ARTICLE_VISIBILITIES,
|
|
1703
3194
|
AUTOCAPTURE_EVENTS,
|
|
3195
|
+
AgentEventsRequestSchema,
|
|
3196
|
+
AgentMetadataSchema,
|
|
3197
|
+
AgentToolCallSchema,
|
|
3198
|
+
AgentTurnInputSchema,
|
|
1704
3199
|
AppearanceSchema,
|
|
1705
3200
|
AuthoringPickSchema,
|
|
1706
3201
|
AutocaptureSettingsSchema,
|
|
@@ -1708,9 +3203,11 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1708
3203
|
ButtonSchema,
|
|
1709
3204
|
CAPTURE_PARAM,
|
|
1710
3205
|
CAPTURE_SCREENSHOT_MAX_BYTES,
|
|
3206
|
+
COMMON_LOCALES,
|
|
1711
3207
|
COMPLAINT_EVENTS,
|
|
1712
3208
|
COMPLAINT_FIELD_TYPES,
|
|
1713
3209
|
COMPLAINT_STATUSES,
|
|
3210
|
+
CONTROL_VARIANT_ID,
|
|
1714
3211
|
CaptureStepSchema,
|
|
1715
3212
|
CapturedElementSchema,
|
|
1716
3213
|
ChecklistConfigSchema,
|
|
@@ -1719,28 +3216,54 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1719
3216
|
ConversationLookupSchema,
|
|
1720
3217
|
ConversationRatingSchema,
|
|
1721
3218
|
DEFAULT_CAPTURE_SETTINGS,
|
|
3219
|
+
DEFAULT_FEATURE_ATTRIBUTE,
|
|
3220
|
+
DEFAULT_LOCALE,
|
|
1722
3221
|
DEFAULT_PLATFORMS,
|
|
1723
3222
|
EMBED_IFRAME_ATTRS,
|
|
1724
3223
|
EVENT_NAMES,
|
|
1725
3224
|
ErrorTrackingSettingsSchema,
|
|
1726
3225
|
EventBatchSchema,
|
|
3226
|
+
FEATURE_ATTRIBUTE_PATTERN,
|
|
3227
|
+
FEATURE_RULE_LIMITS,
|
|
3228
|
+
FEEDBACK_EVENTS,
|
|
3229
|
+
FEEDBACK_PRIORITIES,
|
|
3230
|
+
FEEDBACK_PRIORITY_LABEL,
|
|
3231
|
+
FEEDBACK_PRIORITY_WEIGHT,
|
|
3232
|
+
FEEDBACK_STATUSES,
|
|
3233
|
+
FEEDBACK_STATUS_LABEL,
|
|
1727
3234
|
FILE_LINK_CLASS,
|
|
3235
|
+
FeedbackCommentSchema,
|
|
3236
|
+
FeedbackFollowSchema,
|
|
3237
|
+
FeedbackListRequestSchema,
|
|
3238
|
+
FeedbackSimilarSchema,
|
|
3239
|
+
FeedbackUpdatesReadSchema,
|
|
3240
|
+
FeedbackVisitorSchema,
|
|
3241
|
+
FeedbackVoteSchema,
|
|
1728
3242
|
FileComplaintSchema,
|
|
1729
3243
|
FrequencySchema,
|
|
1730
3244
|
GUIDELY_ID_ATTRIBUTE,
|
|
3245
|
+
GUIDE_EXPERIMENT_GOALS,
|
|
3246
|
+
GUIDE_EXPERIMENT_GOAL_LABELS,
|
|
3247
|
+
GUIDE_EXPERIMENT_STATUSES,
|
|
1731
3248
|
GUIDE_KINDS,
|
|
1732
3249
|
GUIDE_LIFECYCLE_EVENTS,
|
|
1733
3250
|
GUIDE_STATUSES,
|
|
1734
3251
|
GUIDE_TEMPLATES,
|
|
1735
3252
|
GUIDE_VISIBILITIES,
|
|
1736
3253
|
GuideConfigSchema,
|
|
3254
|
+
GuideLocalizationSchema,
|
|
3255
|
+
GuideScheduleSchema,
|
|
1737
3256
|
GuideStateUpdateSchema,
|
|
3257
|
+
GuideThrottlingSchema,
|
|
1738
3258
|
HEATMAP_VIEWPORTS,
|
|
1739
3259
|
HOWTO_ACTIONS,
|
|
1740
3260
|
HOWTO_STEP_KINDS,
|
|
1741
3261
|
HowToAnnotationSchema,
|
|
1742
3262
|
IdentifyRequestSchema,
|
|
3263
|
+
LOCALE_PATTERN,
|
|
1743
3264
|
LOGGED_IN_AUDIENCE,
|
|
3265
|
+
LocaleSchema,
|
|
3266
|
+
LocalizationSettingsSchema,
|
|
1744
3267
|
MAX_ANNOTATIONS,
|
|
1745
3268
|
MAX_COLLECTION_DEPTH,
|
|
1746
3269
|
MAX_COMPLAINT_ANSWER_LENGTH,
|
|
@@ -1748,6 +3271,11 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1748
3271
|
MAX_COMPLAINT_CHOICES,
|
|
1749
3272
|
MAX_COMPLAINT_FIELDS,
|
|
1750
3273
|
MAX_COMPLAINT_LENGTH,
|
|
3274
|
+
MAX_CUSTOM_CSS,
|
|
3275
|
+
MAX_FEEDBACK_COMMENT,
|
|
3276
|
+
MAX_FEEDBACK_DESCRIPTION,
|
|
3277
|
+
MAX_FEEDBACK_NOTE,
|
|
3278
|
+
MAX_FEEDBACK_TITLE,
|
|
1751
3279
|
MAX_MESSAGE_LENGTH,
|
|
1752
3280
|
MAX_PROPERTY_BYTES,
|
|
1753
3281
|
MAX_STACK_FRAMES,
|
|
@@ -1761,8 +3289,10 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1761
3289
|
MESSAGE_AUTHORS,
|
|
1762
3290
|
MessengerPageRequestSchema,
|
|
1763
3291
|
NETWORK_PLUGIN,
|
|
3292
|
+
NOISY_DATA_ATTR,
|
|
1764
3293
|
NormalizedPointSchema,
|
|
1765
3294
|
NormalizedRectSchema,
|
|
3295
|
+
PAGE_RULE_LIMITS,
|
|
1766
3296
|
PATH_ID_PATTERN,
|
|
1767
3297
|
PDF_BLOCK_CLASS,
|
|
1768
3298
|
PDF_MAX_PAGES,
|
|
@@ -1772,6 +3302,8 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1772
3302
|
PostMessageSchema,
|
|
1773
3303
|
ProjectThemeSchema,
|
|
1774
3304
|
PublishedGuideSchema,
|
|
3305
|
+
RC_MODULE_IDS,
|
|
3306
|
+
RC_MODULE_LABELS,
|
|
1775
3307
|
REPLAY_MAX_COMPRESSED_BYTES,
|
|
1776
3308
|
REPLAY_MAX_RAW_BYTES,
|
|
1777
3309
|
REPLY_TIMES,
|
|
@@ -1781,6 +3313,9 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1781
3313
|
ReplaySettingsSchema,
|
|
1782
3314
|
RuleGroupSchema,
|
|
1783
3315
|
RuleSchema,
|
|
3316
|
+
SCOUT_AGENT_ID,
|
|
3317
|
+
SCRIPT_STUB,
|
|
3318
|
+
SCRIPT_STUB_METHODS,
|
|
1784
3319
|
SDK_API_VERSION,
|
|
1785
3320
|
SELECTOR_KINDS,
|
|
1786
3321
|
SENSITIVE_HEADER_PATTERN,
|
|
@@ -1790,30 +3325,46 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1790
3325
|
SHARED_VERSION,
|
|
1791
3326
|
SHOW_ME_CLASS,
|
|
1792
3327
|
SHOW_ME_HREF_PREFIX,
|
|
3328
|
+
SNAPSHOT_ATTRS,
|
|
3329
|
+
SNAPSHOT_LIMITS,
|
|
1793
3330
|
SOURCEMAP_MAX_FILES_PER_UPLOAD,
|
|
1794
3331
|
SOURCEMAP_MAX_FILE_BYTES,
|
|
1795
3332
|
STATUS_LEVELS,
|
|
1796
3333
|
STEP_TYPES,
|
|
1797
3334
|
SURVEY_QUESTION_TYPES,
|
|
3335
|
+
SdkAgentEventsSchema,
|
|
1798
3336
|
SdkEventSchema,
|
|
1799
3337
|
SelectorStrategySchema,
|
|
3338
|
+
SelectorSyntaxError,
|
|
1800
3339
|
StartConversationSchema,
|
|
1801
3340
|
StepBranchSchema,
|
|
1802
3341
|
StepSchema,
|
|
3342
|
+
SubmitFeedbackSchema,
|
|
1803
3343
|
SurveyConfigSchema,
|
|
1804
3344
|
SurveyQuestionSchema,
|
|
1805
3345
|
SurveyResponseRequestSchema,
|
|
3346
|
+
TAG_PROPERTY_LIMITS,
|
|
1806
3347
|
TRIGGER_TYPES,
|
|
1807
3348
|
TargetSchema,
|
|
1808
3349
|
TriggerSchema,
|
|
1809
3350
|
VIDEO_ATTRS,
|
|
3351
|
+
WCAG_AA_LARGE,
|
|
3352
|
+
WCAG_AA_TEXT,
|
|
1810
3353
|
WS_MAX_MESSAGES_PER_SOCKET,
|
|
1811
3354
|
WS_MAX_MESSAGE_BYTES,
|
|
3355
|
+
applyGuideTranslations,
|
|
3356
|
+
articleTextEntries,
|
|
3357
|
+
assignGuideVariant,
|
|
3358
|
+
baseLanguage,
|
|
1812
3359
|
clamp,
|
|
1813
3360
|
cleanLabel,
|
|
1814
3361
|
compare,
|
|
1815
3362
|
compareVersions,
|
|
1816
3363
|
complaintReference,
|
|
3364
|
+
compoundMatches,
|
|
3365
|
+
contrastIssues,
|
|
3366
|
+
contrastRatio,
|
|
3367
|
+
cssSelectorError,
|
|
1817
3368
|
defaultGuideConfig,
|
|
1818
3369
|
defaultStep,
|
|
1819
3370
|
describeCaptureStep,
|
|
@@ -1821,12 +3372,21 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1821
3372
|
emptyRuleGroup,
|
|
1822
3373
|
evaluateRule,
|
|
1823
3374
|
evaluateRules,
|
|
3375
|
+
evenWeights,
|
|
3376
|
+
experimentBucketRules,
|
|
3377
|
+
experimentSalt,
|
|
3378
|
+
featureCssSelectors,
|
|
3379
|
+
featureRuleError,
|
|
3380
|
+
featureRuleMatchesClick,
|
|
3381
|
+
feedbackReference,
|
|
1824
3382
|
fingerprintError,
|
|
1825
3383
|
firstNameFromTraits,
|
|
1826
3384
|
fnv1a,
|
|
1827
3385
|
foldPathIds,
|
|
1828
3386
|
getPath,
|
|
3387
|
+
guideLocales,
|
|
1829
3388
|
guidePlatforms,
|
|
3389
|
+
guideTextEntries,
|
|
1830
3390
|
guidelyIdFromSelector,
|
|
1831
3391
|
hasVideoMedia,
|
|
1832
3392
|
isAllowedEmbedSrc,
|
|
@@ -1839,6 +3399,12 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1839
3399
|
isRuleGroup,
|
|
1840
3400
|
isSafeMediaUrl,
|
|
1841
3401
|
isVideoContentType,
|
|
3402
|
+
localeName,
|
|
3403
|
+
localizeAnnouncement,
|
|
3404
|
+
localizeArticle,
|
|
3405
|
+
localizeGuide,
|
|
3406
|
+
localizeResourceCenter,
|
|
3407
|
+
matchCssSelector,
|
|
1842
3408
|
matchUrlPattern,
|
|
1843
3409
|
matchesAudiences,
|
|
1844
3410
|
matchesHelpQuery,
|
|
@@ -1846,30 +3412,63 @@ var SHARED_VERSION = "0.9.0";
|
|
|
1846
3412
|
mediaMaxBytes,
|
|
1847
3413
|
normalizeErrorMessage,
|
|
1848
3414
|
normalizeFrameFile,
|
|
3415
|
+
normalizeLocale,
|
|
3416
|
+
normalizeSnapshot,
|
|
3417
|
+
orderedModules,
|
|
1849
3418
|
pageLabel,
|
|
1850
3419
|
pageName,
|
|
3420
|
+
pagePattern,
|
|
3421
|
+
pageRuleError,
|
|
3422
|
+
pageRuleMatches,
|
|
3423
|
+
pageRulesMatch,
|
|
1851
3424
|
pageTerms,
|
|
3425
|
+
parseCssSelector,
|
|
3426
|
+
parseCsvRows,
|
|
3427
|
+
parseHexColor,
|
|
1852
3428
|
parseStack,
|
|
3429
|
+
parseTranslationCsv,
|
|
3430
|
+
parseXliff,
|
|
3431
|
+
propertyAttributeAllowed,
|
|
3432
|
+
queryConditionRegex,
|
|
1853
3433
|
randomId,
|
|
3434
|
+
readableTextOn,
|
|
3435
|
+
relativeLuminance,
|
|
1854
3436
|
resolveCaptureSettings,
|
|
3437
|
+
resolveLocale,
|
|
3438
|
+
resourceCenterLocales,
|
|
1855
3439
|
resourceCenterSections,
|
|
3440
|
+
resourceCenterTextEntries,
|
|
1856
3441
|
rolloutBucket,
|
|
1857
3442
|
safeRegExp,
|
|
3443
|
+
sanitizeCustomCss,
|
|
1858
3444
|
sanitizeProperties,
|
|
3445
|
+
scopeCustomCss,
|
|
1859
3446
|
screenPath,
|
|
3447
|
+
scriptSnippet,
|
|
1860
3448
|
servedArticleAudiences,
|
|
1861
3449
|
showMeHref,
|
|
1862
3450
|
showMeKeyFromHref,
|
|
1863
3451
|
showMeKeys,
|
|
1864
3452
|
slugify,
|
|
3453
|
+
snapshotFromSelector,
|
|
3454
|
+
stableStringify,
|
|
1865
3455
|
stripOrigin,
|
|
1866
3456
|
supportsPlatform,
|
|
1867
3457
|
templateConfig,
|
|
1868
3458
|
toEmbedUrl,
|
|
3459
|
+
toTranslationCsv,
|
|
3460
|
+
toXliff,
|
|
3461
|
+
translationCoverage,
|
|
3462
|
+
unreadAnnouncements,
|
|
1869
3463
|
validateGuideConfig,
|
|
3464
|
+
variantProblems,
|
|
3465
|
+
variantRanges,
|
|
3466
|
+
visibleAnnouncements,
|
|
1870
3467
|
visibleArticleIds,
|
|
1871
3468
|
visibleButtons,
|
|
1872
3469
|
visitorAudiences,
|
|
3470
|
+
visitorLocales,
|
|
3471
|
+
withExperimentBucket,
|
|
1873
3472
|
withVisibility
|
|
1874
3473
|
});
|
|
1875
3474
|
//# sourceMappingURL=index.cjs.map
|