@chiyou/minigame-framework 1.3.0 → 1.3.2

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.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterBilibili.ts +28 -2
  3. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterDesktopBrowser.ts +8 -1
  4. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterDouYin.ts +28 -2
  5. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterHonor.ts +31 -5
  6. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterHuaWei.ts +34 -1
  7. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterKuaiShou.ts +28 -2
  8. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterOppo.ts +17 -2
  9. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterTapTap.ts +31 -5
  10. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterVivo.ts +32 -4
  11. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterWeiXin.ts +28 -2
  12. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterXiaoMi.ts +31 -5
  13. package/src/Framework/Adapter/PlatformAdapter/PlatformAdapterZhiFuBao.ts +31 -5
  14. package/src/Framework/Definition/AnalyticsDefinition.ts +107 -0
  15. package/src/Framework/Definition/FwkErrorDefinition.ts +18 -2
  16. package/src/Framework/Definition/SystemDefinition.ts +12 -1
  17. package/src/Framework/Definition/UIDefinition.ts +6 -0
  18. package/src/Framework/Manager/AnalyticsMgr.ts +351 -0
  19. package/src/Framework/Manager/AudioMgr.ts +56 -7
  20. package/src/Framework/Manager/InputMgr.ts +61 -0
  21. package/src/Framework/Manager/NodePoolMgr.ts +59 -1
  22. package/src/Framework/Manager/TimerMgr.ts +49 -0
  23. package/src/Framework/Manager/UIMgr.ts +75 -9
  24. package/src/Framework/SDK/Umeng/umtrack-wx-game.ts +107 -0
  25. package/src/Framework/Utils/LogUtils.ts +27 -0
  26. package/src/Framework/Utils/ObjectUtils.ts +111 -0
  27. package/src/index.ts +2 -0
@@ -1,8 +1,10 @@
1
1
  import { FwkErrorCode } from "../Definition/FwkErrorDefinition";
2
+ import { FrameworkBase } from "../Definition/FrameworkBase";
2
3
  import { TimerRepeat } from "../Definition/TimerDefinition";
3
4
  import { LogUtils } from "../Utils/LogUtils";
4
5
  import { ServiceLocator } from "../Utils/ServiceLocator";
5
6
  import { BaseMgr } from "./BaseMgr";
7
+ import { EventMgr } from "./EventMgr";
6
8
 
