stormcloud-video-player 0.6.7 → 0.6.9

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.
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { StormcloudVideoPlayer } from '../player/StormcloudVideoPlayer.cjs';
3
- import { S as StormcloudVideoPlayerConfig } from '../types-BYwfSJb5.cjs';
3
+ import { S as StormcloudVideoPlayerConfig } from '../types-DSKC4ySr.cjs';
4
4
 
5
5
  type StormcloudVideoPlayerProps = Omit<StormcloudVideoPlayerConfig, "videoElement"> & React.VideoHTMLAttributes<HTMLVideoElement> & {
6
6
  onReady?: (player: StormcloudVideoPlayer) => void;
@@ -56,30 +56,6 @@ function _object_spread(target) {
56
56
  }
57
57
  return target;
58
58
  }
59
- function ownKeys(object, enumerableOnly) {
60
- var keys = Object.keys(object);
61
- if (Object.getOwnPropertySymbols) {
62
- var symbols = Object.getOwnPropertySymbols(object);
63
- if (enumerableOnly) {
64
- symbols = symbols.filter(function(sym) {
65
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
66
- });
67
- }
68
- keys.push.apply(keys, symbols);
69
- }
70
- return keys;
71
- }
72
- function _object_spread_props(target, source) {
73
- source = source != null ? source : {};
74
- if (Object.getOwnPropertyDescriptors) {
75
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
76
- } else {
77
- ownKeys(Object(source)).forEach(function(key) {
78
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
79
- });
80
- }
81
- return target;
82
- }
83
59
  function _type_of(obj) {
84
60
  "@swc/helpers - typeof";
85
61
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
@@ -484,24 +460,30 @@ function getBrowserID(clientInfo) {
484
460
  });
485
461
  })();
486
462
  }
