@inappstory/slide-api 0.0.22 → 0.0.24

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/index.js CHANGED
@@ -573,8 +573,8 @@ const getWinWidth = function (env) {
573
573
  const getWinHeight = function (env) {
574
574
  return env.innerHeight || env.document.documentElement.clientHeight || env.document.body.clientHeight;
575
575
  };
576
- const sendStatisticEventToApp = function (sdkApi, name, data, devPayload) {
577
- sdkApi.sendStatisticEvent(name, data, devPayload);
576
+ const sendStatisticEventToApp = function (sdkApi, name, data, devPayload, options) {
577
+ sdkApi.sendStatisticEvent(name, data, devPayload, options?.forceEnableStatisticV2 ?? false);
578
578
  };
579
579
  const getValueOrException = function (value, message) {
580
580
  if (value == null) {
@@ -670,6 +670,37 @@ const Clipboard = (function (window, document, navigator) {
670
670
  copy,
671
671
  };
672
672
  })(window, document, navigator);
673
+ function FilterNumber(x) {
674
+ return typeof x === "number";
675
+ }
676
+ function determineLocale() {
677
+ // All modern browsers support this. Should match what's used by localeCompare() etc.
678
+ const intl = window.Intl;
679
+ if (intl !== undefined) {
680
+ return intl.NumberFormat().resolvedOptions().locale;
681
+ }
682
+ // Fall back to ranked choice locales, which are configured in the browser but aren't necessarily
683
+ // what's used in functions like localeCompare().
684
+ const languages = navigator.languages;
685
+ if (languages !== undefined && languages.length > 0) {
686
+ return languages[0];
687
+ }
688
+ // Old standard.
689
+ return navigator.language ?? "en-US";
690
+ }
691
+ function isScreenSupportsTouch(env) {
692
+ let supportsTouch = false;
693
+ if ("ontouchstart" in env) {
694
+ supportsTouch = true;
695
+ }
696
+ else if (env.navigator.msPointerEnabled) {
697
+ supportsTouch = true;
698
+ }
699
+ else if ("ontouchstart" in env.document.documentElement) {
700
+ supportsTouch = true;
701
+ }
702
+ return supportsTouch;
703
+ }
673
704
 
674
705
  var supportAnimate = document.documentElement.animate !== undefined;
675
706
  supportAnimate = false; // tmp off
@@ -1067,8 +1098,8 @@ class EsModuleSdkApi {
1067
1098
  showNextSlide(duration) {
1068
1099
  this.sdkBinding().showNextSlide(duration);
1069
1100
  }
1070
- sendStatisticEvent(name, data, devPayload) {
1071
- this.sdkBinding().sendStatisticEvent(name, data, devPayload);
1101
+ sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2) {
1102
+ this.sdkBinding().sendStatisticEvent(name, data, devPayload, forceEnableStatisticV2);
1072
1103
  }
1073
1104
  getCardLocalData() {
1074
1105
  return this.sdkBinding().getCardLocalData();
@@ -1169,6 +1200,14 @@ class EsModuleSdkApi {
1169
1200
  getCardFonts() {
1170
1201
  return this.sdkBinding().getCardFonts();
1171
1202
  }
1203
+ disableVerticalSwipeGesture() {
1204
+ this.sdkBinding().disableVerticalSwipeGesture();
1205
+ }
1206
+ enableVerticalSwipeGesture() {
1207
+ this.sdkBinding().enableVerticalSwipeGesture();
1208
+ }
1209
+ disableBackpress() { }
1210
+ enableBackpress() { }
1172
1211
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`() => SDKInterface`]; }
1173
1212
  }
1174
1213
 
@@ -1423,11 +1462,11 @@ class WidgetBase {
1423
1462
  }
1424
1463
  return data;
1425
1464
  }
1426
- static sendStatisticEventToApp(name, data, devPayload) {
1427
- sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload);
1465
+ static sendStatisticEventToApp(name, data, devPayload, options) {
1466
+ sendStatisticEventToApp(this.widgetsService.sdkApi, name, data, devPayload, options);
1428
1467
  }
1429
- sendStatisticEventToApp(name, data, devPayload) {
1430
- this.constructor.sendStatisticEventToApp(name, data, devPayload);
1468
+ sendStatisticEventToApp(name, data, devPayload, options) {
1469
+ this.constructor.sendStatisticEventToApp(name, data, devPayload, options);
1431
1470
  }
1432
1471
  startDisabledTimeline() {
1433
1472
  this.sdkApi.startDisabledTimeline(this.cardId, this.slideIndex);
@@ -2039,7 +2078,9 @@ class WidgetDateCountdown extends WidgetBase {
2039
2078
  this._showLayer(this.layers, 0);
2040
2079
  }
2041
2080
  else {
2042
- this._showLayer(this.layers, 1);
2081
+ if (this.layers[1] != null) {
2082
+ this._showLayer(this.layers, 1);
2083
+ }
2043
2084
  }
2044
2085
  }
2045
2086
  onPause() {
@@ -2122,7 +2163,9 @@ class WidgetDateCountdown extends WidgetBase {
2122
2163
  }
2123
2164
  else {
2124
2165
  this.pendingUpdate = false;
2125
- this._showLayer(this.layers, 1);
2166
+ if (this.layers[1] != null) {
2167
+ this._showLayer(this.layers, 1);
2168
+ }
2126
2169
  }
2127
2170
  if (this.pendingUpdate) {
2128
2171
  this.env.requestAnimationFrame(() => this.updateTimer());
@@ -3082,6 +3125,7 @@ class WidgetQuest extends WidgetBase {
3082
3125
  isWidget;
3083
3126
  slideCount;
3084
3127
  nonFinalSlide;
3128
+ slideDisabledNavigation;
3085
3129
  finalSlide;
3086
3130
  constructor(element, options) {
3087
3131
  const isWidget = !hasClass(element, "narrative-slide");
@@ -3094,6 +3138,7 @@ class WidgetQuest extends WidgetBase {
3094
3138
  this.finalSlide = !this.isWidget && !this.nonFinalSlide;
3095
3139
  this.label = this.element.querySelector(".label-view .label");
3096
3140
  this.variants = slice.call(this.element.querySelectorAll(".variants-box .variant-view"));
3141
+ this.slideDisabledNavigation = Boolean(getTagDataAsNumber(this.slide, "disableNavigation") ?? 0);
3097
3142
  this.selectedAnswer = undefined;
3098
3143
  }
3099
3144
  /**
@@ -3238,6 +3283,10 @@ class WidgetQuest extends WidgetBase {
3238
3283
  const directionForward = event.direction === "forward";
3239
3284
  event.direction === "backward";
3240
3285
  if (this.isWidget) {
3286
+ // like in web-sdk - simple block tap navigation at all
3287
+ if (this.slideDisabledNavigation) {
3288
+ return;
3289
+ }
3241
3290
  if (directionForward) {
3242
3291
  return;
3243
3292
  }
@@ -3261,6 +3310,10 @@ class WidgetQuest extends WidgetBase {
3261
3310
  }
3262
3311
  }
3263
3312
  else {
3313
+ // like in web-sdk - simple block tap navigation at all
3314
+ if (this.slideDisabledNavigation) {
3315
+ return;
3316
+ }
3264
3317
  // slides without quest form
3265
3318
  // simple slide case
3266
3319
  if (this.nonFinalSlide || event.slideIndex < this.firstSlideWithQuestIndex()) {
@@ -4219,10 +4272,10 @@ class WidgetRangeSlider extends WidgetBase {
4219
4272
  if (!this.maxHandlePos) {
4220
4273
  this.update(true, false);
4221
4274
  }
4222
- document.addEventListener("touchmove", this.handleMove);
4223
- document.addEventListener("touchend", this.handleEnd);
4224
- document.addEventListener("mousemove", this.handleMove);
4225
- document.addEventListener("mouseup", this.handleEnd);
4275
+ this.env.document.addEventListener("touchmove", this.handleMove);
4276
+ this.env.document.addEventListener("touchend", this.handleEnd);
4277
+ this.env.document.addEventListener("mousemove", this.handleMove);
4278
+ this.env.document.addEventListener("mouseup", this.handleEnd);
4226
4279
  // add active class because Firefox is ignoring
4227
4280
  // the handle:active pseudo selector because of `e.preventDefault();`
4228
4281
  this.range.classList.add(this.options.activeClass);
@@ -4247,10 +4300,10 @@ class WidgetRangeSlider extends WidgetBase {
4247
4300
  this.isClickCapturedBySlider = false;
4248
4301
  });
4249
4302
  // e.preventDefault();
4250
- document.removeEventListener("touchmove", this.handleMove);
4251
- document.removeEventListener("touchend", this.handleEnd);
4252
- document.removeEventListener("mousemove", this.handleMove);
4253
- document.removeEventListener("mouseup", this.handleEnd);
4303
+ this.env.document.removeEventListener("touchmove", this.handleMove);
4304
+ this.env.document.removeEventListener("touchend", this.handleEnd);
4305
+ this.env.document.removeEventListener("mousemove", this.handleMove);
4306
+ this.env.document.removeEventListener("mouseup", this.handleEnd);
4254
4307
  this.range.classList.remove(this.options.activeClass);
4255
4308
  this.element.classList.add("input-done");
4256
4309
  if (!this.hasSubmitButton) {
@@ -15280,6 +15333,1136 @@ class WidgetBarcode extends WidgetBase {
15280
15333
  static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
15281
15334
  }
15282
15335
 
15336
+ class Formatter {
15337
+ intlSupport = false;
15338
+ defaultTimeFormat = "medium";
15339
+ defaultDatetimeFormat = "medium";
15340
+ defaultDateFormat = "medium";
15341
+ decimalSeparator = ".";
15342
+ thousandSeparator = "&thinsp;";
15343
+ spaceSeparator = "&thinsp;";
15344
+ static Second = 1000;
15345
+ static Minute = 60 * Formatter.Second;
15346
+ static Hour = 60 * Formatter.Minute;
15347
+ static Day = 24 * Formatter.Hour;
15348
+ datetimeFormatOptions = {
15349
+ short: {
15350
+ year: "numeric",
15351
+ month: "2-digit",
15352
+ day: "2-digit",
15353
+ hour: "2-digit",
15354
+ minute: "2-digit",
15355
+ },
15356
+ medium: {
15357
+ year: "numeric",
15358
+ month: "2-digit",
15359
+ day: "2-digit",
15360
+ hour: "2-digit",
15361
+ minute: "2-digit",
15362
+ second: "2-digit",
15363
+ },
15364
+ long: {
15365
+ year: "numeric",
15366
+ month: "long",
15367
+ day: "2-digit",
15368
+ hour: "2-digit",
15369
+ minute: "2-digit",
15370
+ second: "2-digit",
15371
+ timeZoneName: "short",
15372
+ },
15373
+ full: {
15374
+ weekday: "long",
15375
+ year: "numeric",
15376
+ month: "long",
15377
+ day: "2-digit",
15378
+ hour: "2-digit",
15379
+ minute: "2-digit",
15380
+ second: "2-digit",
15381
+ timeZoneName: "long",
15382
+ },
15383
+ };
15384
+ dateFormatOptions = {
15385
+ short: {
15386
+ year: "2-digit",
15387
+ month: "2-digit",
15388
+ day: "2-digit",
15389
+ },
15390
+ medium: {
15391
+ year: "numeric",
15392
+ month: "2-digit",
15393
+ day: "2-digit",
15394
+ },
15395
+ long: {
15396
+ year: "numeric",
15397
+ month: "long",
15398
+ day: "2-digit",
15399
+ },
15400
+ full: {
15401
+ weekday: "long",
15402
+ year: "numeric",
15403
+ month: "long",
15404
+ day: "2-digit",
15405
+ },
15406
+ };
15407
+ timeFormatOptions = {
15408
+ short: {
15409
+ hour: "2-digit",
15410
+ minute: "2-digit",
15411
+ },
15412
+ medium: {
15413
+ hour: "2-digit",
15414
+ minute: "2-digit",
15415
+ second: "2-digit",
15416
+ },
15417
+ long: {
15418
+ hour: "2-digit",
15419
+ minute: "2-digit",
15420
+ second: "2-digit",
15421
+ timeZoneName: "short",
15422
+ },
15423
+ full: {
15424
+ hour: "2-digit",
15425
+ minute: "2-digit",
15426
+ second: "2-digit",
15427
+ timeZoneName: "long",
15428
+ },
15429
+ };
15430
+ context;
15431
+ constructor(context) {
15432
+ this.intlSupport = typeof Intl === "object" && Intl !== null;
15433
+ this.context = context;
15434
+ }
15435
+ asDate(value, format = undefined, options = {}) {
15436
+ if (!format) {
15437
+ format = this.defaultDateFormat;
15438
+ }
15439
+ return this.formatDateTimeValue(value, format, "date", options);
15440
+ }
15441
+ asTime(value, format = undefined, options = {}) {
15442
+ if (!format) {
15443
+ format = this.defaultTimeFormat;
15444
+ }
15445
+ return this.formatDateTimeValue(value, format, "time", options);
15446
+ }
15447
+ asDatetime(value, format = undefined, options = {}) {
15448
+ if (!format) {
15449
+ format = this.defaultTimeFormat;
15450
+ }
15451
+ return this.formatDateTimeValue(value, format, "datetime", options);
15452
+ }
15453
+ formatDateTimeValue(value, format = undefined, type = undefined, options = {}) {
15454
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15455
+ if (normalizedValue === null) {
15456
+ return "";
15457
+ }
15458
+ if (this.intlSupport) {
15459
+ let formatterOptions = {};
15460
+ if (type === "date") {
15461
+ if (typeof format === "undefined") {
15462
+ format = this.defaultDateFormat;
15463
+ }
15464
+ if (typeof format === "object") {
15465
+ formatterOptions = format;
15466
+ }
15467
+ else {
15468
+ if (format in this.dateFormatOptions) {
15469
+ formatterOptions = this.dateFormatOptions[format];
15470
+ }
15471
+ else {
15472
+ return this.momentFallback(normalizedValue, format, options);
15473
+ }
15474
+ }
15475
+ }
15476
+ else if (type === "time") {
15477
+ if (typeof format === "undefined") {
15478
+ format = this.defaultTimeFormat;
15479
+ }
15480
+ if (typeof format === "object") {
15481
+ formatterOptions = format;
15482
+ }
15483
+ else {
15484
+ if (format in this.timeFormatOptions) {
15485
+ formatterOptions = this.timeFormatOptions[format];
15486
+ }
15487
+ else {
15488
+ return this.momentFallback(normalizedValue, format, options);
15489
+ }
15490
+ }
15491
+ }
15492
+ else if (type === "datetime") {
15493
+ if (typeof format === "undefined") {
15494
+ format = this.defaultDatetimeFormat;
15495
+ }
15496
+ if (typeof format === "object") {
15497
+ formatterOptions = format;
15498
+ }
15499
+ else {
15500
+ if (format in this.datetimeFormatOptions) {
15501
+ formatterOptions = this.datetimeFormatOptions[format];
15502
+ }
15503
+ else {
15504
+ return this.momentFallback(normalizedValue, format, options);
15505
+ }
15506
+ }
15507
+ }
15508
+ if (options.timezone) {
15509
+ formatterOptions.timeZone = options.timezone;
15510
+ }
15511
+ Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
15512
+ return Intl.DateTimeFormat(this.locale, formatterOptions).format(normalizedValue);
15513
+ }
15514
+ return "";
15515
+ }
15516
+ momentFallback(value, format, options = {}) {
15517
+ return value.toLocaleString(this.locale);
15518
+ // return this.context.$moment(value).format(format);
15519
+ }
15520
+ asInteger(value) {
15521
+ if (value === undefined || value === null) {
15522
+ return this.nullDisplay;
15523
+ }
15524
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15525
+ if (this.intlSupport) {
15526
+ return Intl.NumberFormat(this.locale, {
15527
+ maximumFractionDigits: 0,
15528
+ useGrouping: true,
15529
+ }).format(normalizedValue);
15530
+ }
15531
+ return Formatter.numberFormat(normalizedValue, 0, this.decimalSeparator, this.thousandSeparator);
15532
+ }
15533
+ asDecimal(value, decimals = 2) {
15534
+ if (value == null) {
15535
+ return this.nullDisplay;
15536
+ }
15537
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15538
+ if (this.intlSupport) {
15539
+ return Intl.NumberFormat(this.locale, {
15540
+ maximumFractionDigits: decimals,
15541
+ minimumFractionDigits: decimals,
15542
+ useGrouping: true,
15543
+ }).format(normalizedValue);
15544
+ }
15545
+ return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
15546
+ }
15547
+ asDecimalMax(value, decimals = 2) {
15548
+ if (value === undefined || value === null) {
15549
+ return this.nullDisplay;
15550
+ }
15551
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15552
+ if (this.intlSupport) {
15553
+ return Intl.NumberFormat(this.locale, {
15554
+ maximumFractionDigits: decimals,
15555
+ minimumFractionDigits: 0,
15556
+ useGrouping: true,
15557
+ }).format(normalizedValue);
15558
+ }
15559
+ return Formatter.numberFormat(normalizedValue, decimals, this.decimalSeparator, this.thousandSeparator);
15560
+ }
15561
+ asPercent(value, decimals = 0) {
15562
+ if (value === undefined || value === null) {
15563
+ return this.nullDisplay;
15564
+ }
15565
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15566
+ if (this.intlSupport) {
15567
+ return Intl.NumberFormat(this.locale, {
15568
+ style: "percent",
15569
+ maximumFractionDigits: decimals,
15570
+ minimumFractionDigits: decimals,
15571
+ }).format(normalizedValue);
15572
+ }
15573
+ return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
15574
+ }
15575
+ asPercentMax(value, decimals = 0) {
15576
+ if (value === undefined || value === null) {
15577
+ return this.nullDisplay;
15578
+ }
15579
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15580
+ if (this.intlSupport) {
15581
+ return Intl.NumberFormat(this.locale, {
15582
+ style: "percent",
15583
+ maximumFractionDigits: decimals,
15584
+ minimumFractionDigits: 0,
15585
+ }).format(normalizedValue);
15586
+ }
15587
+ return Formatter.numberFormat(normalizedValue * 100, decimals, this.decimalSeparator, this.thousandSeparator);
15588
+ }
15589
+ asRelativeTime(value, referenceTime = undefined) {
15590
+ if (value === undefined || value === null) {
15591
+ return this.nullDisplay;
15592
+ }
15593
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15594
+ if (normalizedValue == null) {
15595
+ return this.nullDisplay;
15596
+ }
15597
+ if (referenceTime === undefined || referenceTime === null) {
15598
+ referenceTime = new Date();
15599
+ }
15600
+ else {
15601
+ referenceTime = Formatter.normalizeDatetimeValue(value);
15602
+ }
15603
+ const dt = referenceTime.getTime() - normalizedValue.getTime();
15604
+ const absDt = Math.abs(dt);
15605
+ const invert = dt < 0;
15606
+ if (absDt < Formatter.Second) {
15607
+ return this.context.i18n?.t("format.relativeTime.justNow").toString() ?? "";
15608
+ }
15609
+ const seconds = absDt / 1000;
15610
+ let interval = seconds / 31536000;
15611
+ if (interval > 1) {
15612
+ return this.context.i18n?.tc("format.relativeTime.year" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15613
+ }
15614
+ interval = seconds / 2592000;
15615
+ if (interval > 1) {
15616
+ return this.context.i18n?.tc("format.relativeTime.month" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15617
+ }
15618
+ interval = seconds / 86400;
15619
+ if (interval > 1) {
15620
+ return this.context.i18n?.tc("format.relativeTime.day" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15621
+ }
15622
+ interval = seconds / 3600;
15623
+ if (interval > 1) {
15624
+ return this.context.i18n?.tc("format.relativeTime.hour" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15625
+ }
15626
+ interval = seconds / 60;
15627
+ if (interval > 1) {
15628
+ return this.context.i18n?.tc("format.relativeTime.minute" + (invert ? "In" : "Ago"), Math.floor(interval)).toString() ?? "";
15629
+ }
15630
+ return this.context.i18n?.tc("format.relativeTime.second" + (invert ? "In" : "Ago"), Math.floor(seconds)).toString() ?? "";
15631
+ }
15632
+ asDuration(value) {
15633
+ if (value === undefined || value === null) {
15634
+ return "00:00";
15635
+ }
15636
+ const normalizedValue = Formatter.normalizeDatetimeValue(value);
15637
+ if (normalizedValue === undefined || normalizedValue === null) {
15638
+ return "00:00";
15639
+ }
15640
+ const hours = Math.floor(value / 3600);
15641
+ const minutes = Math.floor((value / 60) % 60);
15642
+ const seconds = value % 60;
15643
+ if (hours > 0) {
15644
+ return `${hours}:${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
15645
+ }
15646
+ else {
15647
+ return `${minutes < 10 ? 0 : ""}${minutes}:${seconds < 10 ? 0 : ""}${seconds}`;
15648
+ }
15649
+ }
15650
+ asCurrency(value, currency = undefined) {
15651
+ if (value === undefined || value === null) {
15652
+ return this.nullDisplay;
15653
+ }
15654
+ if (currency === undefined || currency === null) {
15655
+ currency = "USD";
15656
+ }
15657
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15658
+ if (normalizedValue == null) {
15659
+ return this.nullDisplay;
15660
+ }
15661
+ let decimals = 2;
15662
+ if (Number.isInteger(normalizedValue)) {
15663
+ decimals = 0;
15664
+ }
15665
+ if (currency === "RUR" || currency === "RUB") {
15666
+ return `${this.asDecimal(normalizedValue, decimals)}${this.spaceSeparator}₽`;
15667
+ }
15668
+ if (this.intlSupport) {
15669
+ try {
15670
+ return Intl.NumberFormat(this.locale, {
15671
+ style: "currency",
15672
+ currency,
15673
+ currencyDisplay: "symbol",
15674
+ maximumFractionDigits: decimals,
15675
+ minimumFractionDigits: decimals,
15676
+ }).format(normalizedValue);
15677
+ }
15678
+ catch (e) {
15679
+ console.error(e);
15680
+ return String(normalizedValue);
15681
+ }
15682
+ }
15683
+ return currency + "&thinsp;" + this.asDecimal(normalizedValue, 2);
15684
+ }
15685
+ asShortSizeCasual(value, dp = 1) {
15686
+ if (value === undefined || value === null) {
15687
+ return this.nullDisplay;
15688
+ }
15689
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15690
+ if (normalizedValue === undefined || normalizedValue === null) {
15691
+ return this.nullDisplay;
15692
+ }
15693
+ const thresh = 1024;
15694
+ if (Math.abs(value) < thresh) {
15695
+ return value + " B";
15696
+ }
15697
+ const units = ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
15698
+ let u = -1;
15699
+ const r = 10 ** dp;
15700
+ do {
15701
+ value /= thresh;
15702
+ ++u;
15703
+ } while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
15704
+ return value.toFixed(dp) + " " + units[u];
15705
+ }
15706
+ asShortSize(value, si = false, dp = 1) {
15707
+ if (value === undefined || value === null) {
15708
+ return this.nullDisplay;
15709
+ }
15710
+ const normalizedValue = Formatter.normalizeNumericValue(value);
15711
+ if (normalizedValue === undefined || normalizedValue === null) {
15712
+ return this.nullDisplay;
15713
+ }
15714
+ const thresh = si ? 1000 : 1024;
15715
+ if (Math.abs(value) < thresh) {
15716
+ return value + " B";
15717
+ }
15718
+ const units = si ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
15719
+ let u = -1;
15720
+ const r = 10 ** dp;
15721
+ do {
15722
+ value /= thresh;
15723
+ ++u;
15724
+ } while (Math.round(Math.abs(value) * r) / r >= thresh && u < units.length - 1);
15725
+ return value.toFixed(dp) + " " + units[u];
15726
+ }
15727
+ static numberFormat(value, decimals = 0, decimalSeparator = ".", thousandsSeparator) {
15728
+ const sign = value < 0 ? "-" : "";
15729
+ const sNumber = Math.abs(parseInt((+value || 0).toFixed(decimals))) + "";
15730
+ const len = sNumber.length;
15731
+ const tchunk = len > 3 ? len % 3 : 0;
15732
+ const chFirst = tchunk ? sNumber.substr(0, tchunk) + thousandsSeparator : "";
15733
+ const chRest = sNumber.substr(tchunk).replace(/(\d\d\d)(?=\d)/g, "$1" + thousandsSeparator);
15734
+ const chLast = decimals ? decimalSeparator + (Math.abs(value) - parseFloat(sNumber)).toFixed(decimals).slice(2) : "";
15735
+ return sign + chFirst + chRest + chLast;
15736
+ }
15737
+ get nullDisplay() {
15738
+ return "";
15739
+ // if (this.context && this.context.i18n) {
15740
+ // return this.context.i18n.t("notSet").toString();
15741
+ // }
15742
+ //
15743
+ // return "not set";
15744
+ }
15745
+ static normalizeDatetimeValue(value) {
15746
+ const type = typeof value;
15747
+ if (type === "object" && value instanceof Date) {
15748
+ return value;
15749
+ }
15750
+ else if (type === "number") {
15751
+ return new Date(value);
15752
+ }
15753
+ else if (type === "string") {
15754
+ if (isNaN(value)) {
15755
+ return new Date(parseInt(value));
15756
+ }
15757
+ else {
15758
+ const d = Date.parse(value);
15759
+ if (isNaN(d)) {
15760
+ return null;
15761
+ }
15762
+ return new Date(d);
15763
+ }
15764
+ }
15765
+ return null;
15766
+ }
15767
+ static normalizeNumericValue(value) {
15768
+ const type = typeof value;
15769
+ if ((type === "object" && value === null) || type === "undefined") {
15770
+ return 0;
15771
+ }
15772
+ else if (type === "number") {
15773
+ return value;
15774
+ }
15775
+ return parseFloat(value);
15776
+ }
15777
+ get locale() {
15778
+ return this.context.determineLocale();
15779
+ }
15780
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`{\n determineLocale: () => string;\n i18n: { t: (key: string) => string; tc: (key: string, value: string | number) => string } | undefined;\n }`]; }
15781
+ }
15782
+ const formatter = new Formatter({ determineLocale, i18n: undefined });
15783
+
15784
+ class SwipeGestureDetector {
15785
+ env;
15786
+ isScreenSupportsTouch;
15787
+ canContinueHandleDown;
15788
+ onStart;
15789
+ onUpdate;
15790
+ onEnd;
15791
+ constructor(env, isScreenSupportsTouch, canContinueHandleDown, onStart, onUpdate, onEnd) {
15792
+ this.env = env;
15793
+ this.isScreenSupportsTouch = isScreenSupportsTouch;
15794
+ this.canContinueHandleDown = canContinueHandleDown;
15795
+ this.onStart = onStart;
15796
+ this.onUpdate = onUpdate;
15797
+ this.onEnd = onEnd;
15798
+ // Store context
15799
+ this.handleDown = this.handleDown.bind(this);
15800
+ this.handleMove = this.handleMove.bind(this);
15801
+ this.handleEnd = this.handleEnd.bind(this);
15802
+ this.supportsTouch = false;
15803
+ if (this.isScreenSupportsTouch) {
15804
+ this.env.document.addEventListener("touchstart", this.handleDown, false);
15805
+ }
15806
+ else {
15807
+ this.env.document.addEventListener("mousedown", this.handleDown, false);
15808
+ }
15809
+ }
15810
+ startPageCoordinate = [0, 0];
15811
+ limit = Math.tan(((45 * 1.5) / 180) * Math.PI);
15812
+ pageWidth = window.innerWidth || document.body.clientWidth;
15813
+ threshold = Math.max(1, Math.floor(0.01 * this.pageWidth));
15814
+ supportsTouch = false;
15815
+ handleDown(e) {
15816
+ // console.log("handleDown", {e, startPageCoordinate: this.startPageCoordinate})
15817
+ if (!this.canContinueHandleDown(e)) {
15818
+ return;
15819
+ }
15820
+ this.startPageCoordinate = this.getPageCoordinate(e);
15821
+ if (this.isScreenSupportsTouch) {
15822
+ this.env.document.addEventListener("touchmove", this.handleMove, false);
15823
+ this.env.document.addEventListener("touchend", this.handleEnd, false);
15824
+ }
15825
+ else {
15826
+ this.env.document.addEventListener("mousemove", this.handleMove, false);
15827
+ this.env.document.addEventListener("mouseup", this.handleEnd, false);
15828
+ }
15829
+ this.onStart(e);
15830
+ }
15831
+ handleMove(e) {
15832
+ // console.log("handleMove", { startPageCoordinate: this.startPageCoordinate})
15833
+ // this.currentPageCoordinate = this.getPageCoordinate(e);
15834
+ this.onUpdate(e);
15835
+ }
15836
+ handleEnd(e) {
15837
+ if (this.isScreenSupportsTouch) {
15838
+ this.env.document.removeEventListener("touchmove", this.handleMove);
15839
+ this.env.document.removeEventListener("touchend", this.handleEnd);
15840
+ }
15841
+ else {
15842
+ this.env.document.removeEventListener("mousemove", this.handleMove);
15843
+ this.env.document.removeEventListener("mouseup", this.handleEnd);
15844
+ }
15845
+ const currentPageCoordinate = this.getPageCoordinate(e);
15846
+ let gesture = 0 /* SwipeGesture.undefined */;
15847
+ const x = currentPageCoordinate[0] - this.startPageCoordinate[0];
15848
+ const y = currentPageCoordinate[1] - this.startPageCoordinate[1];
15849
+ // console.log("handleEnd", {currentPageCoordinate, startPageCoordinate: this.startPageCoordinate})
15850
+ let xy = Math.abs(x / y);
15851
+ let yx = Math.abs(y / x);
15852
+ if (Math.abs(x) > this.threshold || Math.abs(y) > this.threshold) {
15853
+ if (yx <= this.limit) {
15854
+ if (x < 0) {
15855
+ gesture = 4 /* SwipeGesture.SwipeLeft */;
15856
+ // @ts-ignore
15857
+ // _log(JSON.stringify({t: "SwipeLeft", yx, x, threshold: this.threshold}), true);
15858
+ }
15859
+ else {
15860
+ // @ts-ignore
15861
+ // _log(JSON.stringify({t: "SwipeRight", yx, x, threshold: this.threshold}), true);
15862
+ gesture = 5 /* SwipeGesture.SwipeRight */;
15863
+ }
15864
+ }
15865
+ if (xy <= this.limit) {
15866
+ if (y < 0) {
15867
+ // @ts-ignore
15868
+ // _log(JSON.stringify({t: "SwipeUp", xy, y, threshold: this.threshold}), true);
15869
+ gesture = 2 /* SwipeGesture.SwipeUp */;
15870
+ }
15871
+ else {
15872
+ // @ts-ignore
15873
+ // _log(JSON.stringify({t: "SwipeDown", xy, y, threshold: this.threshold}), true);
15874
+ gesture = 3 /* SwipeGesture.SwipeDown */;
15875
+ }
15876
+ }
15877
+ }
15878
+ else {
15879
+ // @ts-ignore
15880
+ // _log(JSON.stringify({t: "Tap", x, y, threshold: this.threshold}), true);
15881
+ gesture = 1 /* SwipeGesture.Tap */;
15882
+ }
15883
+ this.onEnd(e, gesture);
15884
+ }
15885
+ destroy() {
15886
+ if (this.isScreenSupportsTouch) {
15887
+ this.env.document.removeEventListener("touchstart", this.handleDown);
15888
+ this.env.document.removeEventListener("touchmove", this.handleMove);
15889
+ this.env.document.removeEventListener("touchend", this.handleEnd);
15890
+ }
15891
+ else {
15892
+ this.env.document.removeEventListener("mousedown", this.handleDown);
15893
+ this.env.document.removeEventListener("mousemove", this.handleMove);
15894
+ this.env.document.removeEventListener("mouseup", this.handleEnd);
15895
+ }
15896
+ }
15897
+ getPageCoordinate(e) {
15898
+ let x = 0;
15899
+ let y = 0;
15900
+ if (e["clientX"] != null && e["clientY"] != null) {
15901
+ x = e["clientX"];
15902
+ y = e["clientY"];
15903
+ }
15904
+ else if (e.touches &&
15905
+ e.touches[0] &&
15906
+ e.touches[0]["clientX"] != null &&
15907
+ e.touches[0]["clientY"] != null) {
15908
+ x = e.touches[0]["clientX"];
15909
+ y = e.touches[0]["clientY"];
15910
+ }
15911
+ else if (e.changedTouches &&
15912
+ e.changedTouches[0] &&
15913
+ e.changedTouches[0]["clientX"] != null &&
15914
+ e.changedTouches[0]["clientY"] != null) {
15915
+ x = e.changedTouches[0]["clientX"];
15916
+ y = e.changedTouches[0]["clientY"];
15917
+ }
15918
+ // @ts-ignore
15919
+ else if (e.currentPoint && e.currentPoint["x"] != null && e.currentPoint["y"] != null) {
15920
+ // @ts-ignore
15921
+ x = e.currentPoint["x"];
15922
+ // @ts-ignore
15923
+ y = e.currentPoint["y"];
15924
+ }
15925
+ return [x, y];
15926
+ }
15927
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`Window`, `boolean`, `(e: MouseEvent | TouchEvent) => boolean`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent) => void`, `(e: MouseEvent | TouchEvent, gesture: SwipeGesture) => void`]; }
15928
+ }
15929
+
15930
+ /**
15931
+ * adult: null
15932
+ * availability: 1
15933
+ * coverUrl: "https://cdn.test.inappstory.com/np/file/cf/wb/wc/vcaji5clqon3nkwdwle3cjz63x.jpg?k=KgAAAAAAAAACAQ"
15934
+ * currency: "RUR"
15935
+ * description: "Непромокаемый комбинезон - дождевик детский Муссон"
15936
+ * id: 204
15937
+ * name: "Непромокаемый комбинезон - дождевик детский \"Муссон\""
15938
+ * offerId: "10125"
15939
+ * oldPrice: null
15940
+ * price: "2690.0000"
15941
+ * url: "http://www.songnomik.ru/products/detskaya-odezhda-optom-dlya-novorozhdennyh/detskie-kombinezony-optom/2166483.html"
15942
+ */
15943
+ class WidgetProducts extends WidgetBase {
15944
+ static DEFAULTS = {
15945
+ slide: null,
15946
+ activateAfterCreate: false,
15947
+ create: false,
15948
+ localData: {},
15949
+ };
15950
+ static widgetClassName = "narrative-element-products";
15951
+ captionView;
15952
+ linkTarget = [];
15953
+ msgNetworkError;
15954
+ msgServiceError;
15955
+ swipeGestureDetector = null;
15956
+ isClickCapturedByWidget = false;
15957
+ isScreenSupportsTouch = false;
15958
+ constructor(element, options) {
15959
+ super(element, options);
15960
+ this.captionView = this.element.querySelector(".narrative-element-text-lines");
15961
+ const linkTarget = decodeURIComponent(getTagData(element, "linkTarget") ?? "[]");
15962
+ try {
15963
+ let parsed = JSON.parse(linkTarget);
15964
+ if (Array.isArray(parsed)) {
15965
+ this.linkTarget = parsed.filter(FilterNumber);
15966
+ }
15967
+ }
15968
+ catch (e) {
15969
+ console.error(e);
15970
+ }
15971
+ this.isScreenSupportsTouch = isScreenSupportsTouch(this.env);
15972
+ this.msgNetworkError = getTagData(this.element, "msgNetworkError");
15973
+ this.msgServiceError = getTagData(this.element, "msgServiceError");
15974
+ }
15975
+ /**
15976
+ * Start or restart widget
15977
+ * @param localData
15978
+ */
15979
+ onRefreshUserData(localData) {
15980
+ super.onRefreshUserData(localData);
15981
+ }
15982
+ onStart() {
15983
+ super.onStart();
15984
+ // reinit for case when we returned to slide from other slide and onStop destroyed SwipeGestureDetector
15985
+ this.initSwipeGestureDetector();
15986
+ }
15987
+ isTransparentElement() {
15988
+ if (this.element) {
15989
+ try {
15990
+ const color = window.getComputedStyle(this.element).color;
15991
+ if (color === "transparent" || color === "rgba(0, 0, 0, 0)" || color === "rgba(0,0,0,0)") {
15992
+ return true;
15993
+ }
15994
+ }
15995
+ catch (err) {
15996
+ console.error(err);
15997
+ }
15998
+ }
15999
+ return false;
16000
+ }
16001
+ _statEventWidgetClick() {
16002
+ try {
16003
+ const captionViewText = this.captionView?.textContent ?? "";
16004
+ this.sendStatisticEventToApp("w-products-click", {
16005
+ ...this.statisticEventBaseFieldsShortForm,
16006
+ wi: this.elementId,
16007
+ wl: captionViewText,
16008
+ wv: this.linkTarget,
16009
+ }, {
16010
+ ...this.statisticEventBaseFieldsShortForm,
16011
+ widget_id: this.elementId,
16012
+ widget_label: captionViewText,
16013
+ widget_value: this.linkTarget,
16014
+ }, {
16015
+ forceEnableStatisticV2: true,
16016
+ });
16017
+ }
16018
+ catch (error) {
16019
+ console.error(error);
16020
+ }
16021
+ }
16022
+ _statEventWidgetOpen(offers) {
16023
+ try {
16024
+ const captionViewText = this.captionView?.textContent ?? "";
16025
+ this.sendStatisticEventToApp("w-products-open", {
16026
+ ...this.statisticEventBaseFieldsShortForm,
16027
+ wi: this.elementId,
16028
+ wl: captionViewText,
16029
+ wv: this.linkTarget,
16030
+ wit: offers.map(item => item.offerId),
16031
+ }, {
16032
+ ...this.statisticEventBaseFieldsShortForm,
16033
+ widget_id: this.elementId,
16034
+ widget_label: captionViewText,
16035
+ widget_value: this.linkTarget,
16036
+ widget_items: offers.map(item => item.offerId),
16037
+ }, {
16038
+ forceEnableStatisticV2: true,
16039
+ });
16040
+ }
16041
+ catch (error) {
16042
+ console.error(error);
16043
+ }
16044
+ }
16045
+ _statEventWidgetCardClick(offer) {
16046
+ try {
16047
+ const captionViewText = this.captionView?.textContent ?? "";
16048
+ this.sendStatisticEventToApp("w-products-card-click", {
16049
+ ...this.statisticEventBaseFieldsShortForm,
16050
+ wi: this.elementId,
16051
+ wl: captionViewText,
16052
+ wv: offer.offerId,
16053
+ wvi: offer.id,
16054
+ }, {
16055
+ ...this.statisticEventBaseFieldsShortForm,
16056
+ widget_id: this.elementId,
16057
+ widget_label: captionViewText,
16058
+ widget_value: offer.offerId,
16059
+ widget_value_id: offer.id,
16060
+ }, {
16061
+ forceEnableStatisticV2: true,
16062
+ });
16063
+ }
16064
+ catch (error) {
16065
+ console.error(error);
16066
+ }
16067
+ }
16068
+ async fetchProducts() {
16069
+ const fetchAndCacheMedia = async () => {
16070
+ if (!this.linkTarget.length) {
16071
+ return { message: this.msgServiceError ?? "", models: [] };
16072
+ }
16073
+ const path = `product/offer?id=${this.linkTarget.join(",")}`;
16074
+ const headers = {
16075
+ accept: "application/json",
16076
+ "Content-Type": "application/json",
16077
+ };
16078
+ const profileKey = "fetch-products";
16079
+ try {
16080
+ const response = await this.sdkApi.sendApiRequest(path, "GET", null, headers, null, profileKey);
16081
+ // console.log({response});
16082
+ const status = response.status;
16083
+ if (status === 200 || status === 201) {
16084
+ if (response.data && Array.isArray(response.data) && response.data.length > 0) {
16085
+ try {
16086
+ await this.cacheOffersMediaResources(response.data);
16087
+ }
16088
+ catch (error) {
16089
+ console.error(error);
16090
+ }
16091
+ return { message: "", models: response.data };
16092
+ }
16093
+ else {
16094
+ return { message: this.msgServiceError ?? "", models: [] };
16095
+ }
16096
+ }
16097
+ else if (status === 12163 || status === 12002) {
16098
+ return { message: this.msgNetworkError ?? "", models: [] };
16099
+ }
16100
+ else {
16101
+ return { message: this.msgServiceError ?? "", models: [] };
16102
+ }
16103
+ }
16104
+ catch (error) {
16105
+ console.error(error);
16106
+ return { message: this.msgServiceError ?? "", models: [] };
16107
+ }
16108
+ };
16109
+ return Promise.all([
16110
+ fetchAndCacheMedia(),
16111
+ new Promise(t => {
16112
+ return setTimeout(t, 200);
16113
+ }),
16114
+ ]).then(([result]) => result);
16115
+ }
16116
+ cacheOffersMediaResources(offers) {
16117
+ const cacheItem = (offer) => {
16118
+ return new Promise(resolve => {
16119
+ if (offer.coverUrl != null) {
16120
+ this.env
16121
+ .fetch(offer.coverUrl)
16122
+ .then(response => {
16123
+ if (response != null && response.ok) {
16124
+ response
16125
+ .blob()
16126
+ .then(blob => {
16127
+ offer.coverUrl = URL.createObjectURL(blob);
16128
+ resolve();
16129
+ })
16130
+ .catch(resolve);
16131
+ }
16132
+ else {
16133
+ resolve();
16134
+ }
16135
+ })
16136
+ .catch(resolve);
16137
+ }
16138
+ else {
16139
+ resolve();
16140
+ }
16141
+ });
16142
+ };
16143
+ const promises = offers.map(cacheItem);
16144
+ return Promise.all(promises);
16145
+ }
16146
+ revokeOffersMediaResources(offers) {
16147
+ offers.forEach(offer => {
16148
+ if (offer.coverUrl != null) {
16149
+ // todo check if coverUrl really is object URL
16150
+ URL.revokeObjectURL(offer.coverUrl);
16151
+ }
16152
+ });
16153
+ }
16154
+ initSwipeGestureDetector() {
16155
+ if (this.isOpen) {
16156
+ if (this.swipeGestureDetector == null) {
16157
+ this.swipeGestureDetector = new SwipeGestureDetector(this.env, this.isScreenSupportsTouch,
16158
+ // detect gestures started on backdrop view
16159
+ (e) => e.target instanceof HTMLElement ? e.target.classList.contains("ias-products-container-backdrop-view") : true, e => {
16160
+ // this.isClickCapturedByWidget = true;
16161
+ return;
16162
+ }, e => {
16163
+ return;
16164
+ }, (e, gesture) => {
16165
+ if (gesture === 3 /* SwipeGesture.SwipeDown */) {
16166
+ this.closeProductsView();
16167
+ }
16168
+ // this.env.requestAnimationFrame(() => {
16169
+ // this.isClickCapturedByWidget = false;
16170
+ // });
16171
+ });
16172
+ }
16173
+ }
16174
+ }
16175
+ productsView = null;
16176
+ isOpen = false;
16177
+ get isForcePaused() {
16178
+ return this.isOpen;
16179
+ }
16180
+ currentModels = [];
16181
+ async openProductsView() {
16182
+ if (this.isOpen) {
16183
+ return;
16184
+ }
16185
+ this._statEventWidgetClick();
16186
+ if (!this.disableTimer) {
16187
+ this.sdkApi.pauseUI();
16188
+ }
16189
+ if (!this.isTransparentElement()) {
16190
+ this.element.classList.add("loader");
16191
+ }
16192
+ // const start = window.performance.now();
16193
+ const result = await this.fetchProducts();
16194
+ // @ts-ignore
16195
+ // _log(`fetched for ${window.performance.now() - start}ms`, true);
16196
+ // console.log({result})
16197
+ if (result.models.length > 0) {
16198
+ this.currentModels = result.models;
16199
+ this.productsView = this.createProductsView(this.currentModels, this.closeProductsView.bind(this));
16200
+ this.productsView.classList.add("ias-products-container-view--visible");
16201
+ this.slide.appendChild(this.productsView);
16202
+ this.element.classList.add("hidden");
16203
+ this.isOpen = true;
16204
+ // prevent next slide navigation gesture
16205
+ this.isClickCapturedByWidget = true;
16206
+ this.sdkApi.disableVerticalSwipeGesture();
16207
+ this.sdkApi.disableBackpress();
16208
+ this._statEventWidgetOpen(this.currentModels);
16209
+ this.initSwipeGestureDetector();
16210
+ }
16211
+ else {
16212
+ if (result.message) {
16213
+ this.sdkApi.showToast(result.message);
16214
+ }
16215
+ }
16216
+ this.element.classList.remove("loader");
16217
+ }
16218
+ closeProductsView() {
16219
+ if (!this.isOpen) {
16220
+ return;
16221
+ }
16222
+ this.productsView?.classList.add("ias-products-container-view--hidden");
16223
+ this.element.classList.remove("hidden");
16224
+ this.isClickCapturedByWidget = false;
16225
+ if (this.swipeGestureDetector != null) {
16226
+ this.swipeGestureDetector.destroy();
16227
+ this.swipeGestureDetector = null;
16228
+ }
16229
+ this.sdkApi.enableVerticalSwipeGesture();
16230
+ this.sdkApi.enableBackpress();
16231
+ const onClosed = () => {
16232
+ this.productsView?.removeEventListener("animationend", onClosed);
16233
+ this.productsView?.parentElement?.removeChild(this.productsView);
16234
+ this.revokeOffersMediaResources(this.currentModels);
16235
+ if (!this.disableTimer) {
16236
+ this.sdkApi.resumeUI();
16237
+ }
16238
+ this.isOpen = false;
16239
+ this.currentModels = [];
16240
+ };
16241
+ this.productsView?.addEventListener("animationend", onClosed);
16242
+ }
16243
+ createCardView(offer) {
16244
+ const figure = document.createElement("div");
16245
+ figure.classList.add("ias-products-card-figure");
16246
+ if (offer.coverUrl) {
16247
+ // todo preload coverImage by fetch, save to offer.coverUrl via createUrl (add revoke)
16248
+ // if cannot fetch - skip caching
16249
+ const image = document.createElement("img");
16250
+ image.classList.add("ias-products-card-figure-image");
16251
+ image.alt = offer.name ?? "";
16252
+ image.src = offer.coverUrl;
16253
+ figure.appendChild(image);
16254
+ }
16255
+ // const subTitle = document.createElement("div");
16256
+ // subTitle.classList.add("ias-products-card-subtitle");
16257
+ // subTitle.innerText = offer.description ?? "";
16258
+ const title = document.createElement("div");
16259
+ title.classList.add("ias-products-card-title");
16260
+ title.innerText = offer.name ?? "";
16261
+ let price = null;
16262
+ if (offer.price) {
16263
+ price = document.createElement("div");
16264
+ price.classList.add("ias-products-card-price");
16265
+ price.innerHTML = formatter.asCurrency(offer.price, offer.currency);
16266
+ }
16267
+ let oldPrice = null;
16268
+ if (offer.oldPrice) {
16269
+ oldPrice = document.createElement("div");
16270
+ oldPrice.classList.add("ias-products-card-old-price");
16271
+ oldPrice.innerHTML = formatter.asCurrency(offer.oldPrice, offer.currency);
16272
+ }
16273
+ const prices = document.createElement("div");
16274
+ prices.classList.add("ias-products-card-prices");
16275
+ if (price) {
16276
+ prices.appendChild(price);
16277
+ }
16278
+ if (oldPrice) {
16279
+ prices.appendChild(oldPrice);
16280
+ }
16281
+ const card = document.createElement("div");
16282
+ card.classList.add("ias-products-card");
16283
+ card.onclick = () => {
16284
+ this._statEventWidgetCardClick(offer);
16285
+ if (offer.url) {
16286
+ this.sdkApi.openUrl(offer.url);
16287
+ }
16288
+ };
16289
+ card.appendChild(figure);
16290
+ // card.appendChild(subTitle);
16291
+ card.appendChild(prices);
16292
+ card.appendChild(title);
16293
+ return card;
16294
+ }
16295
+ createScrollView(offers) {
16296
+ const scrollViewGroup = document.createElement("div");
16297
+ scrollViewGroup.classList.add("ias-products-scroll-view-group");
16298
+ const scrollView = document.createElement("div");
16299
+ scrollView.classList.add("ias-products-scroll-view");
16300
+ offers.forEach(offer => scrollView.appendChild(this.createCardView(offer)));
16301
+ scrollViewGroup.appendChild(scrollView);
16302
+ if (!this.isScreenSupportsTouch) {
16303
+ const { scrollLeft, scrollRight, mountScrollControls } = this.createScrollControls(scrollView);
16304
+ const scrollControlsView = document.createElement("div");
16305
+ scrollControlsView.classList.add("ias-products-scroll-controls-view");
16306
+ const scrollControlStartView = document.createElement("div");
16307
+ scrollControlStartView.classList.add("ias-products-scroll-control-start-view");
16308
+ const scrollControlStartIconView = document.createElement("div");
16309
+ scrollControlStartIconView.classList.add("ias-products-scroll-control-start-icon-view");
16310
+ scrollControlStartView.appendChild(scrollControlStartIconView);
16311
+ scrollControlsView.appendChild(scrollControlStartView);
16312
+ scrollControlStartView.onclick = e => {
16313
+ e.preventDefault();
16314
+ e.stopPropagation();
16315
+ if (this.layoutDirection === "ltr") {
16316
+ scrollLeft();
16317
+ }
16318
+ else {
16319
+ scrollRight();
16320
+ }
16321
+ };
16322
+ const scrollControlEndView = document.createElement("div");
16323
+ scrollControlEndView.classList.add("ias-products-scroll-control-end-view");
16324
+ const scrollControlEndIconView = document.createElement("div");
16325
+ scrollControlEndIconView.classList.add("ias-products-scroll-control-end-icon-view");
16326
+ scrollControlEndView.appendChild(scrollControlEndIconView);
16327
+ scrollControlsView.appendChild(scrollControlEndView);
16328
+ scrollControlEndView.onclick = e => {
16329
+ e.preventDefault();
16330
+ e.stopPropagation();
16331
+ if (this.layoutDirection === "ltr") {
16332
+ scrollRight();
16333
+ }
16334
+ else {
16335
+ scrollLeft();
16336
+ }
16337
+ };
16338
+ mountScrollControls(() => scrollViewGroup.appendChild(scrollControlsView));
16339
+ }
16340
+ return scrollViewGroup;
16341
+ }
16342
+ createProductsView(offers, onClose) {
16343
+ const containerView = document.createElement("div");
16344
+ containerView.classList.add("ias-products-container-view");
16345
+ containerView.dir = this.layoutDirection;
16346
+ const backdropView = document.createElement("div");
16347
+ backdropView.classList.add("ias-products-container-backdrop-view");
16348
+ backdropView.onclick = e => {
16349
+ e.preventDefault();
16350
+ e.stopPropagation();
16351
+ onClose();
16352
+ };
16353
+ const backgroundView = document.createElement("div");
16354
+ backgroundView.classList.add("ias-products-container-background-view");
16355
+ const scrollView = this.createScrollView(offers);
16356
+ const closeButton = document.createElement("div");
16357
+ closeButton.classList.add("ias-products-container-close-button");
16358
+ // fill=${ProductsWidgetOptionsDefault.productsList.closeBackgroundColor}
16359
+ closeButton.innerHTML = `<svg width="32" height="12.5" viewBox="0 0 64 25" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M56.293 1.23375C58.054 -0.41125 60.846 -0.41125 62.607 1.23375C64.464 2.96775 64.464 5.85675 62.607 7.59075L35.157 23.2288C33.396 24.8738 30.604 24.8738 28.843 23.2288L1.393 7.59075C0.494002 6.75175 0 5.62775 0 4.41275C0 3.19775 0.494002 2.07375 1.393 1.23475C3.154 -0.410251 5.946 -0.410251 7.707 1.23475L32 13.9237L56.293 1.23375Z" fill="currentColor" /></svg>`;
16360
+ closeButton.onclick = e => {
16361
+ e.preventDefault();
16362
+ e.stopPropagation();
16363
+ onClose();
16364
+ };
16365
+ backgroundView.appendChild(scrollView);
16366
+ backgroundView.appendChild(closeButton);
16367
+ containerView.appendChild(backdropView);
16368
+ containerView.appendChild(backgroundView);
16369
+ return containerView;
16370
+ }
16371
+ scrollViewRef = null;
16372
+ getScrollLeft() {
16373
+ if (this.scrollViewRef != null) {
16374
+ return this.scrollViewRef.scrollLeft;
16375
+ }
16376
+ return 0;
16377
+ }
16378
+ getScrollViewportWidth() {
16379
+ if (this.scrollViewRef != null) {
16380
+ return this.scrollViewRef.clientWidth;
16381
+ }
16382
+ return 0;
16383
+ }
16384
+ setScrollLeft(value) {
16385
+ if (this.scrollViewRef != null) {
16386
+ this.scrollViewRef.scrollLeft = Math.round(value);
16387
+ }
16388
+ }
16389
+ createScrollControls(scrollViewRef) {
16390
+ this.scrollViewRef = scrollViewRef;
16391
+ return {
16392
+ scrollLeft: () => this.setScrollLeft(this.getScrollLeft() - this.getScrollViewportWidth()),
16393
+ scrollRight: () => this.setScrollLeft(this.getScrollLeft() + this.getScrollViewportWidth()),
16394
+ mountScrollControls: (cb) => this.env.requestAnimationFrame(() => scrollViewRef.scrollWidth > scrollViewRef.clientWidth && cb()),
16395
+ };
16396
+ }
16397
+ getIsClickCapturedByWidget() {
16398
+ return this.isClickCapturedByWidget;
16399
+ }
16400
+ destroy() {
16401
+ if (this.swipeGestureDetector != null) {
16402
+ this.swipeGestureDetector.destroy();
16403
+ this.swipeGestureDetector = null;
16404
+ }
16405
+ }
16406
+ onStop() {
16407
+ super.onStop();
16408
+ this.destroy();
16409
+ }
16410
+ static api = {
16411
+ widgetClassName: WidgetProducts.widgetClassName,
16412
+ onRefreshUserData: WidgetProducts.onRefreshUserData,
16413
+ init: function (element, localData) {
16414
+ WidgetProducts.initWidget(element, localData, (element, options) => new WidgetProducts(element, options));
16415
+ },
16416
+ onStart: function (element) {
16417
+ WidgetProducts.getInstance(element)?.onStart();
16418
+ },
16419
+ onStop: function (element) {
16420
+ WidgetProducts.getInstance(element)?.onStop();
16421
+ },
16422
+ click: function (element) {
16423
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16424
+ if (widgetElement) {
16425
+ const widget = WidgetProducts.getInstance(widgetElement);
16426
+ if (widget) {
16427
+ widget.openProductsView();
16428
+ }
16429
+ }
16430
+ return false;
16431
+ },
16432
+ isClickCapturedByWidget: function (element) {
16433
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16434
+ if (widgetElement) {
16435
+ const widget = WidgetProducts.getInstance(widgetElement);
16436
+ if (widget) {
16437
+ return widget.getIsClickCapturedByWidget();
16438
+ }
16439
+ }
16440
+ return false;
16441
+ },
16442
+ isForcePaused: function (element) {
16443
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16444
+ if (widgetElement) {
16445
+ const widget = WidgetProducts.getInstance(widgetElement);
16446
+ if (widget) {
16447
+ return widget.isForcePaused;
16448
+ }
16449
+ }
16450
+ return false;
16451
+ },
16452
+ onHandleBackpress: function (element) {
16453
+ const widgetElement = element.closest(`.${WidgetProducts.widgetClassName}`);
16454
+ if (widgetElement) {
16455
+ const widget = WidgetProducts.getInstance(widgetElement);
16456
+ if (widget) {
16457
+ widget.closeProductsView();
16458
+ }
16459
+ }
16460
+ return false;
16461
+ },
16462
+ };
16463
+ static get [Symbol.for("___CTOR_ARGS___")]() { return [`HTMLElement`, `Partial`]; }
16464
+ }
16465
+
15283
16466
  let sdkInterface;
15284
16467
  const getSlideApi = (_sdkInterface) => {
15285
16468
  sdkInterface = _sdkInterface;
@@ -15300,6 +16483,7 @@ const getSlideApi = (_sdkInterface) => {
15300
16483
  WidgetTest: WidgetTest.api,
15301
16484
  WidgetVote: WidgetVote.api,
15302
16485
  WidgetBarcode: WidgetBarcode.api,
16486
+ WidgetProducts: WidgetProducts.api,
15303
16487
  };
15304
16488
  };
15305
16489