7
9
  interface ITimer {
8
10
  tick: number;
@@ -19,6 +21,7 @@ export class TimerMgr extends BaseMgr {
19
21
  static TAG: string = "TimerMgr";
20
22
 
21
23
  private timers: ITimer[] = [];
24
+ private _paused: boolean = false;
22
25
 
23
26
  onLoad(): void {
24
27
  super.onLoad();
@@ -31,6 +34,10 @@ export class TimerMgr extends BaseMgr {
31
34
  }
32
35
 
33
36
  ServiceLocator.Instance.register("TimerMgr", this);
37
+
38
+ // 监听生命周期事件,切后台暂停定时器
39
+ EventMgr.Instance.on(FrameworkBase.Message.LifeCycle_onGameHide, this._onGameHide, this);
40
+ EventMgr.Instance.on(FrameworkBase.Message.LifeCycle_onGameShow, this._onGameShow, this);
34
41
  }
35
42
 
36
43
  /**
@@ -38,10 +45,50 @@ export class TimerMgr extends BaseMgr {
38
45
  */
39
46
  public init(): void {
40
47
  this.timers = [];
48
+ this._paused = false;
41
49
 
42
50
  LogUtils.Instance.info(TimerMgr.TAG, "初始化完成");
43
51
  }
44
52
 
53
+ /**
54
+ * 暂停所有定时器
55
+ */
56
+ public pauseAll(): void {
57
+ if (this._paused) return;
58
+ this._paused = true;
59
+ LogUtils.Instance.info(TimerMgr.TAG, "定时器已暂停");
60
+ }
61
+
62
+ /**
63
+ * 恢复所有定时器
64
+ */
65
+ public resumeAll(): void {
66
+ if (!this._paused) return;
67
+ this._paused = false;
68
+ LogUtils.Instance.info(TimerMgr.TAG, "定时器已恢复");
69
+ }
70
+
71
+ /**
72
+ * 定时器是否暂停中
73
+ */
74
+ public isPaused(): boolean {
75
+ return this._paused;
76
+ }
77
+
78
+ private _onGameHide(): void {
79
+ this.pauseAll();
80
+ }
81
+
82
+ private _onGameShow(): void {
83
+ this.resumeAll();
84
+ }
85
+
86
+ onDestroy(): void {
87
+ EventMgr.Instance.off(FrameworkBase.Message.LifeCycle_onGameHide, this._onGameHide, this);
88
+ EventMgr.Instance.off(FrameworkBase.Message.LifeCycle_onGameShow, this._onGameShow, this);
89
+ super.onDestroy();
90
+ }
91
+
45
92
  /**
46
93
  * 添加定时器
47
94
  * @param delay 延迟时间(秒)
@@ -118,6 +165,8 @@ export class TimerMgr extends BaseMgr {
118
165
  }
119
166
 
120
167
  protected update(dt: number): void {
168
+ if (this._paused) return;
169
+
121
170
  for (let index = 0; index < this.timers.length; index++) {
122
171
  const item = this.timers[index];
123
172
  item.tick += dt;
@@ -1,10 +1,12 @@
1
- import { Component, Node, Button, Prefab, instantiate, screen, UITransform, v3, view, ResolutionPolicy, math, Tween, tween, Label, Color, Sprite, SpriteFrame, BlockInputEvents, Texture2D } from 'cc';
1
+ import { Component, Node, Button, Prefab, instantiate, screen, UITransform, v3, view, ResolutionPolicy, math, Tween, tween, Label, Color, Sprite, SpriteFrame, BlockInputEvents, Texture2D, Vec3 } from 'cc';
2
2
  import { FwkErrorCode } from '../Definition/FwkErrorDefinition';
3
3
  import { LogUtils } from '../Utils/LogUtils';
4
- import { ToastDuration } from '../Definition/UIDefinition';
4
+ import { ToastDuration, ToastPosition } from '../Definition/UIDefinition';
5
5
  import { BaseMgr } from './BaseMgr';
6
6
  import { ServiceLocator } from '../Utils/ServiceLocator';
7
7
  import type { ResMgr } from './ResMgr';
8
+ import type { SystemMgr } from './SystemMgr';
9
+ import type { InputMgr } from './InputMgr';
8
10
 
9
11
  /** UI 控制器基类 */
10
12
  export class UICtrl extends Component {
@@ -125,6 +127,8 @@ export class UIMgr extends BaseMgr {
125
127
  private toastHistoryMaxCount: number = 10;
126
128
 
127
129
  private resMgr: ResMgr = null;
130
+ private inputMgr: InputMgr = null;
131
+ private systemMgr: SystemMgr = null;
128
132
 
129
133
  /** 打印 UI 映射(调试用) */
130
134
  public print(): void {
@@ -283,6 +287,10 @@ export class UIMgr extends BaseMgr {
283
287
  this.resMgr = ServiceLocator.Instance.get<ResMgr>("ResMgr");
284
288
  }
285
289
 
290
+ if (this.inputMgr === null) {
291
+ this.inputMgr = ServiceLocator.Instance.get<InputMgr>("InputMgr");
292
+ }
293
+
286
294
  if (!this.resMgr) {
287
295
  return null;
288
296
  }
@@ -434,12 +442,18 @@ export class UIMgr extends BaseMgr {
434
442
  * 显示 Toast
435
443
  * @param content 显示内容
436
444
  * @param toastDuration 显示时长
445
+ * @param position 显示位置(ToastPosition 枚举或世界坐标 Vec3),默认居中
437
446
  */
438
- public showToast(content: string, toastDuration: ToastDuration = ToastDuration.Duration_Short): void {
447
+ public showToast(content: string, toastDuration: ToastDuration = ToastDuration.Duration_Short, position?: ToastPosition | Vec3): void {
439
448
  if (this.node_toastRoot === null) {
440
449
  return;
441
450
  }
442
451
 
452
+ // 延迟加载 SystemMgr(避免循环依赖)
453
+ if (this.systemMgr === null) {
454
+ this.systemMgr = ServiceLocator.Instance.get<SystemMgr>("SystemMgr");
455
+ }
456
+
443
457
  // 记录 Toast 历史
444
458
  this.toastHistory.push(content);
445
459
  if (this.toastHistory.length > this.toastHistoryMaxCount) {
@@ -463,6 +477,33 @@ export class UIMgr extends BaseMgr {
463
477
 
464
478
  this.node_toastRoot.active = true;
465
479
  this.node_toastRoot.getComponent(UITransform).width = textWidth + 80;
480
+
481
+ // 设置 Toast 位置
482
+ if (position !== undefined) {
483
+ if (position instanceof Vec3) {
484
+ // Vec3 世界坐标,转换为节点坐标
485
+ let localPos: Vec3 = this.node_toastRoot.getComponent(UITransform).convertToNodeSpaceAR(position);
486
+ this.node_toastRoot.setPosition(localPos.x, localPos.y);
487
+ } else {
488
+ // ToastPosition 枚举
489
+ let x: number = 0;
490
+ let y: number = 0;
491
+ if (this.systemMgr) {
492
+ let screenInfo = this.systemMgr.getScreenInfo();
493
+ let screenH: number = screenInfo.windowHeight;
494
+ let edgeOffset: number = 150; // 距屏幕边缘的距离
495
+ if (position === ToastPosition.Top) {
496
+ y = screenH / 2 - edgeOffset;
497
+ } else if (position === ToastPosition.Bottom) {
498
+ y = -screenH / 2 + edgeOffset;
499
+ }
500
+ // Center: x=0, y=0
501
+ }
502
+ // systemMgr 为空时默认居中(x=0, y=0)
503
+ this.node_toastRoot.setPosition(x, y);
504
+ }
505
+ }
506
+
466
507
  this.tween_toast = tween(this.node_toastRoot)
467
508
  .delay(showTime)
468
509
  .call(() => {
@@ -483,13 +524,10 @@ export class UIMgr extends BaseMgr {
483
524
  /**
484
525
  * 打开 Dialog
485
526
  * @param ui_name UI 名称
486
- * @param maskColor 遮罩颜色
487
- * @return Dialog 节点
527
+ * @param maskColor 遮罩颜色(默认半透明黑)
528
+ * @param closeOnMaskClick 点击遮罩是否关闭 Dialog(默认 false)
488
529
  */
489
- public openDialog(ui_name: string, maskColor?: Color): Node {
490
- if (!maskColor) {
491
- maskColor = new Color(51, 51, 51, 230);
492
- }
530
+ public openDialog(ui_name: string, maskColor: Color = new Color(51, 51, 51, 230), closeOnMaskClick: boolean = false): Node {
493
531
 
494
532
  const whitePixelData = new Uint8Array([maskColor.r, maskColor.g, maskColor.b, maskColor.a]);
495
533
  const texture = new Texture2D();
@@ -519,6 +557,18 @@ export class UIMgr extends BaseMgr {
519
557
  if (node_dialog) {
520
558
  this.node_dialogRoot.addChild(node_agent);
521
559
  this.node_dialogRoot.active = true;
560
+
561
+ // 点击遮罩关闭 Dialog
562
+ if (closeOnMaskClick) {
563
+ let maskTouchCallback = () => {
564
+ this.closeDialog(ui_name, node_dialog);
565
+ };
566
+ // 将回调存到 node_mask 上,方便 closeDialog 时清理
567
+ (node_mask as any)._maskTouchCallback = maskTouchCallback;
568
+ if (this.inputMgr) {
569
+ this.inputMgr.onNodeTouchEnd(node_mask, maskTouchCallback, this);
570
+ }
571
+ }
522
572
  } else {
523
573
  node_agent.destroy();
524
574
  }
@@ -546,6 +596,14 @@ export class UIMgr extends BaseMgr {
546
596
 
547
597
  if (hasNode) {
548
598
  let node_agent: Node = node.parent;
599
+ // 清理点击遮罩关闭的监听器(如果存在)
600
+ let node_mask: Node = node_agent.getChildByName("Node_Mask");
601
+ if (node_mask && (node_mask as any)._maskTouchCallback) {
602
+ if (this.inputMgr) {
603
+ this.inputMgr.offNodeTouchEnd(node_mask, (node_mask as any)._maskTouchCallback, this);
604
+ }
605
+ (node_mask as any)._maskTouchCallback = null;
606
+ }
549
607
  this.destroy_ui(ui_name, node);
550
608
  node_agent.destroy();
551
609
  }
@@ -574,6 +632,14 @@ export class UIMgr extends BaseMgr {
574
632
  if (child.name !== "Node_Mask") {
575
633
  let uiName = this._nodeToUIName(child);
576
634
  if (uiName) {
635
+ // 清理点击遮罩关闭的监听器(如果存在)
636
+ let node_mask: Node = agent.getChildByName("Node_Mask");
637
+ if (node_mask && (node_mask as any)._maskTouchCallback) {
638
+ if (this.inputMgr) {
639
+ this.inputMgr.offNodeTouchEnd(node_mask, (node_mask as any)._maskTouchCallback, this);
640
+ }
641
+ (node_mask as any)._maskTouchCallback = null;
642
+ }
577
643
  this.destroy_ui(uiName, child);
578
644
  closedCount++;
579
645
  break;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * 友盟+ 微信小程序游戏版 SDK
3
+ * 由 umtrack-wx-game.js 转换而来,适配 Cocos Creator 3.x TypeScript 环境
4
+ * 采用直接执行方案,不使用 new Function() 沙箱
5
+ * @version 2.8.2
6
+ */
7
+
8
+ // @ts-nocheck
9
+ // 禁用 TypeScript 检查,因为 SDK 是压缩后的 JS 代码
10
+
11
+ // ============================================
12
+ // SDK 内部实现(直接执行,非沙箱)
13
+ // ============================================
14
+
15
+ var e="[UMENG] -- ",t=function(){var t=null,n=!1;function i(){this.setDebug=function(e){n=e};this.d=function(){if(n)try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.debug.apply(console,arguments)}catch(e){}};this.i=function(){try{if(n)try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.info.apply(console,arguments)}catch(e){}}catch(e){}};this.e=function(){if(n)try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.error.apply(console,arguments)}catch(e){}};this.w=function(){if(n)try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.warn.apply(console,arguments)}catch(e){}};this.v=function(){if(n)try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.log.apply(console,arguments)}catch(e){}};this.t=function(){if(n)try{console.table.apply(console,arguments)}catch(e){}};this.tip=function(){try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.log.apply(console,arguments)}catch(e){}};this.tip_w=function(t){try{console.log("%c "+e+t,"background:red; padding: 4px; padding-right: 8px; border-radius: 4px; color: #fff;")}catch(e){}};this.err=function(){try{"string"==typeof arguments[0]&&(arguments[0]=e+arguments[0]);console.error.apply(console,arguments)}catch(e){}};this.repeat=function(e){for(var t=e;t.length<86;)t+=e;return t}}return function(){null===t&&(t=new i);return t}}(),n=function(){var e=null;function t(){var e={};this.useOpenid=function(){return!!e.useOpenid};this.useSwanid=function(){return!!e.useSwanid};this.autoGetOpenid=function(){return!!e.autoGetOpenid};this.appKey=function(){return e.appKey};this.uploadUserInfo=function(){return e.uploadUserInfo};this.enableVerify=function(){return e.enableVerify};this.set=function(t){e=t};this.get=function(){return e};this.setItem=function(t,n){e[t]=n};this.getItem=function(t){return e[t]}}return function(){e||(e=new t);return e}}();function i(){}i.prototype={on:function(e,t,n){var i=this.e||(this.e={});(i[e]||(i[e]=[])).push({fn:t,ctx:n});return this},once:function(e,t,n){var i=this;function r(){i.off(e,r);t.apply(n,arguments)}r._=t;return this.on(e,r,n)},emit:function(e){for(var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),i=0,r=n.length;i<r;i++)n[i].fn.apply(n[i].ctx,t);return this},off:function(e,t){var n=this.e||(this.e={}),i=n[e],r=[];if(i&&t)for(var o=0,s=i.length;o<s;o++)i[o].fn!==t&&i[o].fn._!==t&&r.push(i[o]);r.length?n[e]=r:delete n[e];return this}};var r=new i;r.messageType={CONFIG_LOADED:0,UMA_LIB_INITED:1};var o=function(e,t){o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return o(e,t)};function s(e,t){o(e,t);function n(){this.constructor=e}e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=new(function(e){s(n,e);function n(){return null!==e&&e.apply(this,arguments)||this}n.prototype.getSdkType=function(){return"wxgamemp"};n.prototype.getUserInfo=function(e){var n={fail:function(){e&&e()},success:function(t){if(t&&t.userInfo){var n=t.userInfo;e&&e({avatar:n.avatarUrl,nickName:n.nickName,gender:n.gender,country:n.country,province:n.province,city:n.city,language:n.language})}}};try{wx.getSetting({success:function(e){e.authSetting["scope.userInfo"]&&wx.getUserInfo(n)},fail:function(){e()}})}catch(e){t.e("getUserInfo error",e)}};return n}(function(){function e(){}e.prototype.setStorage=function(e,t,n){wx.setStorage({key:e,data:t,success:function(){"function"==typeof n&&n(!0)},fail:function(){"function"==typeof n&&n(!1)}})};e.prototype.getStorage=function(e,n){wx.getStorage({key:e,success:function(e){"function"==typeof n&&n(e.data)},fail:function(i){t().w(e+": "+i.errMsg);"function"==typeof n&&n()}})};e.prototype.removeStorage=function(e,t){wx.removeStorage({key:e,success:function(){"function"==typeof t&&t(!0)},fail:function(){"function"==typeof t&&t(!1)}})};e.prototype.getSystemInfo=function(e){wx.getSystemInfo({success:function(t){t.safeArea=t.safeArea||{};var n="";t.host&&"string"==typeof t.host.env&&(n=t.host.env);var i={model:t.model,brand:t.brand,pixelRatio:t.pixelRatio,screenWidth:t.screenWidth,screenHeight:t.screenHeight,fontSizeSetting:t.fontSizeSetting,platform:t.platform,platformVersion:t.version,platformSDKVersion:t.SDKVersion,language:t.language,deviceName:t.model,OSVersion:t.system,resolution:"",theme:t.theme,benchmarkLevel:t.benchmarkLevel,safeArea:{width:t.safeArea.width,height:t.safeArea.height,top:t.safeArea.top,left:t.safeArea.left,bottom:t.safeArea.bottom,right:t.safeArea.right},statusBarHeight:t.statusBarHeight,host:n},r=t.system.split(" ");Array.isArray(r)&&(i.OS=r[0]);var o=Math.round(t.screenWidth*t.pixelRatio),s=Math.round(t.screenHeight*t.pixelRatio);i.resolution=o>s?o+"*"+s:s+"*"+o;"function"==typeof e&&e(i)},fail:function(){"function"==typeof e&&e()}})};e.prototype.getDeviceInfo=function(e){"function"==typeof e&&e("")};e.prototype.checkNetworkAvailable=function(e){wx.getNetworkType({success:function(t){"function"==typeof e&&e(t&&"none"!==t.networkType)},fail:function(){"function"==typeof e&&e(!1)}})};e.prototype.getNetworkInfo=function(e){wx.getNetworkType({success:function(t){"function"==typeof e&&e({networkAvailable:"none"!==t.networkType,networkType:t.networkType})},fail:function(){"function"==typeof e&&e()}})};e.prototype.getDeviceId=function(e){e("")};e.prototype.getAdvertisingId=function(e){"function"==typeof e&&e("")};e.prototype.onNetworkStatusChange=function(e){wx.onNetworkStatusChange((function(t){"function"==typeof e&&e(t.isConnected)}))};e.prototype.request=function(e){var t=e.success,n=e.fail,i=!1,r=null;e.success=function(e){if(!i){r&&clearTimeout(r);"function"==typeof t&&t(e)}};e.fail=function(){if(!i){r&&clearTimeout(r);"function"==typeof n&&n(!1)}};wx.request(e);r=setTimeout((function(){r&&clearTimeout(r);i=!0;"function"==typeof n&&n(i)}),e.timeout||5e3)};e.prototype.getSdkType=function(){return"wxmp"};e.prototype.getPlatform=function(){return"wx"};e.prototype.getUserInfo=function(e){e()};e.prototype.getAppInfoSync=function(){if(wx.getAccountInfoSync){var e=wx.getAccountInfoSync(),t=e&&e.miniProgram?e.miniProgram:{};return{appId:t.appId,appEnv:t.envVersion,appVersion:t.version}}return{}};e.prototype.onShareAppMessage=function(e){wx.onShareAppMessage(e)};e.prototype.shareAppMessage=function(e){wx.shareAppMessage(e)};e.prototype.getLaunchOptionsSync=function(){var e=null;if(e)return e;if(!wx.getLaunchOptionsSync)return{};try{e=wx.getLaunchOptionsSync()}catch(t){e=null}return e||{}};return e}())),u={SESSION_INTERVAL:3e4,LOG_URL:"/wxm_logs",GET_OPENID_URL:"/uminiprogram_logs/wx/getuut",USERINFO_URL:"/uminiprogram_logs/comm/uif",ENDPOINT:"https://umini.shujupie.com",ENDPOINTB:"https://ulogs.umeng.com",DEVICE_INFO_KEY:"device_info",ADVERTISING_ID:"mobile_ad_id",ANDROID_ID:"android_id",CURRENT_SESSION:"current_session",SESSION_PAUSE_TIME:"session_pause_time",EVENT_SEND_DEFAULT_INTERVAL:15e3,EVENT_LAST_SEND_TIME:"last_send_time",MAX_EVENTID_LENGTH:128,MAX_PROPERTY_KEY_LENGTH:256,MAX_PROPERTY_KEYS_COUNT:100,REPORT_POLICY:"report_policy",REPORT_INTERVAL_TIME:"report_interval_time",REPORT_POLICY_START_SEND:"1",REPORT_POLICY_INTERVAL:"6",IMPRINT:"imprint",SEED_VERSION:"1.0.0",IMPL_VERSION:"2.8.2",ALIPAY_AVAILABLE_VERSION:"10.1.52",SHARE_PATH:"um_share_path",SHARES:"shares",REQUESTS:"requests",UUID:"um_uuid",UUID_SUFFIX:"ud",OPENID:"um_od",UNIONID:"um_unid",ALIPAYID:"um_alipayid",USERID:"um_userid",PROVIDER:"um_provider",SWANID:"um_swanid",ANONYMOUSID:"um_anonymousid",LAUNCH_OPTIONS:"LAUNCH_OPTIONS",UM_SSRC:"_um_ssrc",USER_INFO:"user_info",IS_ALIYUN:!1};var c,f={isNumber:function(e){return!Number.isNaN(parseInt(e,10))},compareVersion:function(e,t){for(var n=String(e).split("."),i=String(t).split("."),r=0;r<Math.max(n.length,i.length);r++){var o=parseInt(n[r]||0,10),s=parseInt(i[r]||0,10);if(o>s)return 1;if(o<s)return-1}return 0},getRandomStr:function(e){for(var t="",n=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],i=0;i<Number(e);i++){t+=n[Math.round(Math.random()*(n.length-1))]}return t},clone:function(e){return JSON.parse(JSON.stringify(e))},startsWith:function(e,t){return!(!e||!t||0===t.length||t.length>e.length)&&e.substr(0,t.length)===t},endsWith:function(e,t){return!(!t||0===e.length||t.length>e.length)&&e.substring(e.length-t.length)===t},assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1;n<arguments.length;n++){var i=arguments[n];if(i)for(var r in i)Object.prototype.hasOwnProperty.call(i,r)&&(t[r]=i[r])}return t},deepEqual:function e(t,n){if(t===n)return!0;if(t&&"object"==typeof t&&n&&"object"==typeof n){if(Object.keys(t).length!==Object.keys(n).length)return!1;for(var i in t){if(Object.prototype.hasOwnProperty.call(n,i))return!1;if(!e(t[i],n[i]))return!1}return!0}return!1},trimStart:function(e,t){if(!e)return"";if("string"==typeof t&&t.length){var n=new RegExp("^"+t+"*");e=e.replace(n,"")}else e=e.replace(/^s*/,"");return e},trimEnd:function(e,t){if(!e)return"";var n,i;if("string"==typeof t&&t.length){n=new RegExp(t);i=e.length;for(;n.test(e.charAt(i));)i-=1;return e.slice(0,i+1)}n=/s/;i=e.length-1;for(;n.test(e.charAt(i));)i-=1;return e.slice(0,i+1)},isFunction:function(e){return"function"==typeof e}},p=function(e){s(n,e);function n(){return null!==e&&e.apply(this,arguments)||this}n.prototype.getOpenIdAsync=function(e,n){var i=this;wx.login({success:function(r){r.code?a.request({url:u.ENDPOINT+u.GET_OPENID_URL,method:"GET",data:{key:e,code:r.code},success:function(e){if(e&&200===e.statusCode&&e.data&&e.data.data){var t=e.data.data;i.setOpenid(t.oid);i.setUnionid(t.uid);return n&&n(!0)}n&&n()},fail:function(e){t().v("wx request failed...",e);n&&n()}}):n&&n()},fail:function(){n&&n()}})};return n}(function(e){s(n,e);function n(){var t=null!==e&&e.apply(this,arguments)||this;t._openid="";t._unionid="";t._useOpenid=!1;return t}n.prototype.initID=function(e){var n=this;n._idType=n._useOpenid?"openid":"uuid";t().v("id type: ",n._idType);a.getStorage(u.UNIONID,(function(e){n._unionid=e}));this._useOpenid?a.getStorage(u.OPENID,(function(t){n._openid=t;e&&e()})):e&&e()};n.prototype.setUseOpenid=function(e){this._useOpenid=e};n.prototype.setOpenid=function(e){if(!this._openid&&e){this._openid=e;a.setStorage(u.OPENID,e)}};n.prototype.setUnionid=function(e){if(!this._unionid&&e){this._unionid=e;a.setStorage(u.UNIONID,e)}};n.prototype.getIdTracking=function(){var t=e.prototype.getIdTracking.call(this);this._openid&&(t.openid=this._openid);this._unionid&&(t.unionid=this._unionid);this._userid&&(t.userid=this._userid);return t};n.prototype.getId=function(){return this._useOpenid?this._openid:this._uuid};return n}(function(){function e(){this._uuid="";this._userid="";this._provider="";this._idType=""}e.prototype.createUUID=function(){return f.getRandomStr(10)+Date.now()+f.getRandomStr(7)+u.UUID_SUFFIX};e.prototype.initUUID=function(e){var t=this;a.getStorage(u.UUID,(function(n){if(n)t._uuid=n;else{t._uuid=t.createUUID();a.setStorage(u.UUID,t._uuid)}e&&e(n)}))};e.prototype.initUserid=function(){var e=this;a.getStorage(u.USERID,(function(n){if(!e._userid&&n){e._userid=n;t().v("userId is ",n)}}));a.getStorage(u.PROVIDER,(function(n){if(!e._provider&&n){e._provider=n;t().v("provider is ",n)}}))};e.prototype.init=function(e){var t=this;t.initUUID((function(){t.initUserid();t.initID(e)}))};e.prototype.setUserid=function(e,t){if(!this._userid&&e){this._userid=e;this._provider=t;a.setStorage(u.USERID,e);a.setStorage(u.PROVIDER,t)}};e.prototype.removeUserid=function(){this._userid=void 0;this._provider=void 0;a.removeStorageSync(u.USERID);a.removeStorageSync(u.PROVIDER)};e.prototype.getUserId=function(){return this._userid};e.prototype.getProvider=function(){return this._provider};e.prototype.getIdType=function(){return this._idType};e.prototype.getIdTracking=function(){var e={};this._uuid&&(e.uuid=this._uuid);this._userid&&(e.userid=this._userid);return e};return e}())),l=(c=null,function(){c||(c=new p);return c}),d=function(){var e=null;function t(){var e=!1,t=null,n=[];this.addPageStart=function(n){if(n&&!e){t={ts:Date.now(),path:n,page_name:n};e=!0}};this.addPageEnd=function(i){if(e&&i&&t&&i===t.page_name){var r=Date.now()-t.ts;t.duration=Math.abs(r);n.push(t);t=null;e=!1}};this.get=function(){return n};this.getCurrentPage=function(){return t};this.clear=function(){n.length=0}}return function(){e||(e=new t);return e}}(),h={};var g=function(){var e=null,n=[],i="";function r(){return{add:function(e,r){t().v("share origin: %o",e);var o={title:e&&e.title,path:e&&e.path&&e.path.split("?")[0],_um_sts:Date.now()};o.path&&o.path.length>1&&f.startsWith(o.path,"/")&&(o.path=f.trimStart(o.path,"/"));var s=e.path||"",a=l().getId();if(a){var u=i.split(","),c=(u=u.filter((function(e){return e.length>0}))).indexOf(a);c>=0&&(u=u.slice(0,c));u.length<3&&u.push(a);var p=u.join(",");-1!==s.indexOf("?")?s+="&_um_ssrc="+p:s+="?_um_ssrc="+p;var d=Date.now();s+="&_um_sts="+d;if(r){var g=function(e){var t=[];for(var n in e)"_um_ssrc"!==n&&"_um_sts"!==n&&t.push(n+"="+e[n]);return t.join("&")}(h),v=g?g+"&_um_ssrc="+p+"&_um_sts="+d:"_um_ssrc="+p+"&_um_sts="+d;e.query=e.query?e.query+"&_um_ssrc="+p+"&_um_sts="+d:v}else e.path=s;o._um_ssrc=p;o._um_sts=d}n.push(o);t().v("share: %o",e);return e},setShareSource:function(e){i=e},clear:function(){n.length=0},get:function(){return n}}}return function(){e||(e=new r);return e}}(),v=function(e){if(e)try{return JSON.stringify(e)}catch(e){}return""},_=function(e){if(e)try{return JSON.parse(e)}catch(e){}return null},y=function(){var e=null,t="",i=null,r=!1;function o(){this.load=function(e){if(i){a.removeStorage(t);e()}else{t="um_cache_"+n().appKey();a.getStorage(t,(function(n){i=_(n)||{};r=!0;a.removeStorage(t);e()}))}};this.save=function(){i&&a.setStorage(t,v(i))};this.set=function(e,t){i&&(i[e]=t)};this.get=function(e){return(i||{})[e]};this.remove=function(e){i&&i[e]&&delete i[e]};this.getAll=function(){return i};this.clear=function(){i=null};this.has=function(e){return!!this.get(e)};this.isLoaded=function(){return r}}return function(){e||(e=new o);return e}}(),m="ekvs",S=function(){var e,n,i=[],r=[];function o(){if(i.length){var e=y().get(m);if(function(e){var t=0;for(var n in e)Array.isArray(e[n])&&(t+=e[n].length);return t}(e)+i.length<=1e4){e=s(e,i);y().set(m,e)}}}function s(e,t){var i=(e=e||{})[n];Array.isArray(i)&&i.length?e[n]=i.concat(t):e[n]=[].concat(t);return e}return function(){e||(e={addEvent:function(e){if(n){i.unshift(e);if(i.length>1){o();i.length=0}}else{t().w("session id is null: ",n);r.unshift(e)}},setSessionId:function(e){n=e;t().v("setSessionId: ",n);if(Array.isArray(r)&&r.length&&n){for(var i=0;i<r.length;i++)this.addEvent(r[i]);r.length=0}},getEkvs:function(){var e=y().get(m);i&&i.length&&(e=s(e,i));return e},clear:function(){y().remove(m);i.length=0}});return e}}(),I="2g",E="3g",O="4g",A="half_session",N="close_session",T="ekv",w=["access","access_subtype"],k=function(){var e=null;function t(){var e=!1,t={};function i(e){var i=y().get(u.IMPRINT);i&&(t.imprint=i);t.device_type="Phone";t.sdk_version=u.IMPL_VERSION;t.appkey=n().appKey();a.getDeviceInfo((function(e){t.device_info=e||""}));var r=a.getAppInfoSync();t.appid=r.appId;t.app_env=r.appEnv;t.app_version=r.appVersion;a.getSystemInfo((function(n){a.getNetworkInfo((function(i){var r=function(e,t){var n={};e=e||{};e.safeArea=e.safeArea||{};t=t||{};var i=t.networkType;"none"===i&&(i="unknown");var r=e.model||"",o=e.platform||"",s=e.brand||"",u=s.toLowerCase();n.sdk_type=a.getSdkType();n.platform=a.getPlatform();n.platform_sdk_version=e.platformSDKVersion;n.platform_version=e.platformVersion;n.resolution=e.resolution;n.pixel_ratio=e.pixelRatio;n.os=o;n.font_size_setting=e.fontSizeSetting;n.device_model=r;n.device_brand=s;n.device_manufacturer=u;n.device_manuid=r;n.device_name=r;n.os_version=e.OSVersion;n.language=e.language;n.theme=e.theme;n.benchmark_level=e.benchmarkLevel;n.status_bar_height=e.statusBarHeight;n.safe_area_top=e.safeArea.top;n.safe_area_left=e.safeArea.left;n.safe_area_right=e.safeArea.right;n.safe_area_bottom=e.safeArea.bottom;n.safe_area_height=e.safeArea.height;n.safe_area_width=e.safeArea.width;n.storage=e.storage;n.screen_width=e.screenWidth;n.screen_height=e.screenHeight;n.host=e.host;switch(i=i?i.toLowerCase():""){case O:n.access_subtype="LTE";n.access="4G";break;case E:n.access_subtype="CDMA";n.access="3G";break;case I:n.access_subtype="GRPS";n.access="2G";break;default:n.access=i;delete n.access_subtype}return n}(n,i);f.assign(t,r);e&&e()}))}))}return{init:function(){i((function(){e=!0}))},isLoaded:function(){return e},get:function(){return t},getRealtimeFields:function(){var e={};w.forEach((function(n){e[n]=t[n]}));return e},setIdTracking:function(e){this.setItem("id_tracking",e)},setIdType:function(e){this.setItem("id_type",e)},setAppVersion:function(e){this.setItem("app_version",e)},setSuperProperty:function(e){t.sp||(t.sp={});t.sp.isv=e},getSuperProperty:function(){return t&&t.sp?t.sp.isv:""},setItem:function(e,n){t[e]=n},getItem:function(e){return t[e]}}}return{instance:function(){e||(e=t());return e}}}(),b=function(){var e=null,n=null,i=null;function r(){return{resume:function(e){var r=!1;i||(i=y().get(u.CURRENT_SESSION));var o=new Date;n=o.getTime();if(!i||!i.end_time||n-i.end_time>u.SESSION_INTERVAL){r=!0;!function(e){try{var n=(i||{}).options||{},r=f.assign({},function(e){var n={};for(var i in e)0===i.indexOf("_um_")&&(n[i]=e[i]);t().v("query: ",e);t().v("_um_params: ",n);return n}(e.query));r.path=e.path||n.path;"gaode"!==a.getPlatform()&&(r.scene=e.scene?a.getPlatform()+"_"+e.scene:n.scene);var o=e.referrerInfo;o&&(r.referrerAppId=o.appId);t().v("session options: ",r);var s=r[u.UM_SSRC];s&&g().setShareSource(s);var c=Date.now();i={id:f.getRandomStr(10)+c,start_time:c,options:r}}catch(e){t().e("生成新session失败: ",e)}}(e);t().v("开始新的session(%s): ",i.id,i)}else t().v("延续上一次session(%s): %s ",i.id,o.toLocaleTimeString(),i);return r},pause:function(){!function(){if(i){var e=new Date;i.end_time=e.getTime();"number"!=typeof i.duration&&(i.duration=0);i.duration=i.end_time-n;y().set(u.CURRENT_SESSION,i);t().v("退出会话(%s): %s ",i.id,e.toLocaleTimeString(),i)}}()},getCurrentSessionId:function(){return(i||{}).id},getCurrentSession:function(){return i},cloneCurrentSession:function(){return f.clone(i)}}}return function(){e||(e=r());return e}}();function D(e){var t=null;switch(e){case A:t=function(){var e=null,t=b().cloneCurrentSession();t&&(e={header:{st:"1"},analytics:{sessions:[t]}});return e}();break;case N:t=function(){var e=null,t={},n=b().cloneCurrentSession();if(n){var i=d().get(),r=g().get();Array.isArray(i)&&i.length&&(n.pages=f.clone(i));Array.isArray(r)&&r.length&&(n.shares=f.clone(r));d().clear();g().clear();t.sessions=[n]}var o=S().getEkvs();if(o){t.ekvs=f.clone(o);S().clear()}(t.sessions||t.ekvs)&&(e={analytics:t});return e}();break;case T:t=function(){var e=null,t=S().getEkvs();if(t){e={analytics:{ekvs:f.clone(t)}};S().clear()}return e}()}return t}var R={sessions:"sn",ekvs:"e",active_user:"active_user"},U={sdk_type:"sdt",access:"ac",access_subtype:"acs",device_model:"dm",language:"lang",device_type:"dt",device_manufacturer:"dmf",device_name:"dn",platform_version:"pv",id_type:"it",font_size_setting:"fss",os_version:"ov",device_manuid:"did",platform_sdk_version:"psv",device_brand:"db",appkey:"ak",_id:"id",id_tracking:"itr",imprint:"imp",sdk_version:"sv",resolution:"rl",testToken:"ttn",theme:"t5",benchmark_level:"bml",screen_width:"sw",screen_height:"sh",status_bar_height:"sbh",safe_area_top:"sat",safe_area_left:"sal",safe_area_right:"sar",safe_area_bottom:"sab",safe_area_height:"sah",safe_area_width:"saw",pixel_ratio:"pr",storage:"s7",host:"hs"},P={uuid:"ud",unionid:"und",openid:"od",anonymousid:"nd",alipay_id:"ad",device_id:"dd",userid:"puid"};function L(e,t){var n=C(e,t);e&&e.id_tracking&&(n[t.id_tracking||"id_tracking"]=C(e.id_tracking,P));return n}function C(e,t){var n={};for(var i in e)t[i]?n[t[i]]=e[i]:n[i]=e[i];return n}function M(e,t){var n={};if(e)for(var i in e)e[i]&&(n[t[i]]=e[i]);return n}var x="";function V(){return x}var j="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",G=function(e){for(var t={},n=0,i=e.length;n<i;n++)t[e.charAt(n)]=n;return t}(j),K=String.fromCharCode,F=function(e){if(e.length<2){return(t=e.charCodeAt(0))<128?e:t<2048?K(192|t>>>6)+K(128|63&t):K(224|t>>>12&15)+K(128|t>>>6&63)+K(128|63&t)}var t=65536+1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320);return K(240|t>>>18&7)+K(128|t>>>12&63)+K(128|t>>>6&63)+K(128|63&t)},q=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,H=function(e){var t=[0,2,1][e.length%3],n=e.charCodeAt(0)<<16|(e.length>1?e.charCodeAt(1):0)<<8|(e.length>2?e.charCodeAt(2):0);return[j.charAt(n>>>18),j.charAt(n>>>12&63),t>=2?"=":j.charAt(n>>>6&63),t>=1?"=":j.charAt(63&n)].join("")},B=function(e){return t=function(e){return e.replace(q,F)}(e),t.replace(/[\s\S]{1,3}/g,H);var t},Y=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g"),W=function(e){switch(e.length){case 4:var t=((7&e.charCodeAt(0))<<18|(63&e.charCodeAt(1))<<12|(63&e.charCodeAt(2))<<6|63&e.charCodeAt(3))-65536;return K(55296+(t>>>10))+K(56320+(1023&t));case 3:return K((15&e.charCodeAt(0))<<12|(63&e.charCodeAt(1))<<6|63&e.charCodeAt(2));default:return K((31&e.charCodeAt(0))<<6|63&e.charCodeAt(1))}},J=function(e){var t=e.length,n=t%4,i=(t>0?G[e.charAt(0)]<<18:0)|(t>1?G[e.charAt(1)]<<12:0)|(t>2?G[e.charAt(2)]<<6:0)|(t>3?G[e.charAt(3)]:0),r=[K(i>>>16),K(i>>>8&255),K(255&i)];r.length-=[0,0,2,1][n];return r.join("")},X=function(e){return t=function(e){return e.replace(/[\s\S]{1,4}/g,J)}(e),t.replace(Y,W);var t},z=function(e,t){return t?B(String(e)).replace(/[+\/]/g,(function(e){return"+"==e?"-":"_"})).replace(/=/g,""):B(String(e))},Q=function(e){return X(String(e).replace(/[-_]/g,(function(e){return"-"==e?"+":"/"})).replace(/[^A-Za-z0-9\+\/]/g,""))};var Z=new function(){var e="",t=this;this.set=function(t){e=t};this.get=function(){return e};this.getImpObj=function(){return _(Q(e))};this.getItem=function(e){var n=t.getImpObj();return n&&n[e]||""};this.load=function(){e=y().get(u.IMPRINT)};this.save=function(){e&&y().set(u.IMPRINT,e)}};function $(e,n,i,r){k.instance().setIdType(l().getIdType());k.instance().setIdTracking(l().getIdTracking());var o=l().getUserId();o&&e.analytics&&(e.analytics.active_user={puid:o,provider:l().getProvider()});var s=f.clone(k.instance().get());e.header=f.assign(s,e.header,{ts:Date.now(),testToken:V(),traceId:f.getRandomStr(10)+Date.now()+f.getRandomStr(9)});var c,p=function(e){return{h:L(e.header,U),a:M(e.analytics,R)}}(e),d=v(p);c=p;var h={url:u.ENDPOINT+u.LOG_URL,method:"POST",data:c,success:function(r){var o=r.code||r.status||r.statusCode;if(200===o||413===o){t().i("数据发送成功: ",e,d);!function(e){if(e){k.instance().setItem(u.IMPRINT,e);Z.set(e);Z.save();t().v("imprint: ",Z.getImpObj());Z.getItem("ttn_invalid")&&(x="")}}((r.data||{}).imprint);"function"==typeof n&&n(r)}else{t().w("数据发送失败: ",d);"function"==typeof i&&i()}},fail:function(e){t().w("超时: ",d);"function"==typeof i&&i()},complete:function(){"function"==typeof r&&r()}};a.request(f.assign(h,{header:{"Msg-Type":a.getSdkType()+"/json","disable-base64":"Y","content-type":"application/json"}}))}function ee(e){var t=e,n=[];this.enqueue=function(e){"number"==typeof t&&this.size()>=t&&this.dequeue();n.push(e)};this.dequeue=function(){return n.shift()};this.front=function(){return n[0]};this.isEmpty=function(){return 0===n.length};this.clear=function(){n.length=0};this.size=function(){return n.length};this.items=function(){return n};this.print=function(){console.log(n.toString())}}var te=function(){var e=null,n=!1,i=[],r=new ee(50);function o(e,t,n){if(k.instance().isLoaded()){t=t||{};var i=D(e);if(i){var s=k.instance().getRealtimeFields();i.header=f.assign({},i.header,s);i.noCache=t.noCache;r.enqueue(i)}"function"==typeof n&&n()}else setTimeout((function(){o(e,t,n)}),100)}function s(e){var t=r.front();if(t)$(t,(function(){r.dequeue();s(e)}),(function(){var t=r.dequeue();t&&!t.noCache&&i.push(t);s(e)}));else{!function(){i.forEach((function(e){r.enqueue(e)}));i.length=0}();e()}}function a(e){if(l().getId())if(n)t().i("队列正在发送中");else{n=!0;s((function(){n=!1;"function"==typeof e&&e()}))}else{t().i("获取id标识失败,暂缓发送");"function"==typeof e&&e()}}function c(){this.send=function(e,t,n){e?this.add(e,t,(function(){a(n)})):a(n)};this.add=function(e,t,n){o(e,t,n)};this.load=function(){var e=y().get(u.REQUESTS);e&&e.length&&e.forEach((function(e){r.enqueue(e)}));y().remove(u.REQUESTS)};this.save=function(){y().set(u.REQUESTS,f.clone(r.items()));r.clear()}}return function(){e||(e=new c);return e}}(),ne=function(){var e=null,i=null;function r(){this.setUserInfo=function(e){i=e};this.update=function(){e(i)||a.getUserInfo((function(t){e(t)}))};function e(e){if(e&&"object"==typeof e){var i=y().get(u.USER_INFO);i&&f.deepEqual(e,i)||function(e,i){var r=n().appKey(),o=a.getSdkType(),s=l().getId(),c=l().getIdType();if(!(r&&o&&s&&c))return;var f={ak:n().appKey(),sdt:a.getSdkType(),uin:e.nickName,uia:e.avatar||e.avatarUrl,uig:e.gender,uit:e.country,uip:e.province,uic:e.city,uil:e.language,id:l().getId(),it:l().getIdType(),age:e.age,cln:e.constellation},p=JSON.stringify(f);p=z(p);a.request({url:u.ENDPOINT+u.USERINFO_URL,method:"POST",header:{"content-type":"application/x-www-form-urlencoded"},data:"ui="+p,success:function(n){t().v("用户信息上传成功: ",e);i&&i(n&&n.data&&200===n.data.code)},fail:function(){t().e("用户信息上传失败: ",e);i&&i(!1)}})}(e,(function(t){t&&y().set(u.USER_INFO,e)}));return!0}return!1}}return function(){e||(e=new r);return e}}();function ie(e,t){this.id=e;this.ts=Date.now();var n=typeof t;if("string"===n&&t)this[e]=t;else if("object"===n)for(var i in t)({}).hasOwnProperty.call(t,i)&&(this[i]=t[i])}function re(){var e=!1,i=!1,r=0;this.init=function(i){t().v("sdk version: "+u.IMPL_VERSION);e?t().v("Lib重复实例化"):y().load((function(){t().v("cache初始化成功: ",y().getAll());!function(){l().setUseOpenid&&l().setUseOpenid(n().useOpenid());l().init((function(){k.instance().init();t().v("Header初始化成功")}))}();e=!0;"function"==typeof i&&i();t().tip("SDK集成成功")}))};this.resume=function(r){if(e&&!i){t().v("showOptions: ",r);var o;i=!0;n().enableVerify()&&r&&r.query&&(o=r.query._ttn,x=o||x);this._resume(r)}};this._resume=function(e){te().load();var i=b().resume(e),r=b().getCurrentSessionId();S().setSessionId(r);i&&te().add(A,{},(function(){l().setUseOpenid&&l().setUseOpenid(n().useOpenid());if(n().useOpenid()&&n().autoGetOpenid()&&!l().getId()){t().v("get id async");o(10,3e3)}else{t().v("session auto send");te().send()}}));function o(e,i){l().getId()||e<=0||l().getOpenIdAsync(n().appKey(),(function(n){if(n){t().v("获取id成功");te().send()}else{t().v("获取openid失败,启动重试,剩余可用次数",e-1);setTimeout((function(){o(e-1,i)}),i)}}))}};this.pause=function(o){if(e){i=!1;r=0;b().pause();n().uploadUserInfo()&&ne().update();te().send(N,{},(function(){te().save();y().save();t().v("cache save success");"function"==typeof o&&o()}))}};this.setOpenid=function(e){t().v("setOpenId: %s",e);l().setOpenid(e);te().send()};this.setUnionid=function(e){t().v("setUnionid: %s",e);l().setUnionid(e)};this.setUserid=function(e,n){t().v("setUserid: %s",e,n);l().setUserid(e,n)};this.removeUserid=function(){t().v("removeUserid");l().removeUserid()};this.setUserInfo=function(e){t().v("setUserInfo: %s",e);ne().setUserInfo(e)};this.setAnonymousid=function(e){t().v("setAnonymousId: %s",e);l().setAnonymousid(e);te().send()};this.setAppVersion=function(e){e&&"string"!=typeof e?t().w("setAppVersion方法只接受字符串类型参数"):k.instance().setAppVersion(e)};this.setAlipayUserid=function(e){if(e&&"string"!=typeof e)t().w("setAlipayUserid方法只接受字符串类型参数");else{t().v("setAlipayUserid: %s",e);l().setAlipayUserid(e)}};this.setDeviceId=function(e){if("string"==typeof e){l().setDeviceId(e);return e}};this.setSuperProperty=function(e){if(e&&"string"!=typeof e)t().w("超级属性只支持字符串类型");else{var n=this;if(k.instance().getSuperProperty()!==e){k.instance().setSuperProperty(e);n.pause((function(){n.resume()}))}}};this.trackEvent=function(n,i){if(e){t().v("event: ",n,i);if(function(e,n){if(!e||"string"!=typeof e){t().e('please check trackEvent id. id should be "string" and not null');return!1}var i=["id","ts","du"],r={};i.forEach((function(e){r[e]=1}));if(r[e]){t().e("eventId不能与以下保留字冲突: "+i.join(","));return!1}if(e.length>u.MAX_EVENTID_LENGTH){t().e("The maximum length of event id shall not exceed "+u.MAX_EVENTID_LENGTH);return!1}if(n&&("object"!=typeof n||Array.isArray(n))&&"string"!=typeof n){t().e("please check trackEvent properties. properties should be string or object(not include Array)");return!1}if("object"==typeof n){var o=0;for(var s in n)if({}.hasOwnProperty.call(n,s)){if(s.length>u.MAX_PROPERTY_KEY_LENGTH){t().e("The maximum length of property key shall not exceed "+u.MAX_PROPERTY_KEY_LENGTH);return!1}if(o>=u.MAX_PROPERTY_KEYS_COUNT){t().e("The maximum count of properties shall not exceed "+u.MAX_PROPERTY_KEYS_COUNT);return!1}if(r[s]){t().e("属性中的key不能与以下保留字冲突: "+i.join(","));return!1}o+=1}}return!0}(n,i)){var o=new ie(n,i);S().addEvent(o);var s=!!V(),a=s?0:u.EVENT_SEND_DEFAULT_INTERVAL,c=Date.now();if(function(e,t){return"number"!=typeof r||"number"!=typeof t||r<=0||e-r>t}(c,a)){r=c;te().send(T,{noCache:s},(function(){}))}}}};this.trackShare=function(n){if(e)try{if(a.getSdkType().indexOf("game")>-1){n=g().add(n,!0);t().v("shareQuery: ",n)}else{n=g().add(n,!1);t().v("sharePath: ",n.path)}}catch(e){t().v("shareAppMessage: ",e)}return n};this.trackPageStart=function(t){e&&d().addPageStart(t)};this.trackPageEnd=function(t){e&&d().addPageEnd(t)};this.onShareAppMessage=function(e){var t=this;a.onShareAppMessage((function(){return t.trackShare(e())}))};this.shareAppMessage=function(e){this.trackShare(e);a.shareAppMessage(e)}}var oe=[];function se(){}se.prototype={createMethod:function(e,n,i){try{e[n]=i&&i[n]?function(){return i[n].apply(i,arguments)}:function(){oe.push([n,[].slice.call(arguments)])}}catch(e){t().v("create method errror: ",e)}},installApi:function(e,n){try{var i,r,o="resume,pause,trackEvent,trackPageStart,trackPageEnd,trackShare,setUserid,setOpenid,setUnionid,onShareAppMessage,shareAppMessage".split(",");for(i=0,r=o.length;i<r;i++)this.createMethod(e,o[i],n);if(n)for(i=0,r=oe.length;i<r;i++){var s=oe[i];try{n[s[0]].apply(n,s[1])}catch(e){t().v("impl[v[0]].apply error: ",s[0],e)}}}catch(e){t().v("install api errror: ",e)}}};var ae=[u.ENDPOINT,u.ENDPOINTB];function ue(e,n){var i,r;0===e||1===e&&n?i=u.ENDPOINT:2===e&&n?i=u.ENDPOINTB:n&&(i=ae[e]);if(e>=ae.length||n){n&&(r=i,u.ENDPOINT=r);n&&t().v("命中可用服务",i);!n&&t().tip_w("未命中可用服务");return!1}a.request({url:u.ENDPOINT+"/uminiprogram_logs/ckdh",success:function(t){200===(t.code||t.status||t.statusCode)&&t.data&&200===t.data.code?ue(e+1,!0):ue(e+1,!1)},fail:function(){ue(e+1,!1)}})}var ce={init:function(e){u.ENDPOINTB&&setTimeout((function(){ue(0,!1)}),e)}},fe=new se,pe={_inited:!1,_log:t(),preinit:function(e){if(e&&"object"==typeof e)for(var t in e)u[t]=e[t];return u},use:function(e,t){e&&f.isFunction(e.install)?e.install(pe,t):f.isFunction(e)&&e(pe,t);return pe},messager:r,init:function(e){if(this._inited)t().v("已经实例过,请避免重复初始化");else if(e)if(e.appKey){"boolean"!=typeof e.useOpenid&&(e.useOpenid=!0);n().set(e);t().setDebug(e.debug);this._inited=!0;var i=this;r.emit(r.messageType.CONFIG_LOADED,e);try{var o=new re;t().v("成功创建Lib对象");0;o.init((function(){t().v("Lib对象初始化成功");fe.installApi(i,o);t().v("安装Lib接口成功");r.emit(r.messageType.UMA_LIB_INITED,e)}));ce.init(3e3)}catch(e){t().w("创建Lib对象异常: "+e)}}else t().err("请确保传入正确的appkey");else t().err("请正确设置相关信息!")}};try{fe.installApi(pe,null)}catch(e){t().w("uma赋值异常: ",e)}var le={FETCH_URL:"https://ucc.umeng.com/v1/mini/fetch",ABLOG_URL:"https://pslog.umeng.com/mini_ablog",SDK_VERSION:"2.8.2",MOBILE_NETWORK_NONE:"none",MOBILE_NETWORK_2G:"2g",MOBILE_NETWORK_3G:"3g",MOBILE_NETWORK_4G:"4g",MOBILE_NETWORK_5G:"5g",MOBILE_NETWORK_WIFI:"wifi",IMPRINT:"imprint"},de={},he=Array.isArray;de.isArray=he||function(e){return"[object Array]"===toString.call(e)};de.isObject=function(e){return e===Object(e)&&!de.isArray(e)};de.isEmptyObject=function(e){if(de.isObject(e)){for(var t in e)if(hasOwnProperty.call(e,t))return!1;return!0}return!1};de.isUndefined=function(e){return void 0===e};de.isString=function(e){return"[object String]"===toString.call(e)};de.isDate=function(e){return"[object Date]"===toString.call(e)};de.isNumber=function(e){return"[object Number]"===toString.call(e)};de.each=function(e,t,n){if(null!=e){var i={},r=Array.prototype.forEach;if(r&&e.forEach===r)e.forEach(t,n);else if(e.length===+e.length){for(var o=0,s=e.length;o<s;o++)if(o in e&&t.call(n,e[o],o,e)===i)return}else for(var a in e)if(hasOwnProperty.call(e,a)&&t.call(n,e[a],a,e)===i)return}};de.buildQuery=function(e,t){var n,i,r=[];void 0===t&&(t="&");de.each(e,(function(e,t){n=encodeURIComponent(e.toString());i=encodeURIComponent(t);r[r.length]=i+"="+n}));return r.join(t)};de.JSONDecode=function(e){if(e){try{return JSON.parse(e)}catch(e){console.error("JSONDecode error",e)}return null}};de.JSONEncode=function(e){try{return JSON.stringify(e)}catch(e){console.error("JSONEncode error",e)}};var ge=Object.create(null);function ve(e){t().v("开始构建 fetch body");a.getSystemInfo((function(t){a.getNetworkInfo((function(i){var r=(i=i||{}).networkType;r=r===le.MOBILE_NETWORK_NONE?"unknown":r.toUpperCase();ge.access=r;!function(e,t){var i=e.brand||"";ge.deviceType="Phone";ge.sdkVersion=le.SDK_VERSION;ge.appkey=n().appKey();ge.sdkType=a.getSdkType();ge.umid=l().getId();if(e){ge.language=e.language||"";ge.os=e.OS;ge.osVersion=e.OSVersion;ge.deviceName=e.deviceName;ge.platformVersion=e.platformVersion;ge.platformSdkVersion=e.platformSDKVersion;ge.deviceBrand=i;var r=e.resolution.split("*");if(de.isArray(r)){ge.resolutionHeight=Number(r[0]);ge.resolutionWidth=Number(r[1])}}!function(e){if(e){ge.installTime=e.install_datetime&&Date.parse(e.install_datetime);ge.scene=e.install_scene;ge.channel=e.install_channel;ge.campaign=e.install_campaign}}(Z.getImpObj());t&&t(ge)}(t,e)}))}))}var _e=Object.create(null),ye=null,me=!1,Se={minFetchIntervalSeconds:43200};function Ie(e){e&&de.each(e,(function(e){_e[e.k]=e}))}function Ee(){var e=this;this.STORAGE_NAME=null;r.once(r.messageType.CONFIG_LOADED,(function(n){t().v("云配初始化开始...");e.init(n)}))}Ee.prototype={setDefaultValues:function(e){me&&de.isObject(e)&&de.each(e,(function(e,t){_e[t]&&_e[t].v||(_e[t]={v:e})}))},getValue:function(e){t().v("从配置项中读取 value, 当前配置为: ",_e);t().v("待读取的 key : ",e);try{if(!me)return;var i=_e[e]||{};t().v("读取相应配置ing..., 结果为: ",i);if(de.isNumber(i.e)&&de.isNumber(i.g)){t().v("读取到相应配置, 开始数据上报...");!function(e){var i={appkey:n().appKey(),sdkType:a.getSdkType(),expId:e&&e.e,groupId:e&&e.g,clientTs:Date.now(),key:e&&e.k,value:e&&e.v,umid:l().getId()};try{a.request({url:le.ABLOG_URL,method:"POST",data:[i],success:function(e){e&&200===e.statusCode?t().v("上传数据成功",i):t().w("ablog 请求成功, 返回结果异常 ",e)},fail:function(e){t().w("ablog 请求数据错误 ",i,e)}})}catch(e){t().w("urequest 调用错误",e)}}(i)}return i.v}catch(n){t().w("getValue error, key: ",e)}},active:function(e){try{if(!me)return;var n,i;e&&e.params&&(n=e.params);e&&e.callback&&(i=e.callback);t().v("激活配置项: ",n);if(n){t().v("本地已缓存的配置项: ",_e);Ie(n);t().v("合并后的配置项: ",_e);i&&i(_e);t().v("active 结束")}else{t().v("配置项为空!! 读取本地配置...");a.getStorage(this.STORAGE_NAME,(function(e){if(e){Ie((e=de.JSONDecode(e)||{}).params);t().v("当前本地配置项为: ",_e);i&&i(_e);t().v("active 结束")}else t().v("当前本地配置项为空, 退出激活")}))}}catch(e){t().w("SDK active 错误",e)}},init:function(e){if(e.appKey){ye=e.appKey;this.STORAGE_NAME="um_remote_config_{{"+ye+"}}"}if(ye)if(me)t().w("SDK 已经初始化, 请避免重复初始化");else{me=!0;this.setOptions(e);this.active()}else t().err("请检查您的小程序 appKey, appKey 不能为空")},setOptions:function(e){if(de.isObject(e)){var t=e.minFetchIntervalSeconds;de.isNumber(t)&&(Se.minFetchIntervalSeconds=Math.max(t,5))}},fetch:function(e){if(me&&this.STORAGE_NAME){var n,i;e&&e.active&&(n=e.active);e&&e.callback&&(i=e.callback);var r=this;a.getStorage(this.STORAGE_NAME,(function(e){t().v("开始读缓存 data is ",e);if((e=de.JSONDecode(e)||{}).params&&e.ts&&Date.now()-e.ts<1e3*Se.minFetchIntervalSeconds){t().v("缓存数据存在, 并且本次触发时间距离上次fetch触发时间未超过 fetch 时间间隔, 无需 fetch");i&&i(e.params)}else ve((function(e){t().v("缓存数据不存在, 构建 fetch body :",e);try{a.request({url:le.FETCH_URL,method:"POST",data:e,success:function(e){if(e&&200===e.statusCode&&e.data&&e.data.cc){t().v("fetch 请求成功, 响应数据: ",e.data);var o=Object.create(null);de.each(e.data.cc,(function(e){o[e.k]=e}));var s={ts:Date.now(),params:o};t().v("开始缓存 fetch 请求的云配置结果...");a.setStorage(r.STORAGE_NAME,de.JSONEncode(s),(function(e){t().v("缓存云配置成功, 缓存数据为: ",s);t().v("缓存云配置成功, 成功消息为: ",e);t().v("云配拉取数据是否自动激活: ",n);if(e&&n){t().v("激活云配置...");r.active({params:o,callback:i})}}))}else{t().w("fetch 请求成功,返回结果异常 ",e.data);i&&i()}},fail:function(n){t().w("fetch请求数据错误 ",e,n);i&&i()}})}catch(e){t().w("urequest调用错误",e)}}))}))}}};var Oe={install:function(e,t){e.rc||(e.rc=new Ee);e.messager.once(e.messager.messageType.CONFIG_LOADED,(function(){e._log.v("plugin rc installed")}));return e.rc}},Ae=".",Ne="_um",Te="revenue",we="stage",ke="level",be="running",De="end",Re="init",Ue="set",Pe=[Ne,we,"start"].join(Ae);function Le(e){var t={};for(var n in e){var i=e[n];if("object"==typeof i)for(var r in i)t[n+Ae+r]=i[r];else t[n]=i}return t}var Ce={install:function(e,t){e.revenue=function(t){e.trackEvent([Ne,Te,t.group].join(Ae),Le(t))};var n=0;e.stage={onStart:function(t){n=Date.now();e.trackEvent(Pe,Le(t))},onEnd:function(t){"number"!=typeof t._um_sdu&&(t._um_sdu=0!==n?Date.now()-n:0);e.trackEvent([Ne,we,De,t.event].join(Ae),Le(t))},onRunning:function(t){e.trackEvent([Ne,we,be,t.event].join(Ae),Le(t))}};e.level={onInitLevel:function(t){e.trackEvent([Ne,ke,Re].join(Ae),Le(t))},onSetLevel:function(t){e.trackEvent([Ne,ke,Ue].join(Ae),Le(t))}};e.messager.once(e.messager.messageType.CONFIG_LOADED,(function(){e._log.v("plugin game-ext installed")}));return e}};(typeof wx!=="undefined")&&wx.onShow((function(e){t().v("game onShow: ",e);n=e.query,h=n;var n;pe.resume(e,!0)}));(typeof wx!=="undefined")&&wx.onHide((function(){t().v("game onHide");pe.pause()}));var Me=pe.init;pe.init=function(e){if(e&&e.useOpenid){t().tip_w(t().repeat("!"));t().tip_w("您选择了使用openid进行统计,请确保使用setOpenid回传openid或通过设置autoGetOpenid为true,并在友盟后台设置secret由友盟帮您获取");t().tip_w(t().repeat("!"))}Me.call(pe,e)};pe.use(Oe);pe.use(Ce);(typeof wx!=="undefined")&&(wx.uma=pe)
16
+
17
+ // ============================================
18
+ // TypeScript 类型声明
19
+ // ============================================
20
+
21
+ /**
22
+ * 友盟初始化配置(官网接口)
23
+ */
24
+ export interface UmaInitConfig {
25
+ /** 应用 appKey(必填) */
26
+ appKey: string;
27
+ /** 是否使用 openid 统计,默认 true */
28
+ useOpenid?: boolean;
29
+ /** 是否自动获取 openid,需在友盟后台配置 secret */
30
+ autoGetOpenid?: boolean;
31
+ /** 是否开启调试模式 */
32
+ debug?: boolean;
33
+ }
34
+
35
+ /**
36
+ * 用户信息
37
+ */
38
+ export interface UmaUserInfo {
39
+ nickName?: string;
40
+ avatarUrl?: string;
41
+ gender?: number;
42
+ country?: string;
43
+ province?: string;
44
+ city?: string;
45
+ language?: string;
46
+ age?: number;
47
+ constellation?: string;
48
+ }
49
+
50
+ /**
51
+ * 友盟 SDK 接口定义
52
+ */
53
+ export interface UmaSDK {
54
+ /** 初始化 */
55
+ init(config: UmaInitConfig): void;
56
+ /** 恢复会话(onShow 时调用) */
57
+ resume(options?: any): void;
58
+ /** 暂停会话(onHide 时调用) */
59
+ pause(): void;
60
+ /** 上报自定义事件 */
61
+ trackEvent(eventName: string, params?: object | string): void;
62
+ /** 上报分享 */
63
+ trackShare(shareOptions: object): object;
64
+ /** 页面开始 */
65
+ trackPageStart(pageName: string): void;
66
+ /** 页面结束 */
67
+ trackPageEnd(pageName: string): void;
68
+ /** 设置 openid */
69
+ setOpenid(openid: string): void;
70
+ /** 设置 unionid */
71
+ setUnionid(unionid: string): void;
72
+ /** 设置用户 ID */
73
+ setUserid(userid: string, provider?: string): void;
74
+ /** 移除用户 ID */
75
+ removeUserid(): void;
76
+ /** 设置用户信息 */
77
+ setUserInfo(userInfo: UmaUserInfo): void;
78
+ /** 设置匿名 ID */
79
+ setAnonymousid(anonymousid: string): void;
80
+ /** 设置应用版本 */
81
+ setAppVersion(version: string): void;
82
+ /** 设置超级属性 */
83
+ setSuperProperty(property: string): void;
84
+ /** 注册分享回调 */
85
+ onShareAppMessage(callback: () => object): void;
86
+ /** 调用分享 */
87
+ shareAppMessage(options: object): void;
88
+ /** 收入事件 */
89
+ revenue?: (params: { group: string; [key: string]: any }) => void;
90
+ /** 关卡事件 */
91
+ stage?: {
92
+ onStart: (params: { [key: string]: any }) => void;
93
+ onEnd: (params: { event: string; [key: string]: any }) => void;
94
+ onRunning: (params: { event: string; [key: string]: any }) => void;
95
+ };
96
+ /** 等级事件 */
97
+ level?: {
98
+ onInitLevel: (params: { [key: string]: any }) => void;
99
+ onSetLevel: (params: { [key: string]: any }) => void;
100
+ };
101
+ }
102
+
103
+ // ============================================
104
+ // 导出
105
+ // ============================================
106
+
107
+ export const uma: UmaSDK = pe as any;
@@ -9,6 +9,7 @@ export class LogUtils {
9
9
  static TAG: string = "LogUtils";
10
10
 
11
11
  private isDebug: boolean = false;
12
+ private _timers: Map<string, number> = new Map();
12
13
 
13
14
  /**
14
15
  * 初始化日志模块
@@ -133,6 +134,32 @@ export class LogUtils {
133
134
  return `[${level}][${tag}][${timestamp}]: ${content}`;
134
135
  }
135
136
 
137
+ /**
138
+ * 开始计时
139
+ * @param label 计时标签
140
+ */
141
+ public timeStart(label: string): void {
142
+ if (!this.isDebug) return;
143
+ this._timers.set(label, Date.now());
144
+ console.log(this.formatLog("TIMER", label, "计时开始"));
145
+ }
146
+
147
+ /**
148
+ * 结束计时并输出耗时
149
+ * @param label 计时标签(需与 timeStart 匹配)
150
+ */
151
+ public timeEnd(label: string): void {
152
+ if (!this.isDebug) return;
153
+ const startTime = this._timers.get(label);
154
+ if (startTime === undefined) {
155
+ console.warn(this.formatLog("TIMER", label, "未找到计时起点"));
156
+ return;
157
+ }
158
+ const elapsed = Date.now() - startTime;
159
+ this._timers.delete(label);
160
+ console.log(this.formatLog("TIMER", label, `耗时 ${elapsed}ms`));
161
+ }
162
+
136
163
  /**
137
164
  * 格式化值
138
165
  */
@@ -23,4 +23,115 @@ export class ObjectUtils {
23
23
 
24
24
  return keysA.every(key => ObjectUtils.deepEqual(a[key], b[key]));
25
25
  }
26
+
27
+ // ======================== Base64 编解码 ========================
28
+
29
+ private static readonly BASE64_CHARS: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
30
+
31
+ /**
32
+ * 将字符串转为 UTF-8 字节数组
33
+ */
34
+ private static utf8ToBytes(str: string): number[] {
35
+ const bytes: number[] = [];
36
+ for (let i = 0; i < str.length; i++) {
37
+ const code = str.charCodeAt(i);
38
+ if (code < 0x80) {
39
+ bytes.push(code);
40
+ } else if (code < 0x800) {
41
+ bytes.push(0xC0 | (code >> 6));
42
+ bytes.push(0x80 | (code & 0x3F));
43
+ } else if (code >= 0xD800 && code <= 0xDBFF) {
44
+ // 代理对(emoji 等)
45
+ const hi = code;
46
+ const lo = str.charCodeAt(++i);
47
+ const codePoint = ((hi - 0xD800) << 10) + (lo - 0xDC00) + 0x10000;
48
+ bytes.push(0xF0 | (codePoint >> 18));
49
+ bytes.push(0x80 | ((codePoint >> 12) & 0x3F));
50
+ bytes.push(0x80 | ((codePoint >> 6) & 0x3F));
51
+ bytes.push(0x80 | (codePoint & 0x3F));
52
+ } else {
53
+ bytes.push(0xE0 | (code >> 12));
54
+ bytes.push(0x80 | ((code >> 6) & 0x3F));
55
+ bytes.push(0x80 | (code & 0x3F));
56
+ }
57
+ }
58
+ return bytes;
59
+ }
60
+
61
+ /**
62
+ * 将 UTF-8 字节数组转为字符串
63
+ */
64
+ private static utf8FromBytes(bytes: number[]): string {
65
+ let result = "";
66
+ let i = 0;
67
+ while (i < bytes.length) {
68
+ const b1 = bytes[i++];
69
+ if (b1 < 0x80) {
70
+ result += String.fromCharCode(b1);
71
+ } else if (b1 < 0xE0) {
72
+ const b2 = bytes[i++];
73
+ result += String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
74
+ } else if (b1 < 0xF0) {
75
+ const b2 = bytes[i++];
76
+ const b3 = bytes[i++];
77
+ result += String.fromCharCode(((b1 & 0x0F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
78
+ } else {
79
+ const b2 = bytes[i++];
80
+ const b3 = bytes[i++];
81
+ const b4 = bytes[i++];
82
+ const codePoint = ((b1 & 0x07) << 18) | ((b2 & 0x3F) << 12) | ((b3 & 0x3F) << 6) | (b4 & 0x3F);
83
+ // 转为代理对
84
+ const offset = codePoint - 0x10000;
85
+ result += String.fromCharCode(0xD800 + (offset >> 10), 0xDC00 + (offset & 0x3FF));
86
+ }
87
+ }
88
+ return result;
89
+ }
90
+
91
+ /**
92
+ * Base64 编码(纯 JS 实现,兼容所有小游戏/快应用平台,支持中文和 emoji)
93
+ * @param str 要编码的字符串
94
+ * @returns Base64 编码后的字符串
95
+ */
96
+ public static base64Encode(str: string): string {
97
+ const bytes = ObjectUtils.utf8ToBytes(str);
98
+ const chars = ObjectUtils.BASE64_CHARS;
99
+ let result = "";
100
+ for (let i = 0; i < bytes.length; i += 3) {
101
+ const a = bytes[i];
102
+ const b = i + 1 < bytes.length ? bytes[i + 1] : 0;
103
+ const c = i + 2 < bytes.length ? bytes[i + 2] : 0;
104
+ result += chars[(a >> 2) & 0x3F];
105
+ result += chars[((a << 4) | (b >> 4)) & 0x3F];
106
+ result += i + 1 < bytes.length ? chars[((b << 2) | (c >> 6)) & 0x3F] : "=";
107
+ result += i + 2 < bytes.length ? chars[c & 0x3F] : "=";
108
+ }
109
+ return result;
110
+ }
111
+
112
+ /**
113
+ * Base64 解码(纯 JS 实现,兼容所有小游戏/快应用平台,支持中文和 emoji)
114
+ * @param str Base64 编码的字符串
115
+ * @returns 解码后的原始字符串
116
+ */
117
+ public static base64Decode(str: string): string {
118
+ const chars = ObjectUtils.BASE64_CHARS;
119
+ const bytes: number[] = [];
120
+ // 去除空白字符
121
+ str = str.replace(/\s/g, "");
122
+ for (let i = 0; i < str.length; i += 4) {
123
+ const a = chars.indexOf(str[i]);
124
+ const b = chars.indexOf(str[i + 1]);
125
+ const c = str[i + 2] === "=" ? 0 : chars.indexOf(str[i + 2]);
126
+ const d = str[i + 3] === "=" ? 0 : chars.indexOf(str[i + 3]);
127
+ bytes.push((a << 2) | (b >> 4));
128
+ if (str[i + 2] !== "=") {
129
+ bytes.push(((b & 0xF) << 4) | (c >> 2));
130
+ }
131
+ if (str[i + 3] !== "=") {
132
+ bytes.push(((c & 0x3) << 6) | d);
133
+ }
134
+ }
135
+ return ObjectUtils.utf8FromBytes(bytes);
136
+ }
26
137
  }
package/src/index.ts CHANGED
@@ -20,6 +20,7 @@ export { PrivacyMgr } from './Framework/Manager/PrivacyMgr';
20
20
  export { LifeCycleMgr } from './Framework/Manager/LifeCycleMgr';
21
21
  export { BaseMgr } from './Framework/Manager/BaseMgr';
22
22
  export { NodePoolMgr } from './Framework/Manager/NodePoolMgr';
23
+ export { AnalyticsMgr } from './Framework/Manager/AnalyticsMgr';
23
24
 
24
25
  // Utils 模块
25
26
  export { LogUtils } from './Framework/Utils/LogUtils';
@@ -55,3 +56,4 @@ export * from './Framework/Definition/UIDefinition';
55
56
  export * from './Framework/Definition/EventDefinition';
56
57
  export * from './Framework/Definition/TimerDefinition';
57
58
  export * from './Framework/Definition/FrameworkBase';
59
+ export * from './Framework/Definition/AnalyticsDefinition';