487
- var TRACK_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
463
+ var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
464
+ var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
465
+ var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
466
+ var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
467
+ function buildHeaders(licenseKey) {
468
+ var headers = {
469
+ "Content-Type": "application/json"
470
+ };
471
+ if (licenseKey) {
472
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
473
+ }
474
+ return headers;
475
+ }
488
476
  function sendTrackRequest(licenseKey, body) {
489
477
  return _async_to_generator(function() {
490
- var headers, response;
478
+ var response;
491
479
  return _ts_generator(this, function(_state) {
492
480
  switch(_state.label){
493
481
  case 0:
494
- headers = {
495
- "Content-Type": "application/json"
496
- };
497
- if (licenseKey) {
498
- headers["Authorization"] = "Bearer ".concat(licenseKey);
499
- }
500
482
  return [
501
483
  4,
502
484
  fetch(TRACK_URL, {
503
485
  method: "POST",
504
- headers: headers,
486
+ headers: buildHeaders(licenseKey),
505
487
  body: JSON.stringify(body)
506
488
  })
507
489
  ];
@@ -523,14 +505,86 @@ function sendTrackRequest(licenseKey, body) {
523
505
  });
524
506
  })();
525
507
  }
526
- function sendInitialTracking(licenseKey) {
508
+ function postJson(url, licenseKey, body) {
527
509
  return _async_to_generator(function() {
528
- var clientInfo, browserId, trackingData, headers, response, error;
510
+ var response;
511
+ return _ts_generator(this, function(_state) {
512
+ switch(_state.label){
513
+ case 0:
514
+ return [
515
+ 4,
516
+ fetch(url, {
517
+ method: "POST",
518
+ headers: buildHeaders(licenseKey),
519
+ body: JSON.stringify(body)
520
+ })
521
+ ];
522
+ case 1:
523
+ response = _state.sent();
524
+ if (!response.ok) {
525
+ throw new Error("HTTP error! status: ".concat(response.status));
526
+ }
527
+ return [
528
+ 4,
529
+ response.json()
530
+ ];
531
+ case 2:
532
+ _state.sent();
533
+ return [
534
+ 2
535
+ ];
536
+ }
537
+ });
538
+ })();
539
+ }
540
+ function buildPlayerMetricEvent(_0) {
541
+ return _async_to_generator(function(licenseKey) {
542
+ var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
543
+ var _arguments = arguments;
529
544
  return _ts_generator(this, function(_state) {
530
545
  switch(_state.label){
531
546
  case 0:
547
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
548
+ clientInfo = getClientInfo();
549
+ return [
550
+ 4,
551
+ getBrowserID(clientInfo)
552
+ ];
553
+ case 1:
554
+ browserId = _state.sent();
555
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
556
+ return [
557
+ 2,
558
+ {
559
+ player_id: browserId,
560
+ browserId: browserId,
561
+ device_type: clientInfo.deviceType,
562
+ deviceType: clientInfo.deviceType,
563
+ input_stream_type: context.inputStreamType,
564
+ os: clientInfo.os,
565
+ ad_loaded: flags.adLoaded,
566
+ ad_detect: flags.adDetect,
567
+ license_key: licenseKey,
568
+ capture_at: captureAt,
569
+ timestamp: captureAt
570
+ }
571
+ ];
572
+ }
573
+ });
574
+ }).apply(this, arguments);
575
+ }
576
+ function sendInitialTracking(_0) {
577
+ return _async_to_generator(function(licenseKey) {
578
+ var context, clientInfo, browserId, trackingData, error;
579
+ var _arguments = arguments;
580
+ return _ts_generator(this, function(_state) {
581
+ switch(_state.label){
582
+ case 0:
583
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
584
+ _state.label = 1;
585
+ case 1:
532
586
  _state.trys.push([
533
- 0,
587
+ 1,
534
588
  4,
535
589
  ,
536
590
  5
@@ -540,34 +594,29 @@ function sendInitialTracking(licenseKey) {
540
594
  4,
541
595
  getBrowserID(clientInfo)
542
596
  ];
543
- case 1:
597
+ case 2:
544
598
  browserId = _state.sent();
545
599
  trackingData = _object_spread({
546
600
  browserId: browserId
547
601
  }, clientInfo);
548
- headers = {
549
- "Content-Type": "application/json"
550
- };
551
- if (licenseKey) {
552
- headers["Authorization"] = "Bearer ".concat(licenseKey);
553
- }
554
602
  return [
555
603
  4,
556
- fetch(TRACK_URL, {
557
- method: "POST",
558
- headers: headers,
559
- body: JSON.stringify(trackingData)
604
+ sendTrackRequest(licenseKey, {
605
+ events: [
606
+ {
607
+ player_id: browserId,
608
+ device_type: clientInfo.deviceType,
609
+ input_stream_type: context.inputStreamType,
610
+ os: clientInfo.os,
611
+ ad_loaded: false,
612
+ ad_detect: false,
613
+ license_key: licenseKey,
614
+ capture_at: /* @__PURE__ */ new Date().toISOString()
615
+ }
616
+ ],
617
+ trackingData: trackingData
560
618
  })
561
619
  ];
562
- case 2:
563
- response = _state.sent();
564
- if (!response.ok) {
565
- throw new Error("HTTP error! status: ".concat(response.status));
566
- }
567
- return [
568
- 4,
569
- response.json()
570
- ];
571
620
  case 3:
572
621
  _state.sent();
573
622
  return [
@@ -587,36 +636,30 @@ function sendInitialTracking(licenseKey) {
587
636
  ];
588
637
  }
589
638
  });
590
- })();
639
+ }).apply(this, arguments);
591
640
  }
592
- function sendAdDetectTracking(licenseKey, adDetectInfo) {
593
- return _async_to_generator(function() {
594
- var clientInfo, browserId, trackingData, error;
641
+ function sendAdDetectTracking(_0, _1) {
642
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
643
+ var context, error;
644
+ var _arguments = arguments;
595
645
  return _ts_generator(this, function(_state) {
596
646
  switch(_state.label){
597
647
  case 0:
648
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
649
+ _state.label = 1;
650
+ case 1:
598
651
  _state.trys.push([
599
- 0,
652
+ 1,
600
653
  3,
601
654
  ,
602
655
  4
603
656
  ]);
604
- clientInfo = getClientInfo();
605
- return [
606
- 4,
607
- getBrowserID(clientInfo)
608
- ];
609
- case 1:
610
- browserId = _state.sent();
611
- trackingData = _object_spread({
612
- browserId: browserId
613
- }, clientInfo);
614
657
  return [
615
658
  4,
616
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
617
- licenseKey: licenseKey,
618
- adDetectInfo: adDetectInfo
619
- }))
659
+ sendHeartbeat(licenseKey, context, {
660
+ adDetect: true,
661
+ captureAt: adDetectInfo.timestamp
662
+ })
620
663
  ];
621
664
  case 2:
622
665
  _state.sent();
@@ -637,36 +680,30 @@ function sendAdDetectTracking(licenseKey, adDetectInfo) {
637
680
  ];
638
681
  }
639
682
  });
640
- })();
683
+ }).apply(this, arguments);
641
684
  }
642
- function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
643
- return _async_to_generator(function() {
644
- var clientInfo, browserId, trackingData, error;
685
+ function sendAdLoadedTracking(_0, _1) {
686
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
687
+ var context, error;
688
+ var _arguments = arguments;
645
689
  return _ts_generator(this, function(_state) {
646
690
  switch(_state.label){
647
691
  case 0:
692
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
693
+ _state.label = 1;
694
+ case 1:
648
695
  _state.trys.push([
649
- 0,
696
+ 1,
650
697
  3,
651
698
  ,
652
699
  4
653
700
  ]);
654
- clientInfo = getClientInfo();
655
- return [
656
- 4,
657
- getBrowserID(clientInfo)
658
- ];
659
- case 1:
660
- browserId = _state.sent();
661
- trackingData = _object_spread({
662
- browserId: browserId
663
- }, clientInfo);
664
701
  return [
665
702
  4,
666
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
667
- licenseKey: licenseKey,
668
- adLoadedInfo: adLoadedInfo
669
- }))
703
+ sendHeartbeat(licenseKey, context, {
704
+ adLoaded: true,
705
+ captureAt: adLoadedInfo.timestamp
706
+ })
670
707
  ];
671
708
  case 2:
672
709
  _state.sent();
@@ -687,103 +724,95 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
687
724
  ];
688
725
  }
689
726
  });
690
- })();
727
+ }).apply(this, arguments);
691
728
  }
692
- function sendAdImpressionTracking(licenseKey, adImpressionInfo) {
693
- return _async_to_generator(function() {
694
- var clientInfo, browserId, trackingData, error;
729
+ function sendAdImpressionTracking(_0, _1) {
730
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
731
+ var context, metricEvent, error;
732
+ var _arguments = arguments;
695
733
  return _ts_generator(this, function(_state) {
696
734
  switch(_state.label){
697
735
  case 0:
736
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
737
+ _state.label = 1;
738
+ case 1:
698
739
  _state.trys.push([
699
- 0,
700
- 3,
740
+ 1,
741
+ 4,
701
742
  ,
702
- 4
743
+ 5
703
744
  ]);
704
- clientInfo = getClientInfo();
705
745
  return [
706
746
  4,
707
- getBrowserID(clientInfo)
747
+ buildPlayerMetricEvent(licenseKey, context, {
748
+ captureAt: adImpressionInfo.timestamp
749
+ })
708
750
  ];
709
- case 1:
710
- browserId = _state.sent();
711
- trackingData = _object_spread({
712
- browserId: browserId
713
- }, clientInfo);
751
+ case 2:
752
+ metricEvent = _state.sent();
714
753
  return [
715
754
  4,
716
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
717
- licenseKey: licenseKey,
718
- adImpressionInfo: adImpressionInfo
719
- }))
755
+ Promise.all([
756
+ postJson(HEARTBEAT_URL, licenseKey, metricEvent),
757
+ postJson(IMPRESSIONS_URL, licenseKey, {
758
+ events: [
759
+ {
760
+ player_id: metricEvent.player_id,
761
+ ad_played_count: 1,
762
+ ad_url: adImpressionInfo.adUrl,
763
+ license_key: licenseKey,
764
+ capture_at: adImpressionInfo.timestamp
765
+ }
766
+ ]
767
+ })
768
+ ])
720
769
  ];
721
- case 2:
770
+ case 3:
722
771
  _state.sent();
723
772
  return [
724
773
  3,
725
- 4
774
+ 5
726
775
  ];
727
- case 3:
776
+ case 4:
728
777
  error = _state.sent();
729
778
  console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
730
779
  return [
731
780
  3,
732
- 4
781
+ 5
733
782
  ];
734
- case 4:
783
+ case 5:
735
784
  return [
736
785
  2
737
786
  ];
738
787
  }
739
788
  });
740
- })();
789
+ }).apply(this, arguments);
741
790
  }
742
- function sendHeartbeat(licenseKey) {
743
- return _async_to_generator(function() {
744
- var clientInfo, browserId, heartbeatData, headers, response, error;
791
+ function sendHeartbeat(_0) {
792
+ return _async_to_generator(function(licenseKey) {
793
+ var context, flags, heartbeatData, error;
794
+ var _arguments = arguments;
745
795
  return _ts_generator(this, function(_state) {
746
796
  switch(_state.label){
747
797
  case 0:
798
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
799
+ _state.label = 1;
800
+ case 1:
748
801
  _state.trys.push([
749
- 0,
802
+ 1,
750
803
  4,
751
804
  ,
752
805
  5
753
806
  ]);
754
- clientInfo = getClientInfo();
755
807
  return [
756
808
  4,
757
- getBrowserID(clientInfo)
758
- ];
759
- case 1:
760
- browserId = _state.sent();
761
- heartbeatData = {
762
- browserId: browserId,
763
- timestamp: /* @__PURE__ */ new Date().toISOString()
764
- };
765
- headers = {
766
- "Content-Type": "application/json"
767
- };
768
- if (licenseKey) {
769
- headers["Authorization"] = "Bearer ".concat(licenseKey);
770
- }
771
- return [
772
- 4,
773
- fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
774
- method: "POST",
775
- headers: headers,
776
- body: JSON.stringify(heartbeatData)
777
- })
809
+ buildPlayerMetricEvent(licenseKey, context, flags)
778
810
  ];
779
811
  case 2:
780
- response = _state.sent();
781
- if (!response.ok) {
782
- throw new Error("HTTP error! status: ".concat(response.status));
783
- }
812
+ heartbeatData = _state.sent();
784
813
  return [
785
814
  4,
786
- response.json()
815
+ postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
787
816
  ];
788
817
  case 3:
789
818
  _state.sent();
@@ -804,7 +833,7 @@ function sendHeartbeat(licenseKey) {
804
833
  ];
805
834
  }
806
835
  });
807
- })();
836
+ }).apply(this, arguments);
808
837
  }
809
838
  // Annotate the CommonJS export names for ESM import in node:
810
839
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/utils/tracking.cjs","../../src/utils/tracking.ts"],"names":["__defProp","Object","__getOwnPropDesc","__getOwnPropNames","enumerable","defineProperty","getOwnPropertyDescriptor","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","__copyProps","to","from","except","desc","key","__toCommonJS","mod","value","tracking_exports","getClientInfo","exports","getBrowserID","sendAdDetectTracking","sendAdImpressionTracking","sendAdLoadedTracking","sendHeartbeat","sendInitialTracking","cachedBrowserId","screen","window","navigator","vendor","maxTouchPoints","hardwareConcurrency","screenInfo","width","height","availWidth","availHeight","orientation","type","deviceType","brand","os","isAndroid","isWebView","ua","includes","isSmartTV","webosMatch","match","model","tizenMatch","tvMatch","trim","test","androidModelMatch"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4CACIA,EAAYC,IACZC,QACAC,GAI0CC,YAAiB,WAC/D,SAGS,iCAAA,QAAA,WAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAVLJ,OAAYC,EAAOI,OAAAA,OAAc,YAAA;wBACjCH,SAAmBD,IAAAA,GAAOK,QAAAA,KAAAA,MAAAA,KAAwB;wBAClDH,IAAAA,IAAAA,GAAoBF,IAAAA,GAAOM,EAAAA,MAAAA,EAAAA,IAAAA,IAAmB;4BAC9CC,MAAAA,CAAAA,EAAeP,GAAAA,IAAOQ,CAAAA,QAAS,CAACC,CAAAA,CAAAA,YAAc;wBAC9CC,OAAW,kBAACC,QAAQC;wBACjB,IAAIC,QAAQD,EAAAA,EACfb,UAAUY,QAAQE,MAAM;sBAAEC,KAAKF,GAAG,CAACC,KAAK;oBAAc;;wBAAA,OAAA,MAAA,CAAA,MAAA,CAAA,WAAA;;;oBAAZV,QAAY,KAAA;oBAAK,YAAA,MAAA,IAAA,CAAA,IAAA,WAAA;oBAC/D,UAAA,UAAA,GAAA,CAAA,SAAA;+BAAA,EAAA,QAAA,CAAA,IAAA,QAAA,CAAA,GAAA;uBAAA,IAAA,CAAA;oBACIY,YAAc,MAAA,eAACC,IAAIC,MAAMC,QAAQC;oBACnC,EAAIF;;wBAAAA,GAAQ,CAAA,OAAOA,qCAAP,SAAOA,KAAG,MAAM,YAAY,OAAOA,SAAS,YAAY;;;oBAC7D;;;;;;;6CAE+BA,IAAI,CAACG,IAAI;;kCAAEjB,YAAY,CAAEgB,CAAAA,CAAAA,MAAOlB,IAAAA,CAAAA,YAAiBgB,MAAMG,IAAG,KAAMD,KAAKhB,UAAU;oCAAC,IAAA,CAAA,IAAA,OAAA;;8BAFpH,QAAK,YAAWD,kBAAkBe,0BAA7B,SAAA,6BAAA,QAAA,yBAAA;;gCAAA,KAAA,GAAA,GAAA,QAAA,CAAA,IAAA,QAAA,CAAA,IAAA;6BAAA,KAAA,MAAA,GAAA,QAAA,CAAA,IAAA,SAAA,CAAA,GAAA,IAAA,QAAA,CAAA,IAAA;;;;;;;;yBAAA,6BAAA;;oBAAA;;;qBAGP;;;;;wCAHO;4CAAA;;;;oBAGP;;wBAAA,MAAA,WAAA;4BACA,OAAOD,CAAAA;4BACT,SAAA;4BACIK,MAAAA,KAAAA,IAAe,KAAA,CAAA,gBAACC;iCAAQP,YAAYhB,UAAU,CAAC,GAAG,cAAc;;;oBAHlE,WAAA;0BAGoEwB,OAAO,CAAA,EAAA,EAAA;wBAAK,IAAID,EAAAA,IAAAA,MAAAA,uBAAAA,OAAAA,SAAAA,MAAAA;;oBAEtF;;wBAAA,SAAA,IAAA,GAAwB;;;oBAAxB;;;;;;ICnBA,IAAAE,mBAAA,CAAA;;AAAAd,SAAAc,YAAA,QAAA,UAAA;;mCAAAC,SAAA,wBAAAC,GAAA,GAAAL,aAAAG;;;;;;;;;;yBAAAG,QAAAA;;;;;;;oBAAAF,eAAA,GAAAA;4CAAAA;;yBAAAG,KAAAA;;oBAAAC,0BAAA,SAAAA;+BAAAA,KAAAA;;oBAAAC,sBAAA,SAAAA;oBAAAA;;wBAAAA,MAAAA,WAAAA;;4BAAAC,SAAAA,IAAA,SAAAA;qCAAAA,EAAAA,SAAAA,CAAAA;;;;yBAAAD,MAAAA;oBAAAE,IAAAA,CAAAA,SAAAA,EAAAA,EAAAA,GAAA,SAAAA;iCAAAA,CAAAA,MAAAA,uBAAAA,OAAAA,SAAAA,MAAAA;;oBAAA;;wBAAA,SAAA,IAAA;;;oBAAA;;;;;;oBAAAN;oBASIO,QAAAA,KAAAA,CAEG,GAASR,CAFqB,8DAW1BS,SACCA,UACIA,UACCA,UACCA,qBAAAA,UACFA,UAwHVC,SAA6BA,UAO/BA,4BAAAA,gBAsBWC;;;;;;;;;;;QAhKb,IAAMC,SAASD,UAAUC,MAAA,IAAU;;IACnC,IAAMC,CAAAA,UAAiBF,UAAUE,CAAAA,UAAAA,EAAAA,CAAA,IAAkB,OAAA;;YAE7CC,YAEAC,WAAa,AACjBC,GAAA,GAAOP,QAMT;;;;;;;;;;oBATMK,aAAAA,OAAsBH,UAAUG,mBAAA,IAAuB;oBAE1C;;wBAAA,aAAA;;;oBAAbC,YAAa;oBACjBC,eAAOP,CAAAA;wBAAAA,WAAAA;uBAAAA,KAAAA,8BAAAA,QAAQO,KAAA;;;wBACfC,IAAA,GAAQR,UAAAA,CAAAA,WAAAA,SAAAA,+BAAAA,AACRS,SADgBD,AAChB,GAAYR,GADI,QACJA,oBAAAA,+BAAAA,SAAQS,UAAA;0CACpBC,WAAA,GAAaV,WAAAA,oBAAAA,+BAAAA,SAAQU,WAAA;8BACrBC,aAAcX,EAAAA,WAAAA,oBAAAA,gCAAAA,sBAAAA,SAAQW,WAAA,cAARX,0CAAAA,oBAA6BY,IAAA,KAAQ;;;;wBAHnDJ;;;;;;oBAKF;oBAEA,IAAIK,IAAAA,KAAAA,CACJ,EAAIC,CADqD,OAC7C,mDACZ,EAAIC,KAAK;;;;;;;;;;;QAGT,IAAIC,YAAY;;IAChB,IAAIC,CAAAA,KAAY,gBAAA,UAAA,EAAA,YAAA;;YAGZC,CAAGC,QAAA,CAAS,EACdL,MAAQ,KACRC,cAMAD;;;;;;;;;;oBAREI,aAAY,OAAU;oBAChB;;wBAAA,aAAA;;;oBAARJ,YAAQ;oBACRC,GAAK,YAAA;wBAAA,WAAA;uBAAA;;;wBACLK,UAAY,OAAA,YAAA,wCACZP,YAAa;0CACb,IAAMQ,aAAaH,GAAGI,KAAA,CAAM;4CAC5BC,QAAQF,aAAa,SAAsB,OAAbA,UAAA,CAAW,EAAE,IAAK;;;;wBAHhDD;;;;;;oBAKAN,KAAQ;wBACRC,IAAAA,CAAK,IAAA,GACLK,YAAY,iDACZP,aAAa;;;;;;;;;;;YAGbU,QAAQC,aACJ,SAA0BC,OAAjBD,UAAA,CAAW,EAAE,EAAA,KAAW,OAAPC,SAAUC,IAAA,KACpC;;IACN,KAAWR,EAAX,CAAcC,QAAA,CAAS,YAAY,CAAA,UAAA,EAAA,gBAAA;;YAEjCJ,YACAK,WACAP,cAMF,IACEK,GAAGC,QAAA,CAAS,cACXD,CAAAA,GAAGC,QAAA,CAAS,WAAWhB,OAAOgB,QAAA,CAAS,OAAM,GAC9C;;;;;;;;;;oBAXAJ,GAAK,UAAA;oBACO;;wBAAA,aAAA;;;oBAAZK,UAAY,EAAA;oBACZP,WAAa,IAAA;wBAAA,WAAA;uBAAA;;;wBACf,CAAA,IAAWK,GAAGC,QAAA,CAAS,YAAYD,GAAGC,QAAA,CAAS,UAAU,kBACvDL,OAAQ;0CACRC,KAAK;gDACLK,YAAY;;;;oBAHd;;;;;;;wBASEN,IAAAA,IAAQ,CAAA,GACRC,KAAK,4DACLK,YAAY;;;;;;;;;;;YAMZN,QAAQ;;QACRC,CAAK,IAAA,UAAA,UAAA;;YAELF,YACF,WACEC,MAAQ,SAIV,SAOII,UAmBF;;;;;;;;;;oBAhCAL,WAAa,EAAA;oBACDM;;wBAAS,WAAYD,EAAAA,CAAGC,QAAA,CAAS,UAAU;;;oBAAzD,CAAA,IAAWD,GAAGC,IAAAA,IAAA,CAAS;oBACrBL,gBAAQ;qCACRC,KAAK;0BACLK,SAAAA,EAAY,WAAA,GAAA,IAAA,OAAA,WAAA;wBACZP,aAAa;oBACf,CAAA,IAAWK,GAAGC,EAAAA,MAAA,CAAS,YAAY;0BACjCL,QAAQ,MAAA;wBACRC,KAAK;wBACLK,YAAY;0BACZP,KAAAA,CAAAA,OAAa,SAAA,GAAA,UAAA,OAAA;oBACf;oBAEgB;;wBAAA,KAAY,GAC1BG,YAAY,4DACZD,KAAK;4BACLF,QAAAA,KAAa,SAASc,IAAA,CAAKT,MAAM,WAAW;qCAE5C,IACEA,GAAGC,QAAA,CAAS,cACXf,CAAAA,mBAAmB,KAClBc,GAAGC,QAAA,CAAS,gBACZD,GAAGC,QAAA,CAAS,SAAQ,GACtB;gCACAN,EAAAA,KAAAA,MAAa,GAAA,CAAA;8BACbO,YAAY;;;oBAZZF,CAAGC,QAAA,CAAS,CAAA;wBAcd,CAAA,SAAA,EAAA,EAAA;0BAEA,IAAMS,IAAAA,MAAAA,SAAoBV,GAAGI,KAAA,CAAM,KAAA,OAAA,SAAA,MAAA;wBACnC,IAAIM,qBAAqBA,iBAAA,CAAkB,EAAC,EAAG;;;0BAC7CL,OAAAA,CAAQK,GAAAA,cAAA,CAAkB,EAAC;;;;;;;;;oBAC7B;oBACF,QAAA,KAAA,CAAA,oDAAA;;;;;;;;;;;YAGEb,KAAK;;QACLF,aAAa,wCAAA;QACbC,KAAAA,GAAQ,IAAA,GAAA;wBACR,IAAIZ,UAAUE,cAAA,GAAiB,KAAK,OAAOuB,IAAA,CAAKT,KAAK;6BACnDL,aAAa;gCACf;gCACF;4BAEA,IAAI,CAACG,aAAa,CAACI,aAAa,CAAC,SAASO,IAAA,CAAKT,KAAK;yBAClD,IAAIA,GAAGC,QAAA,CAAS,YAAY;mCAC1BJ,KAAK;aACLF,aAAa","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/utils/tracking.ts\nvar tracking_exports = {};\n__export(tracking_exports, {\n getBrowserID: () => getBrowserID,\n getClientInfo: () => getClientInfo,\n sendAdDetectTracking: () => sendAdDetectTracking,\n sendAdImpressionTracking: () => sendAdImpressionTracking,\n sendAdLoadedTracking: () => sendAdLoadedTracking,\n sendHeartbeat: () => sendHeartbeat,\n sendInitialTracking: () => sendInitialTracking\n});\nmodule.exports = __toCommonJS(tracking_exports);\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar TRACK_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\nasync function sendTrackRequest(licenseKey, body) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n getBrowserID,\n getClientInfo,\n sendAdDetectTracking,\n sendAdImpressionTracking,\n sendAdLoadedTracking,\n sendHeartbeat,\n sendInitialTracking\n});\n","import type {\n ClientInfo,\n TrackingData,\n HeartbeatData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst TRACK_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/utils/tracking.cjs","../../src/utils/tracking.ts"],"names":["name","all","__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","get","enumerable","__copyProps","to","from","except","desc","key","value","mod","tracking_exports","getBrowserID","call","getClientInfo","sendAdDetectTracking","sendAdImpressionTracking","sendAdLoadedTracking","sendHeartbeat","sendInitialTracking","module","exports","__toCommonJS","cachedBrowserId","screen","window","navigator","ua","userAgent","platform","vendor","maxTouchPoints","deviceMemory","hardwareConcurrency","screenInfo","width","height","memory","availWidth","availHeight","orientation","type","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","includes","webosMatch","match","tvMatch","tizenMatch","trim","test","androidModelMatch","outerHeight","outerWidth","domain","substring","location","hostname","origin","language","languages","join","cookieEnabled","doNotTrack"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/utils/tracking.ts\nvar tracking_exports = {};\n__export(tracking_exports, {\n getBrowserID: () => getBrowserID,\n getClientInfo: () => getClientInfo,\n sendAdDetectTracking: () => sendAdDetectTracking,\n sendAdImpressionTracking: () => sendAdImpressionTracking,\n sendAdLoadedTracking: () => sendAdLoadedTracking,\n sendHeartbeat: () => sendHeartbeat,\n sendInitialTracking: () => sendInitialTracking\n});\nmodule.exports = __toCommonJS(tracking_exports);\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar PLAYER_TRACKING_BASE_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking\";\nvar TRACK_URL = `${PLAYER_TRACKING_BASE_URL}/metrics/ingest`;\nvar HEARTBEAT_URL = `${PLAYER_TRACKING_BASE_URL}/heartbeat`;\nvar IMPRESSIONS_URL = `${PLAYER_TRACKING_BASE_URL}/impressions/ingest`;\nfunction buildHeaders(licenseKey) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n return headers;\n}\nasync function sendTrackRequest(licenseKey, body) {\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function postJson(url, licenseKey, body) {\n const response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function buildPlayerMetricEvent(licenseKey, context = {}, flags = {}) {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n return {\n player_id: browserId,\n browserId,\n device_type: clientInfo.deviceType,\n deviceType: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: flags.adLoaded,\n ad_detect: flags.adDetect,\n license_key: licenseKey,\n capture_at: captureAt,\n timestamp: captureAt\n };\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n await sendTrackRequest(licenseKey, {\n events: [\n {\n player_id: browserId,\n device_type: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: false,\n ad_detect: false,\n license_key: licenseKey,\n capture_at: (/* @__PURE__ */ new Date()).toISOString()\n }\n ],\n trackingData\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n try {\n await sendHeartbeat(licenseKey, context, {\n adDetect: true,\n captureAt: adDetectInfo.timestamp\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n try {\n await sendHeartbeat(licenseKey, context, {\n adLoaded: true,\n captureAt: adLoadedInfo.timestamp\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n try {\n const metricEvent = await buildPlayerMetricEvent(licenseKey, context, {\n captureAt: adImpressionInfo.timestamp\n });\n await Promise.all([\n postJson(HEARTBEAT_URL, licenseKey, metricEvent),\n postJson(IMPRESSIONS_URL, licenseKey, {\n events: [\n {\n player_id: metricEvent.player_id,\n ad_played_count: 1,\n ad_url: adImpressionInfo.adUrl,\n license_key: licenseKey,\n capture_at: adImpressionInfo.timestamp\n }\n ]\n })\n ]);\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n try {\n const heartbeatData = await buildPlayerMetricEvent(\n licenseKey,\n context,\n flags\n );\n await postJson(HEARTBEAT_URL, licenseKey, heartbeatData);\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n getBrowserID,\n getClientInfo,\n sendAdDetectTracking,\n sendAdImpressionTracking,\n sendAdLoadedTracking,\n sendHeartbeat,\n sendInitialTracking\n});\n","import type {\n ClientInfo,\n TrackingData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n PlayerAnalyticsContext,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst PLAYER_TRACKING_BASE_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking\";\nconst TRACK_URL = `${PLAYER_TRACKING_BASE_URL}/metrics/ingest`;\nconst HEARTBEAT_URL = `${PLAYER_TRACKING_BASE_URL}/heartbeat`;\nconst IMPRESSIONS_URL = `${PLAYER_TRACKING_BASE_URL}/impressions/ingest`;\n\ntype PlayerMetricFlags = {\n adLoaded?: boolean;\n adDetect?: boolean;\n captureAt?: string;\n};\n\nfunction buildHeaders(licenseKey: string | undefined): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n return headers;\n}\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nasync function postJson(\n url: string,\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nasync function buildPlayerMetricEvent(\n licenseKey: string | undefined,\n context: PlayerAnalyticsContext = {},\n flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const captureAt = flags.captureAt ?? new Date().toISOString();\n\n return {\n player_id: browserId,\n browserId,\n device_type: clientInfo.deviceType,\n deviceType: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: flags.adLoaded,\n ad_detect: flags.adDetect,\n license_key: licenseKey,\n capture_at: captureAt,\n timestamp: captureAt,\n };\n}\n\nexport async function sendInitialTracking(\n licenseKey?: string,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n await sendTrackRequest(licenseKey, {\n events: [\n {\n player_id: browserId,\n device_type: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: false,\n ad_detect: false,\n license_key: licenseKey,\n capture_at: new Date().toISOString(),\n },\n ],\n trackingData,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n await sendHeartbeat(licenseKey, context, {\n adDetect: true,\n captureAt: adDetectInfo.timestamp,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n await sendHeartbeat(licenseKey, context, {\n adLoaded: true,\n captureAt: adLoadedInfo.timestamp,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n const metricEvent = await buildPlayerMetricEvent(licenseKey, context, {\n captureAt: adImpressionInfo.timestamp,\n });\n await Promise.all([\n postJson(HEARTBEAT_URL, licenseKey, metricEvent),\n postJson(IMPRESSIONS_URL, licenseKey, {\n events: [\n {\n player_id: metricEvent.player_id,\n ad_played_count: 1,\n ad_url: adImpressionInfo.adUrl,\n license_key: licenseKey,\n capture_at: adImpressionInfo.timestamp,\n },\n ],\n }),\n ]);\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(\n licenseKey?: string,\n context: PlayerAnalyticsContext = {},\n flags: PlayerMetricFlags = {}\n): Promise<void> {\n try {\n const heartbeatData = await buildPlayerMetricEvent(\n licenseKey,\n context,\n flags\n );\n await postJson(HEARTBEAT_URL, licenseKey, heartbeatData);\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n"]}