playsout-web-sdk 1.0.62 → 1.0.63

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 (102) hide show
  1. package/README.md +206 -366
  2. package/dist/arrow-DVB3ZH4I.png +0 -0
  3. package/dist/bofang-7CYHXAOR.png +0 -0
  4. package/dist/chunk-DXJDUM6W.js +2 -0
  5. package/dist/chunk-FQSZP2MS.cjs +2 -0
  6. package/dist/chunk-GZLJ3BX5.js +1929 -0
  7. package/dist/chunk-RBKA52ZP.cjs +1929 -0
  8. package/dist/chunk-VZ5ZVHY4.js +2 -0
  9. package/dist/chunk-ZWHQXIXN.cjs +2 -0
  10. package/dist/clock-UCOJBATJ.png +0 -0
  11. package/dist/comment-CYSCAN7M.png +0 -0
  12. package/dist/config.d.ts +2 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/{core → dist/core}/api.d.ts +1 -5
  15. package/dist/core/api.d.ts.map +1 -0
  16. package/{core → dist/core}/errors.d.ts +1 -4
  17. package/dist/core/errors.d.ts.map +1 -0
  18. package/{core → dist/core}/events.d.ts +1 -9
  19. package/{core → dist/core}/events.d.ts.map +1 -1
  20. package/{core → dist/core}/index.d.ts.map +1 -1
  21. package/{core → dist/core}/storage.d.ts +0 -1
  22. package/{core → dist/core}/storage.d.ts.map +1 -1
  23. package/{core → dist/core}/types.d.ts +2 -37
  24. package/dist/core/types.d.ts.map +1 -0
  25. package/dist/data/games.d.ts +3 -0
  26. package/dist/data/games.d.ts.map +1 -0
  27. package/dist/fenxiang-SHOVHZII.png +0 -0
  28. package/dist/index.cjs +1 -0
  29. package/{index.d.ts → dist/index.d.ts} +1 -1
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.global.js +1929 -0
  32. package/dist/index.iife.js +1929 -0
  33. package/{index.js → dist/index.js} +1 -1
  34. package/dist/like-UTHO5POC.png +0 -0
  35. package/dist/live-like-4WE6H52V.png +0 -0
  36. package/dist/next-T6TSGXOI.png +0 -0
  37. package/dist/react/PlaysoutVideoWidget.d.ts +16 -0
  38. package/dist/react/PlaysoutVideoWidget.d.ts.map +1 -0
  39. package/dist/react/index.cjs +1 -0
  40. package/{react → dist/react}/index.d.ts +2 -0
  41. package/dist/react/index.d.ts.map +1 -0
  42. package/dist/react/index.js +1 -0
  43. package/dist/share-2WNZMMZ6.png +0 -0
  44. package/dist/shoucang-CSI3UBYK.png +0 -0
  45. package/dist/shuqian-KOBOMTMJ.png +0 -0
  46. package/dist/shuqian1-VMWYGXP3.png +0 -0
  47. package/dist/vue/PlaysoutVideoWidget.d.ts +31 -0
  48. package/dist/vue/PlaysoutVideoWidget.d.ts.map +1 -0
  49. package/{vue → dist/vue}/composable.d.ts +4 -2
  50. package/{vue → dist/vue}/composable.d.ts.map +1 -1
  51. package/dist/vue/index.cjs +1 -0
  52. package/{vue → dist/vue}/index.d.ts +1 -0
  53. package/dist/vue/index.d.ts.map +1 -0
  54. package/dist/vue/index.js +1 -0
  55. package/dist/web-components/PlaysoutVideoWidget.d.ts +59 -0
  56. package/dist/web-components/PlaysoutVideoWidget.d.ts.map +1 -0
  57. package/{web-components → dist/web-components}/PlaysoutWidget.d.ts +6 -3
  58. package/dist/web-components/PlaysoutWidget.d.ts.map +1 -0
  59. package/dist/web-components/index.cjs +1 -0
  60. package/dist/web-components/index.d.ts +5 -0
  61. package/dist/web-components/index.d.ts.map +1 -0
  62. package/dist/web-components/index.js +1 -0
  63. package/package.json +77 -63
  64. package/chunk-EZLO3WY6.js +0 -2
  65. package/chunk-MDSUYVLI.cjs +0 -2
  66. package/chunk-Z2CIDSTP.cjs +0 -2
  67. package/chunk-Z5PDR5PA.js +0 -2
  68. package/core/api.d.ts.map +0 -1
  69. package/core/errors.d.ts.map +0 -1
  70. package/core/types.d.ts.map +0 -1
  71. package/data/games.d.ts +0 -30
  72. package/data/games.d.ts.map +0 -1
  73. package/index.cjs +0 -1
  74. package/index.d.ts.map +0 -1
  75. package/index.global.js +0 -1546
  76. package/index.iife.js +0 -1546
  77. package/react/index.cjs +0 -1
  78. package/react/index.d.ts.map +0 -1
  79. package/react/index.js +0 -1
  80. package/vue/index.cjs +0 -1
  81. package/vue/index.d.ts.map +0 -1
  82. package/vue/index.js +0 -1
  83. package/web-components/PlaysoutWidget.d.ts.map +0 -1
  84. package/web-components/imageCache.d.ts +0 -13
  85. package/web-components/imageCache.d.ts.map +0 -1
  86. package/web-components/index.cjs +0 -1546
  87. package/web-components/index.d.ts +0 -3
  88. package/web-components/index.d.ts.map +0 -1
  89. package/web-components/index.js +0 -1546
  90. /package/{core → dist/core}/index.d.ts +0 -0
  91. /package/{iife-entry.d.ts → dist/iife-entry.d.ts} +0 -0
  92. /package/{iife-entry.d.ts.map → dist/iife-entry.d.ts.map} +0 -0
  93. /package/{public-api.d.ts → dist/public-api.d.ts} +0 -0
  94. /package/{public-api.d.ts.map → dist/public-api.d.ts.map} +0 -0
  95. /package/{react → dist/react}/context.d.ts +0 -0
  96. /package/{react → dist/react}/context.d.ts.map +0 -0
  97. /package/{vue → dist/vue}/plugin.d.ts +0 -0
  98. /package/{vue → dist/vue}/plugin.d.ts.map +0 -0
  99. /package/{web-components → dist/web-components}/PrivyBridge.d.ts +0 -0
  100. /package/{web-components → dist/web-components}/PrivyBridge.d.ts.map +0 -0
  101. /package/{web-components → dist/web-components}/assetUrl.d.ts +0 -0
  102. /package/{web-components → dist/web-components}/assetUrl.d.ts.map +0 -0
package/index.global.js DELETED
@@ -1,1546 +0,0 @@
1
- "use strict";var __PlaysoutBundle=(()=>{var q=Object.defineProperty;var De=Object.getOwnPropertyDescriptor;var Ue=Object.getOwnPropertyNames;var ze=Object.prototype.hasOwnProperty;var Be=(r,t)=>{for(var e in t)q(r,e,{get:t[e],enumerable:!0})},He=(r,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ue(t))!ze.call(r,o)&&o!==e&&q(r,o,{get:()=>t[o],enumerable:!(a=De(t,o))||a.enumerable});return r};var je=r=>He(q({},"__esModule",{value:!0}),r);var Nt={};Be(Nt,{Login:()=>wt,PlaysoutSDKClass:()=>Ot,destroy:()=>vt,getCategories:()=>Pt,getGames:()=>At,getLocale:()=>Tt,getToken:()=>xt,getUser:()=>St,getUserInfo:()=>It,init:()=>ft,instance:()=>_t,isInitialized:()=>Rt,isLoggedIn:()=>Mt,logout:()=>kt,mount:()=>bt,off:()=>Ct,on:()=>Lt,setLocale:()=>Et,unmount:()=>yt});var w=class extends Error{constructor(e,a,o){super(a);this.code=e;this.details=o;this.name="SDKError"}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}},$e={NOT_INITIALIZED:"SDK not initialized. Please call PlaysoutSDK.init() first.",ALREADY_INITIALIZED:"SDK already initialized. Please do not call init() more than once.",NOT_LOGGED_IN:"User not logged in. Please log in first.",TOKEN_EXPIRED:"Login token has expired. Please log in again.",INVALID_TOKEN:"Invalid login token. Please log in again.",NETWORK_ERROR:"Network connection failed. Please check your network.",TIMEOUT:"Request timed out. Please try again later.",SERVER_ERROR:"Server is busy. Please try again later.",API_ERROR:"API request failed.",INVALID_PARAMS:"Invalid parameter(s).",MISSING_PARAMS:"Missing required parameter(s).",FEATURE_NOT_SUPPORTED:"This feature is not supported in the current environment.",UNKNOWN:"An unknown error occurred.",PAYMENT_FAILED:"Payment failed.",SHARE_FAILED:"Share failed."};function g(r,t){return new w(r,$e[r],t)}var M="playsout_",_=class{constructor(t){this.storage=t}get(t){try{return this.storage.getItem(M+t)}catch{return null}}set(t,e){try{this.storage.setItem(M+t,e)}catch(a){console.warn("[PlaysoutSDK] Storage set failed:",a)}}remove(t){try{this.storage.removeItem(M+t)}catch{}}clear(){try{let t=[];for(let e=0;e<this.storage.length;e++){let a=this.storage.key(e);a&&a.startsWith(M)&&t.push(a)}t.forEach(e=>this.storage.removeItem(e))}catch{}}},W=class{constructor(){this.store=new Map}get(t){return this.store.get(t)??null}set(t,e){this.store.set(t,e)}remove(t){this.store.delete(t)}clear(){this.store.clear()}};function le(r="localStorage"){return typeof window>"u"||r==="memory"?new W:r==="sessionStorage"?new _(sessionStorage):new _(localStorage)}var x=le(),u={get:r=>x.get(r),set:(r,t)=>{x.set(r,t)},remove:r=>{x.remove(r)},clear:()=>{x.clear()},getJSON:r=>{let t=x.get(r);if(!t)return null;try{return JSON.parse(t)}catch{return null}},setJSON:(r,t)=>{x.set(r,JSON.stringify(t))},configure(r){x=le(r)}},h={TOKEN_DATA:"token_data",USER:"user",LOGIN_PARAMS:"login_params",LOCALE:"locale",CONFIG:"config"};var V=class{constructor(){this.events=new Map}on(t,e){return this.events.has(t)||this.events.set(t,new Set),this.events.get(t).add(e),()=>{this.off(t,e)}}once(t,e){let a=o=>{e(o),this.off(t,a)};return this.on(t,a)}off(t,e){this.events.get(t)?.delete(e),this.events.get(t)?.size===0&&this.events.delete(t)}emit(t,e){this.events.get(t)?.forEach(a=>{try{a(e)}catch(o){console.error(`[PlaysoutSDK] Event handler error for "${t}":`,o)}})}listenerCount(t){return this.events.get(t)?.size??0}clear(){this.events.clear()}},T=new V,b={on:(r,t)=>T.on(r,t),once:(r,t)=>T.once(r,t),off:(r,t)=>{T.off(r,t)},clear:()=>{T.clear()},emit:(r,t)=>{T.emit(r,t)}};var Ke="https://games.playsout.com/resources/icon/image";function l(r){if(!r||/^(data:|https?:|blob:)/i.test(r))return r;let t=r.replace(/^\.\//,"");return`${Ke}/${t}`}var Fe=r=>{if(!r)return r;try{let t=new URL(r);if(t.hostname==="games.playsout.com"){let e=t.pathname,a=e.endsWith("/"),o=/\.[a-z0-9]+$/i.test(e);!a&&!o&&(t.pathname=`${e}/`)}return t.toString()}catch{return r}},qe=r=>r.map(t=>{if(!t.externalUrl)return t;let e=Fe(t.externalUrl);return e===t.externalUrl?t:{...t,externalUrl:e}}),We=[{id:"BlockCrushFun",title:"Block Crush Fun",category:"Puzzle",image:l("./games/BlockCrushFun.png"),isNew:!0,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/BlockCrushFun/"},{id:"KittyEscape",title:"Kitty Escape",category:"Puzzle",image:l("./games/KittyEscape.jpg"),isNew:!0,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/KittyEscape/"},{id:"ProjectGarden",title:"Project: Garden",category:"Adventure",image:l("./games/SimulatedAdventures.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/simulated/"},{id:"ProjectIDLE",title:"Project: IDLE",category:"Simulation",image:l("./games/ProjectIDLE.jpg"),isNew:!0,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/idle/"},{id:"SoccerDASH",title:"Soccer Dash",category:"Arcade",image:l("./games/Soccer Dash.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SoccerDASH/"},{id:"SoccerSurvivor",title:"Soccer Survivor",category:"Arcade",image:l("./games/SoccerSurvivor.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SoccerSurvivors/"},{id:"CulinaryStarWeb",title:"Culinary Star",category:"Casual",image:l("./games/CulinaryStar.webp"),description:"Cooking game",isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/CulinaryStar/"},{id:"PickaxeQuest",title:"Pickaxe Quest",category:"Adventure",image:l("./games/PickaxeQuest.jpg"),description:"Mining and adventure game",isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/PickaxeQuest/",apiGameId:73},{id:"MonsterSurvivors",title:"Monster Survivors",category:"Adventure",image:l("./games/MonsterSurvivors.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/MonsterSurvivors/"},{id:"IdleTowerDefense",title:"Idle Tower Defense",category:"RPG",image:l("./games/IdleTowerDefense.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/IdleTowerDefense/"},{id:"MushroomWarriors",title:"Mushroom Warriors",category:"RPG",image:l("./games/MushroomWarriors.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/MushroomWarriors/"},{id:"FollowThePath",title:"Follow The Path",category:"Arcade",image:l("./games/FollowThePath.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/FollowThePath/"},{id:"SoccerCascade",title:"Soccer Cascade",category:"Arcade",image:l("./games/Soccer Cascade.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SoccerCascade/"},{id:"CatDelta",title:"Cat Delta",category:"Adventure",image:l("./games/CatDelta.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/CatDelta/"},{id:"ColorRun",title:"Color Run",category:"Arcade",image:l("./games/ColorRun.jpg"),isNew:!1,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/ColorRun/"},{id:"SoccerZombies",title:"Soccer vs. Zombies",category:"Tower Defense",image:l("./games/Soccer vs. Zombies.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SoccerZombies/"},{id:"MiniSoccer",title:"Mini Soccer",category:"Arcade",image:l("./games/minisoccer.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/minisoccer/"},{id:"SoccerMaze",title:"Soccer Maze",category:"Arcade",image:l("./games/Soccer Maze.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SoccerMaze/"},{id:"StupidArrow",title:"Stupid Arrow",category:"Arcade",image:l("./games/StupidArrow.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/StupidArrow/"},{id:"ZigZag",title:"Zig Zag",category:"Arcade",image:l("./games/ZigZag.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/ZigZag/"},{id:"SpikesEverywhere",title:"Spikes Everywhere",category:"Arcade",image:l("./games/SpikesEverywhere.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SpikesEverywhere/"},{id:"ArrowRacer",title:"Arrow Racer",category:"Arcade",image:l("./games/ArrowRacer.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/ArrowRacer/"},{id:"CircleLeap",title:"Circle Leap",category:"Arcade",image:l("./games/CircleLeap.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/CircleLeap/"},{id:"ColorMatcher",title:"Color Matcher",category:"Arcade",image:l("./games/ColorMatcher.jpg"),isNew:!1,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/ColorMatcher/"},{id:"EndlessMaze",title:"Endless Maze",category:"Arcade",image:l("./games/EndlessMaze.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/EndlessMaze/"},{id:"SpinningAround",title:"Spinning Around",category:"Arcade",image:l("./games/SpinningAround.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/SpinningAround/"},{id:"BoomBallz",title:"Boom Ballz",category:"Arcade",image:l("./games/BoomBallz.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/BoomBallz/"},{id:"CubeHead",title:"Cube Head",category:"Arcade",image:l("./games/CubeHead.jpg"),isNew:!1,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/CubeHead/"},{id:"CapybaraLink",title:"Capybara Link",category:"Puzzle",image:l("./games/CapybaraLink.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/CapybaraLink/"},{id:"Snake2048",title:"Snake 2048",category:"Puzzle",image:l("./games/Snake2048.jpg"),isNew:!0,isHot:!0,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/Snake2048/"},{id:"FishTankFury",title:"Fish Tank Fury",category:"Puzzle",image:l("./games/FishTankFury.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/FishTankFury/"},{id:"ConnectBalls",title:"Connect Balls",category:"Arcade",image:l("./games/ConnectBalls.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/ConnectBalls/"},{id:"CircularBreaker",title:"Circular Breaker",category:"Arcade",image:l("./games/CircularBreaker.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/CircularBreaker/"},{id:"OneDoor",title:"One Door",category:"Arcade",image:l("./games/OneDoor.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/OneDoor/"},{id:"CatchtheFruits",title:"Catch the Fruits",category:"Casual",image:l("./games/CatchtheFruits.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/CatchtheFruits/"},{id:"Falling2048",title:"Falling 2048",category:"Casual",image:l("./games/Falling2048.jpg"),isNew:!0,isHot:!1,enable:!0,orientation:"portrait",externalUrl:"https://games.playsout.com/grab/Falling2048/"}],ce=qe(We),v=()=>ce.filter(r=>r.enable),jt={Adventure:v().filter(r=>r.category==="Adventure"),Moba:v().filter(r=>r.category==="Moba")};var de=r=>ce.find(t=>t.id===r);var ge=()=>Array.from(new Set(v().map(r=>r.category)));var ee="https://api.playsout.com",te=3e4;function Ye(r){let t=String(r?.platform||"").toLowerCase();if(t==="tiktok"){let e=r.authorizationCode;if(typeof e!="string"||!e.trim())throw g("MISSING_PARAMS","authorizationCode is required for TikTok login");return{platform:t,authorizationCode:e}}if(t==="grab"||t==="eros"){let e=r;if(typeof e.platformUserId!="string"||!e.platformUserId.trim())throw g("MISSING_PARAMS","platformUserId is required for Grab/Eros login");if(typeof e.platformToken!="string"||!e.platformToken.trim())throw g("MISSING_PARAMS","platformToken is required for Grab/Eros login");if(typeof e.username!="string"||!e.username.trim())throw g("MISSING_PARAMS","username is required for Grab/Eros login");return{platform:t,platformUserId:e.platformUserId,platformToken:e.platformToken,username:e.username,inviteCode:typeof e.inviteCode=="string"?e.inviteCode:void 0}}throw g("INVALID_PARAMS","Unsupported platform. Expected grab, eros, or tiktok")}var A=null,J=null,Q=null,Z=null;function pe(r){J=r}function fe(r){Q=r}function be(r){Z=r}function ue(){if(Z)try{Z()}catch{}}async function Je(r){if(!Q)throw ue(),r instanceof w?r:g("TOKEN_EXPIRED",r);try{return await Q()}catch(t){throw ue(),t instanceof w?t:g("TOKEN_EXPIRED",t)}}async function me(r,t={},e,a=!1,o=a){let i=e?.apiBaseUrl||ee,n=r.startsWith("http")?r:`${i}${r}`,s=new AbortController,p=setTimeout(()=>s.abort(),te);try{let m=u.getJSON(h.TOKEN_DATA),f={"Content-Type":"application/json",...t.headers};a&&m?.accessToken&&!f.token&&(f.token=m.accessToken);let k=await fetch(n,{...t,signal:s.signal,headers:f});if(clearTimeout(p),!k.ok){if(k.status===401&&a&&o)return await he(r,t,e);throw g(k.status>=500?"SERVER_ERROR":"API_ERROR",`HTTP ${k.status}: ${k.statusText}`)}let E=await k.json();if(E.code!==1e4){if(a&&o)return await he(r,t,e);throw g("API_ERROR",E.msg||"API request failed")}return E.data}catch(m){throw clearTimeout(p),m instanceof w?m:m instanceof Error?m.name==="AbortError"?g("TIMEOUT"):g("NETWORK_ERROR",m.message):g("UNKNOWN")}}async function he(r,t,e){await ye(e);let a=e?.apiBaseUrl||ee,o=r.startsWith("http")?r:`${a}${r}`,i=new AbortController,n=setTimeout(()=>i.abort(),te);try{let s=u.getJSON(h.TOKEN_DATA),p={"Content-Type":"application/json",...t.headers};s?.accessToken&&(p.token=s.accessToken);let m=await fetch(o,{...t,signal:i.signal,headers:p});if(clearTimeout(n),!m.ok)throw g(m.status>=500?"SERVER_ERROR":"API_ERROR",`HTTP ${m.status}: ${m.statusText}`);let f=await m.json();if(f.code!==1e4)throw g("API_ERROR",f.msg||"API request failed");return f.data}catch(s){throw clearTimeout(n),s instanceof w?s:s instanceof Error&&s.name==="AbortError"?g("TIMEOUT"):g("NETWORK_ERROR",s?.message||"Request failed")}}async function ye(r){if(A)return A;let t=(async()=>{try{let e=u.getJSON(h.TOKEN_DATA),a=Math.floor(Date.now()/1e3);if(!e?.refreshToken||e.refreshExpiresAt<=a)throw g("TOKEN_EXPIRED","Refresh token has expired");let o=r?.apiBaseUrl||ee,i=new AbortController,n=setTimeout(()=>i.abort(),te);try{let s=await fetch(`${o}/platform/refreshToken`,{method:"POST",signal:i.signal,headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e.refreshToken})});if(clearTimeout(n),!s.ok)throw s.status>=500?g("SERVER_ERROR",`HTTP ${s.status}: ${s.statusText}`):g("TOKEN_EXPIRED",`HTTP ${s.status}: ${s.statusText}`);let p=await s.json();if(p.code!==1e4||!p.data)throw g("TOKEN_EXPIRED",p.msg||"Failed to refresh token");let m=p.data;if(u.setJSON(h.TOKEN_DATA,m),J)try{J(m)}catch{}return m}catch(s){throw clearTimeout(n),s instanceof w?s:s instanceof Error&&s.name==="AbortError"?g("TIMEOUT"):g("NETWORK_ERROR",s?.message||"Refresh token failed")}}catch(e){return await Je(e)}})();A=t;try{return await t}finally{A===t&&(A=null)}}var X=class{constructor(){this.config=null}configure(t){this.config=t}async refreshToken(){return await ye(this.config||void 0)}async getGames(t){let e=v();if(t?.category&&(e=e.filter(a=>a.category===t.category)),t?.search){let a=t.search.toLowerCase();e=e.filter(o=>o.title.toLowerCase().includes(a)||o.category.toLowerCase().includes(a)||o.description&&o.description.toLowerCase().includes(a))}if(t?.sortBy)switch(t.sortBy){case"newest":e=e.filter(a=>a.isNew).concat(e.filter(a=>!a.isNew));break;case"rating":e=e.filter(a=>a.isHot).concat(e.filter(a=>!a.isHot));break}if(t?.page&&t?.pageSize){let a=(t.page-1)*t.pageSize;e=e.slice(a,a+t.pageSize)}return e}async getCategories(){let t=v(),e=new Map;return t.forEach(a=>{let o=e.get(a.category)||0;e.set(a.category,o+1)}),Array.from(e.entries()).map(([a,o],i)=>({id:`category_${i}`,name:a,count:o}))}async getGameById(t){return de(t)}async getCategoryNames(){return ge()}async loginOnly(t){let e=Ye(t);return await me("/platform/login",{method:"POST",body:JSON.stringify(e)},this.config??void 0)}async Login(t){let e=await this.loginOnly(t);u.setJSON(h.TOKEN_DATA,e);try{let a=await this.getUserInfo(!1);return{tokenData:e,user:a}}catch(a){throw u.remove(h.TOKEN_DATA),u.remove(h.USER),a}}async getUserInfo(t=!0){return await me("/platform/user",{method:"GET"},this.config??void 0,!0,t)}async getUser(){return u.getJSON(h.USER)}async validateToken(t){return!!t}},Y=null;function O(){return Y||(Y=new X),Y}var Ze="https://api.playsout.com",ve="zh",P=class r{constructor(){this.config=null;this._isInitialized=!1;this._user=null;this._token=null;this._locale=ve;this._widget=null}clearAuthState(){let t=!!(this._token||u.get(h.TOKEN_DATA)||u.get(h.USER));return this._user=null,this._token=null,u.remove(h.TOKEN_DATA),u.remove(h.USER),u.remove(h.LOGIN_PARAMS),t}updateUser(t){this._user={userId:String(t.id),username:t.username},u.setJSON(h.USER,this._user)}saveLoginParams(t){if(t.platform==="grab"||t.platform==="eros"){u.setJSON(h.LOGIN_PARAMS,{...t});return}u.remove(h.LOGIN_PARAMS)}async performLogin(t,e){let a=O();a.configure(this.config);let o=await a.loginOnly(t);u.setJSON(h.TOKEN_DATA,o);let i=await a.getUserInfo(!1);return this._token=o.accessToken,this.updateUser(i),e&&this.saveLoginParams(t),b.emit("login",{user:this._user,token:this._token}),{tokenData:o,user:i}}async recoverAuthentication(){let t=u.getJSON(h.LOGIN_PARAMS);if(!t||t.platform!=="grab"&&t.platform!=="eros")throw g("TOKEN_EXPIRED","No reusable login parameters available");return(await this.performLogin(t,!1)).tokenData}handleAuthExpired(){this.clearAuthState()&&b.emit("authExpired"),this.config?.debug&&console.warn("[PlaysoutSDK] Auth expired, logged out")}static getInstance(){return r.instance||(r.instance=new r),r.instance}async init(t={}){if(this._isInitialized)throw g("ALREADY_INITIALIZED");this.config={apiBaseUrl:t.apiBaseUrl||Ze,debug:t.debug||!1,storage:t.storage||"localStorage",locale:t.locale||ve,appId:t.appId||""},u.configure(this.config.storage),pe(o=>{this._token=o.accessToken}),fe(()=>this.recoverAuthentication()),be(()=>{this.handleAuthExpired()});let e=u.getJSON(h.TOKEN_DATA);this._user=u.getJSON(h.USER),this._locale=u.get(h.LOCALE)||this.config.locale;let a=Math.floor(Date.now()/1e3);if(e){let o=O();if(o.configure(this.config),e.accessToken&&e.expiresAt>a?this._token=e.accessToken:await o.refreshToken(),this._token&&!this._user){let i=await o.getUserInfo();this.updateUser(i)}}else this._user&&(this._user=null,u.remove(h.USER));this._isInitialized=!0,this.config.debug&&(console.log("[PlaysoutSDK] Initialized with config:",this.config),console.log("[PlaysoutSDK] Restored token:",this._token?this._token.substring(0,20)+"...":"(none)")),b.emit("initialized")}destroy(){this.config=null,this._isInitialized=!1,this._user=null,this._token=null,u.clear(),b.clear()}get isInitialized(){return this._isInitialized}get isLoggedIn(){return!!(this._token&&this._user)}get user(){return this._user}get token(){return this._token}get locale(){return this._locale}get sdkConfig(){return this.config}async Login(t){this.ensureInitialized(),this.config?.debug&&console.log("[PlaysoutSDK] Login with params:",t);try{let e=await this.performLogin(t,!0);return this.config?.debug&&console.log("[PlaysoutSDK] Login success, user:",e.user),e}catch(e){throw this.clearAuthState(),e}}async getUserInfo(){if(this.ensureInitialized(),!this.isLoggedIn)throw g("NOT_LOGGED_IN","Please login first");let t=O();t.configure(this.config);let e=await t.getUserInfo();return this.config?.debug&&console.log("[PlaysoutSDK] getUserInfo result:",e),e&&this.updateUser(e),e}logout(){this.clearAuthState(),b.emit("logout")}getToken(){return this.ensureInitialized(),this._token}getUser(){return this.ensureInitialized(),this._user}setLocale(t){if(this.ensureInitialized(),!["zh","en","ja","ko","vi","th","id","ms"].includes(t))throw g("INVALID_PARAMS",`Unsupported locale: ${t}`);this._locale=t,u.set(h.LOCALE,t),this.config?.debug&&console.log("[PlaysoutSDK] Locale changed to:",t);let e=this._widget||document.querySelector("playsout-widget");e&&e.getAttribute("locale")!==t&&e.setAttribute("locale",t),b.emit("localeChange",t)}getLocale(){return this.ensureInitialized(),this._locale}async getGames(t){this.ensureInitialized();let e=v();if(t?.category&&(e=e.filter(a=>a.category===t.category)),t?.search){let a=t.search.toLowerCase();e=e.filter(o=>o.title.toLowerCase().includes(a)||o.category.toLowerCase().includes(a)||o.description&&o.description.toLowerCase().includes(a))}if(t?.sortBy)switch(t.sortBy){case"newest":e=e.filter(a=>a.isNew).concat(e.filter(a=>!a.isNew));break;case"rating":e=e.filter(a=>a.isHot).concat(e.filter(a=>!a.isHot));break}if(t?.page&&t?.pageSize){let a=(t.page-1)*t.pageSize;e=e.slice(a,a+t.pageSize)}return e}async getCategories(){this.ensureInitialized();let t=v(),e=new Map;return t.forEach(a=>{let o=e.get(a.category)||0;e.set(a.category,o+1)}),Array.from(e.entries()).map(([a,o],i)=>({id:`category_${i}`,name:a,count:o}))}async getGameById(t){return this.ensureInitialized(),v().find(e=>e.id===t)}mount(t,e){if(this.ensureInitialized(),typeof document>"u")throw g("FEATURE_NOT_SUPPORTED","mount requires DOM environment");let a=document.querySelector(t);if(!a)throw g("INVALID_PARAMS",`Container not found: ${t}`);let o=document.createElement("playsout-widget");this.config?.appId&&o.setAttribute("app-id",this.config.appId),o.setAttribute("locale",e?.locale||this._locale),e?.detailMode&&o.setAttribute("detail-mode",e.detailMode),this._widget=o,e?.onGameClick&&o.addEventListener("game-click",i=>{let n=i;e.onGameClick(n.detail)}),e?.onLoginRequired&&o.addEventListener("login-required",e.onLoginRequired),e?.onLocaleChange&&o.addEventListener("locale-change",i=>{let n=i;e.onLocaleChange(n.detail)}),a.appendChild(o),this.config?.debug&&console.log("[PlaysoutSDK] Widget mounted to:",t)}unmount(){let t=document.querySelector("playsout-widget");t&&t.remove(),this._widget=null}on(t,e){return this.ensureInitialized(),b.on(t,e)}off(t,e){this.ensureInitialized(),b.off(t,e)}ensureInitialized(){if(!this._isInitialized)throw g("NOT_INITIALIZED")}},c=P.getInstance();typeof window<"u"&&(window.__playsout_sdk_instance=c);var N=Object.freeze({init:c.init.bind(c),mount:c.mount.bind(c),unmount:c.unmount.bind(c),destroy:c.destroy.bind(c),Login:c.Login.bind(c),logout:c.logout.bind(c),getToken:c.getToken.bind(c),getUserInfo:c.getUserInfo.bind(c),getUser:c.getUser.bind(c),setLocale:c.setLocale.bind(c),getLocale:c.getLocale.bind(c),getGames:c.getGames.bind(c),getCategories:c.getCategories.bind(c),on:c.on.bind(c),off:c.off.bind(c),get isInitialized(){return c.isInitialized},get isLoggedIn(){return c.isLoggedIn},instance:c,PlaysoutSDKClass:P});var Xe="games.playsout.com";var ae="__playsout_img_cache_v1",B=`${ae}_blob_`,H=!1,D=4*1024*1024-1024*1024;function d(...r){}var I=new Map,G=new Map,et=50,L=new Map,U=new Map,y=0;function re(){try{let r=localStorage.getItem(ae);if(!r)return d("loadCacheIndex: \u65E0\u7F13\u5B58\u7D22\u5F15"),y=0,new Map;let t=JSON.parse(r);d("loadCacheIndex: \u52A0\u8F7D\u4E86",t.length,"\u6761\u8BB0\u5F55"),y=0;for(let e of t){let a=`${B}${btoa(e.url).replace(/[\/+=]/g,"_")}`;localStorage.getItem(a)&&(y+=e.size)}return d("loadCacheIndex: \u5F53\u524D blob \u603B\u91CF",y,"bytes"),new Map(t.map(e=>[e.url,e]))}catch{return d("loadCacheIndex: \u89E3\u6790\u5931\u8D25"),y=0,new Map}}function z(r){try{let t=Array.from(r.values());t.length>200&&(t.sort((e,a)=>a.timestamp-e.timestamp),t.length=200),localStorage.setItem(ae,JSON.stringify(t)),d("saveCacheIndex: \u4FDD\u5B58\u4E86",t.length,"\u6761\u8BB0\u5F55")}catch(t){d("saveCacheIndex: \u4FDD\u5B58\u5931\u8D25",t)}}function tt(r,t){if(!(y+t<=D))try{let e=re(),a=Array.from(e.values()).map(o=>({record:o,score:ke(o.url)??1/0})).filter(o=>o.score>r).sort((o,i)=>i.score-o.score);for(let{record:o}of a){if(y+t<=D)break;let i=`${B}${btoa(o.url).replace(/[\/+=]/g,"_")}`;localStorage.removeItem(i),e.delete(o.url),y-=o.size,d("evictLowerPriorityEntries: \u91CA\u653E\u4F4E\u4F18\u5148\u7EA7\u7F13\u5B58",o.url,"\u8282\u7701",o.size,"bytes")}z(e)}catch(e){d("evictLowerPriorityEntries: \u5931\u8D25",e)}}function we(r,t){if(I.size>=et){let e=null,a=1/0;for(let[o,i]of I)i.lastAccess<a&&(a=i.lastAccess,e=o);if(e){let o=I.get(e);URL.revokeObjectURL(URL.createObjectURL(o.blob)),I.delete(e),d("addToMemoryCache: LRU\u6DD8\u6C70",e)}}I.set(r,{blob:t,lastAccess:Date.now()}),d("addToMemoryCache: \u6DFB\u52A0\u5230\u5185\u5B58\u7F13\u5B58",r,"\u5927\u5C0F:",t.size,"bytes")}async function at(r){if(!H)return;if(G.has(r)){d("cacheImage:",r,"\u8BE5\u8BF7\u6C42\u5DF2\u5728\u8FDB\u884C\u4E2D\uFF0C\u7B49\u5F85\u5B8C\u6210"),await G.get(r);return}d("cacheImage: \u5F00\u59CB\u4E0B\u8F7D",r);let t=(async()=>{try{let e=await fetch(r);if(!e.ok){d("cacheImage:",r,"\u54CD\u5E94\u5931\u8D25",e.status);return}let a=await e.blob(),o=e.headers.get("ETag")||"";d("cacheImage:",r,"\u4E0B\u8F7D\u6210\u529F\uFF0C\u5927\u5C0F:",a.size,"ETag:",o),we(r,a);let i=ke(r);if(i!==void 0)if(tt(i,a.size),y+a.size<=D)try{let n=re();n.set(r,{url:r,timestamp:Date.now(),etag:o,size:a.size}),z(n);let s=JSON.stringify({type:a.type,data:Array.from(new Uint8Array(await a.arrayBuffer()))}),p=`${B}${btoa(r).replace(/[\/+=]/g,"_")}`;localStorage.setItem(p,s),y+=a.size,d("cacheImage:",r,"\u5DF2\u4FDD\u5B58\u5230localStorage\uFF08\u5360\u7528",a.size,"bytes\uFF0C\u9884\u7B97\u5269\u4F59",D-y,"\uFF09")}catch(n){n.name==="QuotaExceededError"?d("cacheImage: localStorage \u914D\u989D\u5DF2\u6EE1\uFF0C\u505C\u6B62\u5199\u5165"):d("cacheImage:",r,"localStorage\u4FDD\u5B58\u5931\u8D25",n)}else d("cacheImage:",r,"\u817E\u51FA\u7A7A\u95F4\u540E\u4ECD\u8D85\u8FC7\u9884\u7B97\uFF0C\u8DF3\u8FC7");else d("cacheImage:",r,"\u975E\u4F18\u5148\u7EA7URL\uFF0C\u4E0D\u5199\u5165localStorage")}catch(e){d("cacheImage:",r,"\u4E0B\u8F7D\u5931\u8D25",e)}finally{G.delete(r)}})();G.set(r,t)}function oe(r){try{if(new URL(r).hostname===Xe)return d("isCacheableImage:",r,"\u662FCDN\u56FE\u7247"),!0}catch{}return r.startsWith("/games/")||r.startsWith("./games/")||r.startsWith("/home-")||r.startsWith("./home-")||r.startsWith("/logo")||r.startsWith("./logo")?(d("isCacheableImage:",r,"\u662F\u672C\u5730\u56FE\u7247"),!0):(d("isCacheableImage:",r,"\u4E0D\u662F\u53EF\u7F13\u5B58\u7684\u56FE\u7247"),!1)}function ke(r){return U.has(r)?U.get(r):L.get(r)}function xe(r){if(!H)return;let t=-1e3;for(let e of r)oe(e)&&U.set(e,t++);d("setCriticalAssets: \u5171",U.size,"\u4E2A\u5173\u952E\u8D44\u6E90")}function Ie(r,t=!1){if(!H)return;t||L.clear();let e=0;if(t){for(let o of L.values())o>e&&(e=o);e+=1}let a=e;for(let o of r)oe(o)&&L.set(o,a++);d("setPriorityCache: \u5F53\u524D\u5171",L.size,"\u4E2A\u4F18\u5148\u7F13\u5B58URL")}function Se(r){if(!H)return r;if(d("resolveWithCache:",r),!oe(r))return d("resolveWithCache:",r,"\u4E0D\u662FCDN\u56FE\u7247\uFF0C\u539F\u6837\u8FD4\u56DE"),r;if(I.has(r)){let e=I.get(r);e.lastAccess=Date.now();try{let a=URL.createObjectURL(e.blob);return d("resolveWithCache:",r,"\u547D\u4E2D\u5185\u5B58\u7F13\u5B58\uFF0C\u8FD4\u56DEblob URL"),a}catch{d("resolveWithCache:",r,"\u521B\u5EFAblob URL\u5931\u8D25")}}let t=re();if(t.has(r)){let e=`${B}${btoa(r).replace(/[\/+=]/g,"_")}`,a=localStorage.getItem(e);if(a)try{let{type:o,data:i}=JSON.parse(a),n=new Blob([new Uint8Array(i)],{type:o});we(r,n);let s=URL.createObjectURL(n);return d("resolveWithCache:",r,"\u547D\u4E2DlocalStorage\u7F13\u5B58\uFF0C\u540C\u6B65\u8FD4\u56DEblob URL"),s}catch(o){d("resolveWithCache:",r,"localStorage blob\u89E3\u6790\u5931\u8D25\uFF0C\u6E05\u9664\u7F13\u5B58",o),t.delete(r),z(t),localStorage.removeItem(e)}else d("resolveWithCache:",r,"localStorage blob\u4E0D\u5B58\u5728\uFF0C\u6E05\u9664\u7D22\u5F15"),t.delete(r),z(t)}return d("resolveWithCache:",r,"\u5B8C\u5168\u6CA1\u6709\u7F13\u5B58\uFF0C\u540E\u53F0\u4E0B\u8F7D"),at(r),r}var ie="privy-bridge";var j="DIAMOND",rt="2025.01";var ot=()=>`host-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,S=r=>typeof r!="string"||r.length>128?"":r,it=r=>{let t=Number(r);return!Number.isSafeInteger(t)||t<=0?0:t},$=class{constructor(t){this.orders=new Map;this.pendingPayment=null;this.attached=!1;this.options=t,this.handleMessage=this.handleMessage.bind(this)}attach(){this.attached||typeof window>"u"||(window.addEventListener("message",this.handleMessage),this.attached=!0)}detach(){!this.attached||typeof window>"u"||(window.removeEventListener("message",this.handleMessage),this.attached=!1,this.cancelPendingPayment({code:"USER_CANCELLED",message:"Host view closed"}))}cancelPendingPayment(t={code:"USER_CANCELLED",message:"Payment cancelled"}){if(!this.pendingPayment)return;let e=this.pendingPayment;this.pendingPayment=null,this.updateOrderStatus(e.order.hostOrderId,"cancelled"),this.sendError(e.request,t)}handleMessage(t){let e=this.options.getIframe();if(!e?.contentWindow||t.source!==e.contentWindow)return;let a=this.getGameOrigin();if(!a||t.origin!==a)return;let o=t.data;if(this.isValidRequest(o))switch(o.method){case"bridge.handshake":this.handleHandshake(o);return;case"auth.getUser":this.handleGetUser(o);return;case"pay.createOrder":this.handleCreateOrder(o);return;case"pay.request":this.handlePaymentRequest(o);return;case"pay.query":this.handlePaymentQuery(o);return;default:this.sendError(o,{code:"INVALID_METHOD",message:"Unsupported method"})}}isValidRequest(t){return!!(t&&t.channel===ie&&t.type==="request"&&typeof t.id=="string"&&t.id.length>0&&t.id.length<=128&&typeof t.method=="string"&&t.method.length>0&&t.method.length<=128)}getGameOrigin(){let t=this.options.getGameUrl();if(!t||typeof window>"u")return"";try{return new URL(t,window.location.href).origin}catch{return""}}postToGame(t){let e=this.options.getIframe(),a=this.getGameOrigin();!e?.contentWindow||!a||e.contentWindow.postMessage(t,a)}sendResponse(t,e){this.postToGame({channel:ie,version:"1.0",type:"response",id:t.id,method:t.method,payload:e})}sendError(t,e){this.postToGame({channel:ie,version:"1.0",type:"response",id:t.id,method:t.method,error:e})}handleHandshake(t){this.sendResponse(t,{hostVersion:rt,capabilities:["auth.getUser","pay.createOrder","pay.request","pay.query"],capabilitiesDetail:{auth:{methods:["account"],scopes:["basic"]},pay:{methods:["balance"],currency:j,flow:["createOrder","request"]}},config:{currency:j}})}handleGetUser(t){let e=this.options.getUser();if(!e){this.sendError(t,{code:"AUTH_REQUIRED",message:"User not logged in"});return}this.sendResponse(t,{uid:e.uid,nickname:e.nickname,avatarUrl:e.avatarUrl||"",locale:this.options.getLocale(),roles:["player"]})}handleCreateOrder(t){let e=t.payload||{},a=S(e.orderId),o=S(e.productId),i=it(e.amount);if(!a||!i){this.sendError(t,{code:"INVALID_REQUEST",message:"Invalid order payload"});return}let n=ot(),s=Math.floor((Date.now()+6e5)/1e3),p={orderId:a,hostOrderId:n,amount:i,currency:j,productId:o,status:"created",expiresAt:s};this.orders.set(n,p),this.sendResponse(t,{orderId:a,hostOrderId:n,amount:i,currency:j,productId:o,expiresAt:s})}async handlePaymentRequest(t){let e=t.payload||{},a=S(e.orderId),o=S(e.hostOrderId);if(!a||!o){this.sendError(t,{code:"INVALID_REQUEST",message:"Missing orderId or hostOrderId"});return}if(this.pendingPayment){this.sendError(t,{code:"PAYMENT_PENDING",message:"Payment already in progress"});return}let i=this.orders.get(o);if(!i||i.orderId!==a){this.sendError(t,{code:"INVALID_REQUEST",message:"Order not found"});return}if(i.status==="success"){this.sendError(t,{code:"ORDER_ALREADY_PAID",message:"Order already paid"});return}if(i.expiresAt<=Math.floor(Date.now()/1e3)){this.updateOrderStatus(o,"expired"),this.sendError(t,{code:"ORDER_EXPIRED",message:"Order expired"});return}this.updateOrderStatus(o,"pending"),this.pendingPayment={request:t,order:i};let n=await this.options.requestPayment({orderId:i.orderId,hostOrderId:i.hostOrderId,amount:i.amount,currency:i.currency,productId:i.productId});if(this.pendingPayment?.request.id===t.id){if(this.pendingPayment=null,n.status==="success"){this.updateOrderStatus(o,"success"),this.sendResponse(t,{success:!0,orderId:a,hostOrderId:o,balance:n.balance});return}this.updateOrderStatus(o,n.status==="insufficient"?"created":"cancelled"),this.sendError(t,{code:n.status==="insufficient"?"INSUFFICIENT_BALANCE":"USER_CANCELLED",message:n.status==="insufficient"?"Insufficient balance":"User cancelled payment"})}}handlePaymentQuery(t){let e=t.payload||{},a=S(e.hostOrderId),o=S(e.orderId),i;if(a?i=this.orders.get(a):o&&(i=Array.from(this.orders.values()).find(n=>n.orderId===o)),!i){this.sendError(t,{code:"INVALID_REQUEST",message:"Order not found"});return}this.sendResponse(t,{orderId:i.orderId,hostOrderId:i.hostOrderId,amount:i.amount,currency:i.currency,status:i.status,expiresAt:i.expiresAt})}updateOrderStatus(t,e){let a=this.orders.get(t);a&&this.orders.set(t,{...a,status:e})}};var Ee={app:{title:"Playsout Mini Games",description:"Play quick games without login."},home:{loggedIn:"Logged in",logIn:"Log in",games:"Games",bannerAlt:"Playsout Games",searchPlaceholder:"Search by title or category",noGames:"No games found"},profile:{title:"Profile",settings:"Settings",language:"Language",recentGames:"Recently Played Games",noGames:"No games played yet",guest:"Guest",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"Adventure",Simulation:"Simulation",Casual:"Casual",Arcade:"Arcade",Moba:"Moba",Puzzle:"Puzzle"},auth:{loginSuccess:"Login successful!",loginTitle:"Playsout Login",welcome:"Welcome to the Playsout game platform",prompt:"Log in to start playing",mustLogin:"You must log in to play",authorizeHint:"Click the button below to authorize your login",authorizing:"Authorizing...",authorize:"Authorize login",terms:"By authorizing, you agree to our Terms of Service",signingIn:"Signing In",signMessage:"Please sign the message in your wallet"},game:{loading:"Loading",notFound:"Game not found",backHome:"Back to home",pageTitleSuffix:"Game Platform",header:{back:"Back",shareAria:"Share game",toggleMenuAria:"Toggle menu",fallbackTitle:"Game"}},menu:{favorite:"Favorite",favorited:"Favorited",profile:"Profile",login:"Login",refresh:"Refresh",loggedIn:"Logged in"},share:{title:"Share Game",closeLabel:"Close",retry:"Retry",loading:"Loading...",imageAlt:"Game share image",shareUrlLabel:"Share URL:",copied:"Copied",copy:"Copy",saveShare:"Save & Share",hint:"Image includes a QR code that links to this game",loadError:"Failed to load share image",downloadError:"Failed to download image"},checkin:{successTitle:"You got rewards!",successMessage:"Your rewards have been claimed.",failedTitle:"Check-in failed",canceledTitle:"Check-in canceled",errors:{userRejected:"You canceled the check-in operation",insufficientFunds:"Insufficient funds to pay gas",alreadyCheckedIn:"You already checked in today. Come back tomorrow!",network:"Network error. Please try again later"}},store:{title:"Gem Store",hot:"HOT",buy:"BUY",cancel:"Cancel",unit:"Gems",successTitle:"Payment Successful",successMessage:"You received {amount} gems!"},payment:{title:"Confirm Purchase",description:"Spend {amount} gems for this in-game item?",amountLabel:"{amount} gems",balance:"Current balance: {balance} gems",insufficientTitle:"Insufficient Balance",insufficientDesc:"Available: {gems} Gems",insufficientMessage:"Current balance is {balance} gems. This purchase needs {amount} gems.",cancel:"Cancel",confirm:"Confirm",recharge:"Recharge",successTitle:"Payment Successful",successMessage:"{amount} gems have been deducted.",invalidRequest:"Invalid payment request."}};var Te={app:{title:"Playsout \u5C0F\u6E38\u620F",description:"\u65E0\u9700\u767B\u5F55\u5373\u53EF\u7545\u73A9\u5C0F\u6E38\u620F\u3002"},home:{loggedIn:"\u5DF2\u767B\u5F55",logIn:"\u767B\u5F55",games:"\u6E38\u620F",bannerAlt:"Playsout \u6E38\u620F",searchPlaceholder:"\u6309\u6807\u9898\u6216\u7C7B\u522B\u641C\u7D22",noGames:"\u672A\u627E\u5230\u6E38\u620F"},profile:{title:"\u4E2A\u4EBA\u4E2D\u5FC3",settings:"\u8BBE\u7F6E",language:"\u8BED\u8A00",recentGames:"\u6700\u8FD1\u73A9\u8FC7\u7684\u6E38\u620F",noGames:"\u8FD8\u6CA1\u6709\u73A9\u8FC7\u6E38\u620F",guest:"\u6E38\u5BA2",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"\u5192\u9669",Simulation:"\u6A21\u62DF",Casual:"\u4F11\u95F2",Arcade:"\u8857\u673A",Moba:"MOBA",Puzzle:"\u76CA\u667A"},auth:{loginSuccess:"\u767B\u5F55\u6210\u529F!",loginTitle:"Playsout \u767B\u5F55",welcome:"\u6B22\u8FCE\u6765\u5230 Playsout \u6E38\u620F\u5E73\u53F0",prompt:"\u767B\u5F55\u5F00\u59CB\u6E38\u620F",mustLogin:"\u60A8\u5FC5\u987B\u767B\u5F55\u624D\u80FD\u73A9\u6E38\u620F",authorizeHint:"\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u6388\u6743\u767B\u5F55",authorizing:"\u6388\u6743\u4E2D...",authorize:"\u6388\u6743\u767B\u5F55",terms:"\u6388\u6743\u5373\u8868\u793A\u60A8\u540C\u610F\u6211\u4EEC\u7684\u670D\u52A1\u6761\u6B3E",signingIn:"\u767B\u5F55\u4E2D",signMessage:"\u8BF7\u5728\u94B1\u5305\u4E2D\u7B7E\u540D"},game:{loading:"\u52A0\u8F7D\u4E2D",notFound:"\u627E\u4E0D\u5230\u6E38\u620F",backHome:"\u8FD4\u56DE\u9996\u9875",pageTitleSuffix:"\u6E38\u620F\u5E73\u53F0",header:{back:"\u8FD4\u56DE",shareAria:"\u5206\u4EAB\u6E38\u620F",toggleMenuAria:"\u5207\u6362\u83DC\u5355",fallbackTitle:"\u6E38\u620F"}},menu:{favorite:"\u6536\u85CF",favorited:"\u5DF2\u6536\u85CF",profile:"\u4E2A\u4EBA\u4E2D\u5FC3",login:"\u767B\u5F55",refresh:"\u5237\u65B0",loggedIn:"\u5DF2\u767B\u5F55"},share:{title:"\u5206\u4EAB\u6E38\u620F",closeLabel:"\u5173\u95ED",retry:"\u91CD\u8BD5",loading:"\u52A0\u8F7D\u4E2D...",imageAlt:"\u6E38\u620F\u5206\u4EAB\u56FE\u7247",shareUrlLabel:"\u5206\u4EAB\u94FE\u63A5:",copied:"\u5DF2\u590D\u5236",copy:"\u590D\u5236",saveShare:"\u4FDD\u5B58\u5E76\u5206\u4EAB",hint:"\u56FE\u7247\u5305\u542B\u6B64\u6E38\u620F\u7684\u4E8C\u7EF4\u7801",loadError:"\u52A0\u8F7D\u5206\u4EAB\u56FE\u7247\u5931\u8D25",downloadError:"\u4E0B\u8F7D\u56FE\u7247\u5931\u8D25"},checkin:{successTitle:"\u9886\u53D6\u6210\u529F!",successMessage:"\u60A8\u7684\u5956\u52B1\u5DF2\u9886\u53D6\u3002",failedTitle:"\u7B7E\u5230\u5931\u8D25",canceledTitle:"\u7B7E\u5230\u53D6\u6D88",errors:{userRejected:"\u60A8\u53D6\u6D88\u4E86\u7B7E\u5230\u64CD\u4F5C",insufficientFunds:"\u4F59\u989D\u4E0D\u8DB3\u4EE5\u652F\u4ED8 Gas \u8D39",alreadyCheckedIn:"\u4ECA\u5929\u5DF2\u7ECF\u7B7E\u5230\u8FC7\u4E86\u3002\u660E\u5929\u518D\u6765\u5427!",network:"\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5"}},store:{title:"\u5B9D\u77F3\u5546\u5E97",hot:"\u70ED\u95E8",buy:"\u8D2D\u4E70",cancel:"\u53D6\u6D88",unit:"\u5B9D\u77F3",successTitle:"\u652F\u4ED8\u6210\u529F",successMessage:"\u60A8\u83B7\u5F97\u4E86 {amount} \u5B9D\u77F3\uFF01"},payment:{title:"\u786E\u8BA4\u8D2D\u4E70",description:"\u662F\u5426\u6D88\u8017 {amount} \u5B9D\u77F3\u8D2D\u4E70\u8BE5\u6E38\u620F\u9053\u5177\uFF1F",amountLabel:"{amount} \u5B9D\u77F3",balance:"\u5F53\u524D\u4F59\u989D\uFF1A{balance} \u5B9D\u77F3",insufficientTitle:"\u4F59\u989D\u4E0D\u8DB3",insufficientDesc:"\u53EF\u7528\u4F59\u989D: {gems} \u5B9D\u77F3",insufficientMessage:"\u5F53\u524D\u4F59\u989D\u4E3A {balance} \u5B9D\u77F3\uFF0C\u672C\u6B21\u8D2D\u4E70\u9700\u8981 {amount} \u5B9D\u77F3\u3002",cancel:"\u53D6\u6D88",confirm:"\u786E\u8BA4",recharge:"\u5145\u503C",successTitle:"\u652F\u4ED8\u6210\u529F",successMessage:"\u5DF2\u6263\u9664 {amount} \u5B9D\u77F3\u3002",invalidRequest:"\u652F\u4ED8\u8BF7\u6C42\u65E0\u6548\u3002"}};var Ae={app:{title:"Playsout \u30DF\u30CB\u30B2\u30FC\u30E0",description:"\u30ED\u30B0\u30A4\u30F3\u306A\u3057\u3067\u30B2\u30FC\u30E0\u3092\u30D7\u30EC\u30A4\u3002"},home:{loggedIn:"\u30ED\u30B0\u30A4\u30F3\u6E08\u307F",logIn:"\u30ED\u30B0\u30A4\u30F3",games:"\u30B2\u30FC\u30E0",bannerAlt:"Playsout \u30B2\u30FC\u30E0",searchPlaceholder:"\u30BF\u30A4\u30C8\u30EB\u307E\u305F\u306F\u30AB\u30C6\u30B4\u30EA\u3067\u691C\u7D22",noGames:"\u30B2\u30FC\u30E0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"},profile:{title:"\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB",settings:"\u8A2D\u5B9A",language:"\u8A00\u8A9E",recentGames:"\u6700\u8FD1\u30D7\u30EC\u30A4\u3057\u305F\u30B2\u30FC\u30E0",noGames:"\u307E\u3060\u30D7\u30EC\u30A4\u3057\u305F\u30B2\u30FC\u30E0\u304C\u3042\u308A\u307E\u305B\u3093",guest:"\u30B2\u30B9\u30C8",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"\u30A2\u30C9\u30D9\u30F3\u30C1\u30E3\u30FC",Simulation:"\u30B7\u30DF\u30E5\u30EC\u30FC\u30B7\u30E7\u30F3",Casual:"\u30AB\u30B8\u30E5\u30A2\u30EB",Arcade:"\u30A2\u30FC\u30B1\u30FC\u30C9",Moba:"MOBA",Puzzle:"\u30D1\u30BA\u30EB"},auth:{loginSuccess:"\u30ED\u30B0\u30A4\u30F3\u6210\u529F!",loginTitle:"Playsout \u30ED\u30B0\u30A4\u30F3",welcome:"Playsout \u30B2\u30FC\u30E0\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u3078\u3088\u3046\u3053\u305D",prompt:"\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u30D7\u30EC\u30A4\u3092\u958B\u59CB",mustLogin:"\u30D7\u30EC\u30A4\u3059\u308B\u306B\u306F\u30ED\u30B0\u30A4\u30F3\u304C\u5FC5\u8981\u3067\u3059",authorizeHint:"\u4E0B\u306E\u30DC\u30BF\u30F3\u3092\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044",authorizing:"\u627F\u8A8D\u4E2D...",authorize:"\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D",terms:"\u627F\u8A8D\u3059\u308B\u3053\u3068\u3067\u3001\u5229\u7528\u898F\u7D04\u306B\u540C\u610F\u3057\u305F\u3053\u3068\u306B\u306A\u308A\u307E\u3059",signingIn:"\u30B5\u30A4\u30F3\u30A4\u30F3\u4E2D",signMessage:"\u30A6\u30A9\u30EC\u30C3\u30C8\u3067\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u7F72\u540D\u3057\u3066\u304F\u3060\u3055\u3044"},game:{loading:"\u8AAD\u307F\u8FBC\u307F\u4E2D",notFound:"\u30B2\u30FC\u30E0\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",backHome:"\u30DB\u30FC\u30E0\u306B\u623B\u308B",pageTitleSuffix:"\u30B2\u30FC\u30E0\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0",header:{back:"\u623B\u308B",shareAria:"\u30B2\u30FC\u30E0\u3092\u5171\u6709",toggleMenuAria:"\u30E1\u30CB\u30E5\u30FC\u5207\u308A\u66FF\u3048",fallbackTitle:"\u30B2\u30FC\u30E0"}},menu:{favorite:"\u304A\u6C17\u306B\u5165\u308A",favorited:"\u304A\u6C17\u306B\u5165\u308A\u6E08\u307F",profile:"\u30D7\u30ED\u30D5\u30A3\u30FC\u30EB",login:"\u30ED\u30B0\u30A4\u30F3",refresh:"\u66F4\u65B0",loggedIn:"\u30ED\u30B0\u30A4\u30F3\u6E08\u307F"},share:{title:"\u30B2\u30FC\u30E0\u3092\u5171\u6709",closeLabel:"\u9589\u3058\u308B",retry:"\u518D\u8A66\u884C",loading:"\u8AAD\u307F\u8FBC\u307F\u4E2D...",imageAlt:"\u30B2\u30FC\u30E0\u5171\u6709\u753B\u50CF",shareUrlLabel:"\u5171\u6709URL:",copied:"\u30B3\u30D4\u30FC\u3057\u307E\u3057\u305F",copy:"\u30B3\u30D4\u30FC",saveShare:"\u4FDD\u5B58\u3057\u3066\u5171\u6709",hint:"\u753B\u50CF\u306B\u306F\u30B2\u30FC\u30E0\u3078\u306EQR\u30B3\u30FC\u30C9\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059",loadError:"\u5171\u6709\u753B\u50CF\u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F",downloadError:"\u753B\u50CF\u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u306B\u5931\u6557\u3057\u307E\u3057\u305F"},checkin:{successTitle:"\u5831\u916C\u3092\u7372\u5F97\u3057\u307E\u3057\u305F!",successMessage:"\u5831\u916C\u304C\u8ACB\u6C42\u3055\u308C\u307E\u3057\u305F\u3002",failedTitle:"\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u5931\u6557",canceledTitle:"\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u30AD\u30E3\u30F3\u30BB\u30EB",errors:{userRejected:"\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u64CD\u4F5C\u3092\u30AD\u30E3\u30F3\u30BB\u30EB\u3057\u307E\u3057\u305F",insufficientFunds:"\u30AC\u30B9\u4EE3\u3092\u652F\u6255\u3046\u6B8B\u9AD8\u304C\u4E0D\u8DB3\u3057\u3066\u3044\u307E\u3059",alreadyCheckedIn:"\u672C\u65E5\u306F\u65E2\u306B\u30C1\u30A7\u30C3\u30AF\u30A4\u30F3\u6E08\u307F\u3067\u3059\u3002\u660E\u65E5\u307E\u305F\u6765\u3066\u304F\u3060\u3055\u3044!",network:"\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u3002\u5F8C\u3067\u3082\u3046\u4E00\u5EA6\u304A\u8A66\u3057\u304F\u3060\u3055\u3044"}},store:{title:"\u30B8\u30A7\u30E0\u30B9\u30C8\u30A2",hot:"HOT",buy:"\u8CFC\u5165",cancel:"\u30AD\u30E3\u30F3\u30BB\u30EB",unit:"\u30B8\u30A7\u30E0",successTitle:"\u652F\u6255\u3044\u5B8C\u4E86",successMessage:"{amount}\u30B8\u30A7\u30E0\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF01"},payment:{title:"\u8CFC\u5165\u78BA\u8A8D",description:"\u3053\u306E\u30B2\u30FC\u30E0\u5185\u30A2\u30A4\u30C6\u30E0\u306B {amount} \u30B8\u30A7\u30E0\u3092\u4F7F\u7528\u3057\u307E\u3059\u304B\uFF1F",amountLabel:"{amount} \u30B8\u30A7\u30E0",balance:"\u73FE\u5728\u306E\u6B8B\u9AD8: {balance} \u30B8\u30A7\u30E0",insufficientTitle:"\u6B8B\u9AD8\u4E0D\u8DB3",insufficientDesc:"\u4FDD\u6709: {gems} \u30B8\u30A7\u30E0",insufficientMessage:"\u73FE\u5728\u306E\u6B8B\u9AD8\u306F {balance} \u30B8\u30A7\u30E0\u3067\u3059\u3002\u3053\u306E\u8CFC\u5165\u306B\u306F {amount} \u30B8\u30A7\u30E0\u304C\u5FC5\u8981\u3067\u3059\u3002",cancel:"\u30AD\u30E3\u30F3\u30BB\u30EB",confirm:"\u78BA\u8A8D",recharge:"\u30C1\u30E3\u30FC\u30B8",successTitle:"\u652F\u6255\u3044\u5B8C\u4E86",successMessage:"{amount} \u30B8\u30A7\u30E0\u304C\u5DEE\u3057\u5F15\u304B\u308C\u307E\u3057\u305F\u3002",invalidRequest:"\u652F\u6255\u3044\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u7121\u52B9\u3067\u3059\u3002"}};var Pe={app:{title:"Playsout \uBBF8\uB2C8 \uAC8C\uC784",description:"\uB85C\uADF8\uC778 \uC5C6\uC774 \uAC8C\uC784\uC744 \uC990\uAE30\uC138\uC694."},home:{loggedIn:"\uB85C\uADF8\uC778\uB428",logIn:"\uB85C\uADF8\uC778",games:"\uAC8C\uC784",bannerAlt:"Playsout \uAC8C\uC784",searchPlaceholder:"\uC81C\uBAA9 \uB610\uB294 \uCE74\uD14C\uACE0\uB9AC\uB85C \uAC80\uC0C9",noGames:"\uAC8C\uC784\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4"},profile:{title:"\uD504\uB85C\uD544",settings:"\uC124\uC815",language:"\uC5B8\uC5B4",recentGames:"\uCD5C\uADFC \uD50C\uB808\uC774\uD55C \uAC8C\uC784",noGames:"\uC544\uC9C1 \uD50C\uB808\uC774\uD55C \uAC8C\uC784\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",guest:"\uC190\uB2D8",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"\uC5B4\uB4DC\uBCA4\uCC98",Simulation:"\uC2DC\uBBAC\uB808\uC774\uC158",Casual:"\uCE90\uC8FC\uC5BC",Arcade:"\uC544\uCF00\uC774\uB4DC",Moba:"MOBA",Puzzle:"\uD37C\uC990"},auth:{loginSuccess:"\uB85C\uADF8\uC778 \uC131\uACF5!",loginTitle:"Playsout \uB85C\uADF8\uC778",welcome:"Playsout \uAC8C\uC784 \uD50C\uB7AB\uD3FC\uC5D0 \uC624\uC2E0 \uAC83\uC744 \uD658\uC601\uD569\uB2C8\uB2E4",prompt:"\uAC8C\uC784\uC744 \uC2DC\uC791\uD558\uB824\uBA74 \uB85C\uADF8\uC778\uD558\uC138\uC694",mustLogin:"\uAC8C\uC784\uC744 \uD558\uB824\uBA74 \uB85C\uADF8\uC778\uD574\uC57C \uD569\uB2C8\uB2E4",authorizeHint:"\uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uB824\uBA74 \uC544\uB798 \uBC84\uD2BC\uC744 \uD074\uB9AD\uD558\uC138\uC694",authorizing:"\uC2B9\uC778 \uC911...",authorize:"\uB85C\uADF8\uC778 \uC2B9\uC778",terms:"\uC2B9\uC778\uD558\uBA74 \uC11C\uBE44\uC2A4 \uC57D\uAD00\uC5D0 \uB3D9\uC758\uD558\uAC8C \uB429\uB2C8\uB2E4",signingIn:"\uB85C\uADF8\uC778 \uC911",signMessage:"\uC9C0\uAC11\uC5D0\uC11C \uBA54\uC2DC\uC9C0\uC5D0 \uC11C\uBA85\uD574\uC8FC\uC138\uC694"},game:{loading:"\uB85C\uB529 \uC911",notFound:"\uAC8C\uC784\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4",backHome:"\uD648\uC73C\uB85C \uB3CC\uC544\uAC00\uAE30",pageTitleSuffix:"\uAC8C\uC784 \uD50C\uB7AB\uD3FC",header:{back:"\uB4A4\uB85C",shareAria:"\uAC8C\uC784 \uACF5\uC720",toggleMenuAria:"\uBA54\uB274 \uC804\uD658",fallbackTitle:"\uAC8C\uC784"}},menu:{favorite:"\uC990\uACA8\uCC3E\uAE30",favorited:"\uC990\uACA8\uCC3E\uAE30\uB428",profile:"\uD504\uB85C\uD544",login:"\uB85C\uADF8\uC778",refresh:"\uC0C8\uB85C\uACE0\uCE68",loggedIn:"\uB85C\uADF8\uC778\uB428"},share:{title:"\uAC8C\uC784 \uACF5\uC720",closeLabel:"\uB2EB\uAE30",retry:"\uC7AC\uC2DC\uB3C4",loading:"\uB85C\uB529 \uC911...",imageAlt:"\uAC8C\uC784 \uACF5\uC720 \uC774\uBBF8\uC9C0",shareUrlLabel:"\uACF5\uC720 URL:",copied:"\uBCF5\uC0AC\uB428",copy:"\uBCF5\uC0AC",saveShare:"\uC800\uC7A5 \uBC0F \uACF5\uC720",hint:"\uC774\uBBF8\uC9C0\uC5D0 \uAC8C\uC784\uC73C\uB85C \uC5F0\uACB0\uB418\uB294 QR \uCF54\uB4DC\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4",loadError:"\uACF5\uC720 \uC774\uBBF8\uC9C0\uB97C \uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4",downloadError:"\uC774\uBBF8\uC9C0\uB97C \uB2E4\uC6B4\uB85C\uB4DC\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4"},checkin:{successTitle:"\uBCF4\uC0C1\uC744 \uBC1B\uC558\uC2B5\uB2C8\uB2E4!",successMessage:"\uBCF4\uC0C1\uC774 \uC9C0\uAE09\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",failedTitle:"\uCD9C\uC11D \uC2E4\uD328",canceledTitle:"\uCD9C\uC11D \uCDE8\uC18C\uB428",errors:{userRejected:"\uCD9C\uC11D \uC791\uC5C5\uC744 \uCDE8\uC18C\uD588\uC2B5\uB2C8\uB2E4",insufficientFunds:"\uAC00\uC2A4\uBE44\uB97C \uC9C0\uBD88\uD560 \uC790\uAE08\uC774 \uBD80\uC871\uD569\uB2C8\uB2E4",alreadyCheckedIn:"\uC624\uB298 \uC774\uBBF8 \uCD9C\uC11D\uD588\uC2B5\uB2C8\uB2E4. \uB0B4\uC77C \uB2E4\uC2DC \uC624\uC138\uC694!",network:"\uB124\uD2B8\uC6CC\uD06C \uC624\uB958. \uB098\uC911\uC5D0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694"}},store:{title:"\uBCF4\uC11D \uC0C1\uC810",hot:"\uC778\uAE30",buy:"\uAD6C\uB9E4",cancel:"\uCDE8\uC18C",unit:"\uBCF4\uC11D",successTitle:"\uACB0\uC81C \uC131\uACF5",successMessage:"{amount}\uAC1C\uC758 \uBCF4\uC11D\uC744 \uBC1B\uC558\uC2B5\uB2C8\uB2E4!"},payment:{title:"\uAD6C\uB9E4 \uD655\uC778",description:"\uC774 \uAC8C\uC784 \uC544\uC774\uD15C\uC5D0 \uBCF4\uC11D {amount}\uAC1C\uB97C \uC0AC\uC6A9\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",amountLabel:"\uBCF4\uC11D {amount}\uAC1C",balance:"\uD604\uC7AC \uC794\uC561: \uBCF4\uC11D {balance}\uAC1C",insufficientTitle:"\uC794\uC561 \uBD80\uC871",insufficientDesc:"\uBCF4\uC720: {gems} \uBCF4\uC11D",insufficientMessage:"\uD604\uC7AC \uC794\uC561\uC740 \uBCF4\uC11D {balance}\uAC1C\uC785\uB2C8\uB2E4. \uC774 \uAD6C\uB9E4\uC5D0\uB294 \uBCF4\uC11D {amount}\uAC1C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.",cancel:"\uCDE8\uC18C",confirm:"\uD655\uC778",recharge:"\uCDA9\uC804",successTitle:"\uACB0\uC81C \uC131\uACF5",successMessage:"\uBCF4\uC11D {amount}\uAC1C\uAC00 \uCC28\uAC10\uB418\uC5C8\uC2B5\uB2C8\uB2E4.",invalidRequest:"\uACB0\uC81C \uC694\uCCAD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."}};var Le={app:{title:"Playsout \u0E21\u0E34\u0E19\u0E34\u0E40\u0E01\u0E21",description:"\u0E40\u0E25\u0E48\u0E19\u0E40\u0E01\u0E21\u0E14\u0E48\u0E27\u0E19\u0E42\u0E14\u0E22\u0E44\u0E21\u0E48\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A"},home:{loggedIn:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E41\u0E25\u0E49\u0E27",logIn:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",games:"\u0E40\u0E01\u0E21",bannerAlt:"\u0E40\u0E01\u0E21 Playsout",searchPlaceholder:"\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E15\u0E32\u0E21\u0E0A\u0E37\u0E48\u0E2D\u0E2B\u0E23\u0E37\u0E2D\u0E2B\u0E21\u0E27\u0E14\u0E2B\u0E21\u0E39\u0E48",noGames:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E40\u0E01\u0E21"},profile:{title:"\u0E42\u0E1B\u0E23\u0E44\u0E1F\u0E25\u0E4C",settings:"\u0E01\u0E32\u0E23\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32",language:"\u0E20\u0E32\u0E29\u0E32",recentGames:"\u0E40\u0E01\u0E21\u0E17\u0E35\u0E48\u0E40\u0E25\u0E48\u0E19\u0E25\u0E48\u0E32\u0E2A\u0E38\u0E14",noGames:"\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E40\u0E01\u0E21\u0E17\u0E35\u0E48\u0E40\u0E25\u0E48\u0E19",guest:"\u0E1C\u0E39\u0E49\u0E40\u0E22\u0E35\u0E48\u0E22\u0E21\u0E0A\u0E21",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"\u0E1C\u0E08\u0E0D\u0E20\u0E31\u0E22",Simulation:"\u0E08\u0E33\u0E25\u0E2D\u0E07\u0E2A\u0E16\u0E32\u0E19\u0E01\u0E32\u0E23\u0E13\u0E4C",Casual:"\u0E41\u0E04\u0E0A\u0E0A\u0E27\u0E25",Arcade:"\u0E2D\u0E32\u0E23\u0E4C\u0E40\u0E04\u0E14",Moba:"\u0E42\u0E21\u0E1A\u0E32",Puzzle:"\u0E1B\u0E23\u0E34\u0E28\u0E19\u0E32"},auth:{loginSuccess:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08!",loginTitle:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A Playsout",welcome:"\u0E22\u0E34\u0E19\u0E14\u0E35\u0E15\u0E49\u0E2D\u0E19\u0E23\u0E31\u0E1A\u0E2A\u0E39\u0E48\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E40\u0E01\u0E21 Playsout",prompt:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E23\u0E34\u0E48\u0E21\u0E40\u0E25\u0E48\u0E19",mustLogin:"\u0E04\u0E38\u0E13\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E25\u0E48\u0E19",authorizeHint:"\u0E04\u0E25\u0E34\u0E01\u0E1B\u0E38\u0E48\u0E21\u0E14\u0E49\u0E32\u0E19\u0E25\u0E48\u0E32\u0E07\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E2D\u0E19\u0E38\u0E0D\u0E32\u0E15\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",authorizing:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2D\u0E19\u0E38\u0E0D\u0E32\u0E15...",authorize:"\u0E2D\u0E19\u0E38\u0E0D\u0E32\u0E15\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",terms:"\u0E01\u0E32\u0E23\u0E2D\u0E19\u0E38\u0E0D\u0E32\u0E15\u0E41\u0E2A\u0E14\u0E07\u0E27\u0E48\u0E32\u0E04\u0E38\u0E13\u0E22\u0E2D\u0E21\u0E23\u0E31\u0E1A\u0E02\u0E49\u0E2D\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E43\u0E19\u0E01\u0E32\u0E23\u0E43\u0E2B\u0E49\u0E1A\u0E23\u0E34\u0E01\u0E32\u0E23\u0E02\u0E2D\u0E07\u0E40\u0E23\u0E32",signingIn:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E25\u0E07\u0E0A\u0E37\u0E48\u0E2D\u0E40\u0E02\u0E49\u0E32\u0E43\u0E0A\u0E49",signMessage:"\u0E01\u0E23\u0E38\u0E13\u0E32\u0E40\u0E0B\u0E47\u0E19\u0E0A\u0E37\u0E48\u0E2D\u0E02\u0E49\u0E2D\u0E04\u0E27\u0E32\u0E21\u0E43\u0E19\u0E01\u0E23\u0E30\u0E40\u0E1B\u0E4B\u0E32\u0E40\u0E07\u0E34\u0E19\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13"},game:{loading:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14",notFound:"\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E40\u0E01\u0E21",backHome:"\u0E01\u0E25\u0E31\u0E1A\u0E2B\u0E19\u0E49\u0E32\u0E2B\u0E25\u0E31\u0E01",pageTitleSuffix:"\u0E41\u0E1E\u0E25\u0E15\u0E1F\u0E2D\u0E23\u0E4C\u0E21\u0E40\u0E01\u0E21",header:{back:"\u0E01\u0E25\u0E31\u0E1A",shareAria:"\u0E41\u0E0A\u0E23\u0E4C\u0E40\u0E01\u0E21",toggleMenuAria:"\u0E2A\u0E25\u0E31\u0E1A\u0E40\u0E21\u0E19\u0E39",fallbackTitle:"\u0E40\u0E01\u0E21"}},menu:{favorite:"\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E42\u0E1B\u0E23\u0E14",favorited:"\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E43\u0E19\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E42\u0E1B\u0E23\u0E14\u0E41\u0E25\u0E49\u0E27",profile:"\u0E42\u0E1B\u0E23\u0E44\u0E1F\u0E25\u0E4C",login:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",refresh:"\u0E23\u0E35\u0E40\u0E1F\u0E23\u0E0A",loggedIn:"\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E41\u0E25\u0E49\u0E27"},share:{title:"\u0E41\u0E0A\u0E23\u0E4C\u0E40\u0E01\u0E21",closeLabel:"\u0E1B\u0E34\u0E14",retry:"\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48",loading:"\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14...",imageAlt:"\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E41\u0E0A\u0E23\u0E4C\u0E40\u0E01\u0E21",shareUrlLabel:"\u0E41\u0E0A\u0E23\u0E4C URL:",copied:"\u0E04\u0E31\u0E14\u0E25\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27",copy:"\u0E04\u0E31\u0E14\u0E25\u0E2D\u0E01",saveShare:"\u0E1A\u0E31\u0E19\u0E17\u0E36\u0E01\u0E41\u0E25\u0E30\u0E41\u0E0A\u0E23\u0E4C",hint:"\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E23\u0E27\u0E21\u0E23\u0E2B\u0E31\u0E2A QR \u0E17\u0E35\u0E48\u0E25\u0E34\u0E07\u0E01\u0E4C\u0E44\u0E1B\u0E22\u0E31\u0E07\u0E40\u0E01\u0E21\u0E19\u0E35\u0E49",loadError:"\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E41\u0E0A\u0E23\u0E4C\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",downloadError:"\u0E14\u0E32\u0E27\u0E19\u0E4C\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08"},checkin:{successTitle:"\u0E04\u0E38\u0E13\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A\u0E23\u0E32\u0E07\u0E27\u0E31\u0E25!",successMessage:"\u0E23\u0E31\u0E1A\u0E23\u0E32\u0E07\u0E27\u0E31\u0E25\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E41\u0E25\u0E49\u0E27",failedTitle:"\u0E40\u0E0A\u0E47\u0E04\u0E2D\u0E34\u0E19\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27",canceledTitle:"\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E40\u0E0A\u0E47\u0E04\u0E2D\u0E34\u0E19",errors:{userRejected:"\u0E04\u0E38\u0E13\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E01\u0E32\u0E23\u0E40\u0E0A\u0E47\u0E04\u0E2D\u0E34\u0E19",insufficientFunds:"\u0E40\u0E07\u0E34\u0E19\u0E44\u0E21\u0E48\u0E1E\u0E2D\u0E08\u0E48\u0E32\u0E22\u0E04\u0E48\u0E32\u0E41\u0E01\u0E4A\u0E2A",alreadyCheckedIn:"\u0E04\u0E38\u0E13\u0E40\u0E0A\u0E47\u0E04\u0E2D\u0E34\u0E19\u0E27\u0E31\u0E19\u0E19\u0E35\u0E49\u0E44\u0E1B\u0E41\u0E25\u0E49\u0E27 \u0E01\u0E25\u0E31\u0E1A\u0E21\u0E32\u0E43\u0E2B\u0E21\u0E48\u0E1E\u0E23\u0E38\u0E48\u0E07\u0E19\u0E35\u0E49!",network:"\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14\u0E40\u0E04\u0E23\u0E37\u0E2D\u0E02\u0E48\u0E32\u0E22 \u0E42\u0E1B\u0E23\u0E14\u0E25\u0E2D\u0E07\u0E43\u0E2B\u0E21\u0E48\u0E20\u0E32\u0E22\u0E2B\u0E25\u0E31\u0E07"}},store:{title:"\u0E23\u0E49\u0E32\u0E19\u0E04\u0E49\u0E32\u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",hot:"\u0E21\u0E32\u0E41\u0E23\u0E07",buy:"\u0E0B\u0E37\u0E49\u0E2D",cancel:"\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",unit:"\u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",successTitle:"\u0E0A\u0E33\u0E23\u0E30\u0E40\u0E07\u0E34\u0E19\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",successMessage:"\u0E04\u0E38\u0E13\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A {amount} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35!"},payment:{title:"\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E01\u0E32\u0E23\u0E0B\u0E37\u0E49\u0E2D",description:"\u0E43\u0E0A\u0E49 {amount} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E0B\u0E37\u0E49\u0E2D\u0E44\u0E2D\u0E40\u0E17\u0E21\u0E43\u0E19\u0E40\u0E01\u0E21\u0E19\u0E35\u0E49\u0E2B\u0E23\u0E37\u0E2D\u0E44\u0E21\u0E48?",amountLabel:"{amount} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",balance:"\u0E22\u0E2D\u0E14\u0E04\u0E07\u0E40\u0E2B\u0E25\u0E37\u0E2D\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {balance} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",insufficientTitle:"\u0E22\u0E2D\u0E14\u0E04\u0E07\u0E40\u0E2B\u0E25\u0E37\u0E2D\u0E44\u0E21\u0E48\u0E1E\u0E2D",insufficientDesc:"\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48: {gems} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",insufficientMessage:"\u0E22\u0E2D\u0E14\u0E04\u0E07\u0E40\u0E2B\u0E25\u0E37\u0E2D\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19\u0E04\u0E37\u0E2D {balance} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35 \u0E01\u0E32\u0E23\u0E0B\u0E37\u0E49\u0E2D\u0E19\u0E35\u0E49\u0E15\u0E49\u0E2D\u0E07\u0E43\u0E0A\u0E49 {amount} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35",cancel:"\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",confirm:"\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19",recharge:"\u0E40\u0E15\u0E34\u0E21\u0E40\u0E07\u0E34\u0E19",successTitle:"\u0E0A\u0E33\u0E23\u0E30\u0E40\u0E07\u0E34\u0E19\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",successMessage:"\u0E2B\u0E31\u0E01 {amount} \u0E2D\u0E31\u0E0D\u0E21\u0E13\u0E35\u0E41\u0E25\u0E49\u0E27",invalidRequest:"\u0E04\u0E33\u0E02\u0E2D\u0E0A\u0E33\u0E23\u0E30\u0E40\u0E07\u0E34\u0E19\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07"}};var Ce={app:{title:"Playsout Mini Games",description:"Ch\u01A1i game nhanh kh\xF4ng c\u1EA7n \u0111\u0103ng nh\u1EADp."},home:{loggedIn:"\u0110\xE3 \u0111\u0103ng nh\u1EADp",logIn:"\u0110\u0103ng nh\u1EADp",games:"Tr\xF2 ch\u01A1i",bannerAlt:"Tr\xF2 ch\u01A1i Playsout",searchPlaceholder:"T\xECm ki\u1EBFm theo ti\xEAu \u0111\u1EC1 ho\u1EB7c danh m\u1EE5c",noGames:"Kh\xF4ng t\xECm th\u1EA5y tr\xF2 ch\u01A1i"},profile:{title:"H\u1ED3 s\u01A1",settings:"C\xE0i \u0111\u1EB7t",language:"Ng\xF4n ng\u1EEF",recentGames:"Tr\xF2 ch\u01A1i \u0111\xE3 ch\u01A1i g\u1EA7n \u0111\xE2y",noGames:"Ch\u01B0a ch\u01A1i game n\xE0o",guest:"Kh\xE1ch",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"Phi\xEAu l\u01B0u",Simulation:"M\xF4 ph\u1ECFng",Casual:"Ph\u1ED5 th\xF4ng",Arcade:"Arcade",Moba:"Moba",Puzzle:"Gi\u1EA3i \u0111\u1ED1"},auth:{loginSuccess:"\u0110\u0103ng nh\u1EADp th\xE0nh c\xF4ng!",loginTitle:"\u0110\u0103ng nh\u1EADp Playsout",welcome:"Ch\xE0o m\u1EEBng \u0111\u1EBFn v\u1EDBi n\u1EC1n t\u1EA3ng tr\xF2 ch\u01A1i Playsout",prompt:"\u0110\u0103ng nh\u1EADp \u0111\u1EC3 b\u1EAFt \u0111\u1EA7u ch\u01A1i",mustLogin:"B\u1EA1n ph\u1EA3i \u0111\u0103ng nh\u1EADp \u0111\u1EC3 ch\u01A1i",authorizeHint:"Nh\u1EA5p v\xE0o n\xFAt b\xEAn d\u01B0\u1EDBi \u0111\u1EC3 \u1EE7y quy\u1EC1n \u0111\u0103ng nh\u1EADp",authorizing:"\u0110ang \u1EE7y quy\u1EC1n...",authorize:"\u1EE6y quy\u1EC1n \u0111\u0103ng nh\u1EADp",terms:"B\u1EB1ng c\xE1ch \u1EE7y quy\u1EC1n, b\u1EA1n \u0111\u1ED3ng \xFD v\u1EDBi \u0110i\u1EC1u kho\u1EA3n d\u1ECBch v\u1EE5 c\u1EE7a ch\xFAng t\xF4i",signingIn:"\u0110ang \u0111\u0103ng nh\u1EADp",signMessage:"Vui l\xF2ng k\xFD tin nh\u1EAFn trong v\xED c\u1EE7a b\u1EA1n"},game:{loading:"\u0110ang t\u1EA3i",notFound:"Kh\xF4ng t\xECm th\u1EA5y tr\xF2 ch\u01A1i",backHome:"V\u1EC1 trang ch\u1EE7",pageTitleSuffix:"N\u1EC1n t\u1EA3ng tr\xF2 ch\u01A1i",header:{back:"Quay l\u1EA1i",shareAria:"Chia s\u1EBB tr\xF2 ch\u01A1i",toggleMenuAria:"Chuy\u1EC3n \u0111\u1ED5i menu",fallbackTitle:"Tr\xF2 ch\u01A1i"}},menu:{favorite:"Y\xEAu th\xEDch",favorited:"\u0110\xE3 y\xEAu th\xEDch",profile:"H\u1ED3 s\u01A1",login:"\u0110\u0103ng nh\u1EADp",refresh:"L\xE0m m\u1EDBi",loggedIn:"\u0110\xE3 \u0111\u0103ng nh\u1EADp"},share:{title:"Chia s\u1EBB tr\xF2 ch\u01A1i",closeLabel:"\u0110\xF3ng",retry:"Th\u1EED l\u1EA1i",loading:"\u0110ang t\u1EA3i...",imageAlt:"H\xECnh \u1EA3nh chia s\u1EBB tr\xF2 ch\u01A1i",shareUrlLabel:"URL chia s\u1EBB:",copied:"\u0110\xE3 sao ch\xE9p",copy:"Sao ch\xE9p",saveShare:"L\u01B0u & Chia s\u1EBB",hint:"H\xECnh \u1EA3nh bao g\u1ED3m m\xE3 QR li\xEAn k\u1EBFt \u0111\u1EBFn tr\xF2 ch\u01A1i n\xE0y",loadError:"Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c h\xECnh \u1EA3nh chia s\u1EBB",downloadError:"Kh\xF4ng t\u1EA3i xu\u1ED1ng \u0111\u01B0\u1EE3c h\xECnh \u1EA3nh"},checkin:{successTitle:"B\u1EA1n \u0111\xE3 nh\u1EADn ph\u1EA7n th\u01B0\u1EDFng!",successMessage:"Ph\u1EA7n th\u01B0\u1EDFng c\u1EE7a b\u1EA1n \u0111\xE3 \u0111\u01B0\u1EE3c nh\u1EADn.",failedTitle:"\u0110i\u1EC3m danh th\u1EA5t b\u1EA1i",canceledTitle:"\u0110i\u1EC3m danh \u0111\xE3 h\u1EE7y",errors:{userRejected:"B\u1EA1n \u0111\xE3 h\u1EE7y thao t\xE1c \u0111i\u1EC3m danh",insufficientFunds:"Kh\xF4ng \u0111\u1EE7 ti\u1EC1n \u0111\u1EC3 tr\u1EA3 ph\xED Gas",alreadyCheckedIn:"H\xF4m nay b\u1EA1n \u0111\xE3 \u0111i\u1EC3m danh r\u1ED3i. H\xE3y quay l\u1EA1i v\xE0o ng\xE0y mai!",network:"L\u1ED7i m\u1EA1ng. Vui l\xF2ng th\u1EED l\u1EA1i sau"}},store:{title:"C\u1EEDa h\xE0ng \u0110\xE1 qu\xFD",hot:"HOT",buy:"MUA",cancel:"H\u1EE7y",unit:"\u0110\xE1 qu\xFD",successTitle:"Thanh to\xE1n th\xE0nh c\xF4ng",successMessage:"B\u1EA1n \u0111\xE3 nh\u1EADn \u0111\u01B0\u1EE3c {amount} \u0111\xE1 qu\xFD!"},payment:{title:"X\xE1c nh\u1EADn mua",description:"D\xF9ng {amount} \u0111\xE1 qu\xFD \u0111\u1EC3 mua v\u1EADt ph\u1EA9m trong game n\xE0y?",amountLabel:"{amount} \u0111\xE1 qu\xFD",balance:"S\u1ED1 d\u01B0 hi\u1EC7n t\u1EA1i: {balance} \u0111\xE1 qu\xFD",insufficientTitle:"S\u1ED1 d\u01B0 kh\xF4ng \u0111\u1EE7",insufficientDesc:"Hi\u1EC7n c\xF3: {gems} \u0110\xE1 qu\xFD",insufficientMessage:"S\u1ED1 d\u01B0 hi\u1EC7n t\u1EA1i l\xE0 {balance} \u0111\xE1 qu\xFD. Giao d\u1ECBch n\xE0y c\u1EA7n {amount} \u0111\xE1 qu\xFD.",cancel:"H\u1EE7y",confirm:"X\xE1c nh\u1EADn",recharge:"N\u1EA1p ti\u1EC1n",successTitle:"Thanh to\xE1n th\xE0nh c\xF4ng",successMessage:"\u0110\xE3 tr\u1EEB {amount} \u0111\xE1 qu\xFD.",invalidRequest:"Y\xEAu c\u1EA7u thanh to\xE1n kh\xF4ng h\u1EE3p l\u1EC7."}};var Re={app:{title:"Playsout Mini Games",description:"Mainkan game cepat tanpa login."},home:{loggedIn:"Sudah login",logIn:"Login",games:"Game",bannerAlt:"Game Playsout",searchPlaceholder:"Cari berdasarkan judul atau kategori",noGames:"Game tidak ditemukan"},profile:{title:"Profil",settings:"Pengaturan",language:"Bahasa",recentGames:"Game yang Baru Dimainkan",noGames:"Belum ada game yang dimainkan",guest:"Tamu",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"Petualangan",Simulation:"Simulasi",Casual:"Kasual",Arcade:"Arcade",Moba:"Moba",Puzzle:"Teka-teki"},auth:{loginSuccess:"Login berhasil!",loginTitle:"Login Playsout",welcome:"Selamat datang di platform game Playsout",prompt:"Login untuk mulai bermain",mustLogin:"Anda harus login untuk bermain",authorizeHint:"Klik tombol di bawah untuk mengotorisasi login",authorizing:"Mengotorisasi...",authorize:"Otorisasi login",terms:"Dengan mengotorisasi, Anda menyetujui Ketentuan Layanan kami",signingIn:"Masuk...",signMessage:"Silakan tanda tangani pesan di dompet Anda"},game:{loading:"Memuat",notFound:"Game tidak ditemukan",backHome:"Kembali ke beranda",pageTitleSuffix:"Platform Game",header:{back:"Kembali",shareAria:"Bagikan game",toggleMenuAria:"Alihkan menu",fallbackTitle:"Game"}},menu:{favorite:"Favorit",favorited:"Difavoritkan",profile:"Profil",login:"Login",refresh:"Segarkan",loggedIn:"Sudah login"},share:{title:"Bagikan Game",closeLabel:"Tutup",retry:"Coba lagi",loading:"Memuat...",imageAlt:"Gambar berbagi game",shareUrlLabel:"URL Berbagi:",copied:"Disalin",copy:"Salin",saveShare:"Simpan & Bagikan",hint:"Gambar termasuk kode QR yang menautkan ke game ini",loadError:"Gagal memuat gambar berbagi",downloadError:"Gagal mengunduh gambar"},checkin:{successTitle:"Anda mendapat hadiah!",successMessage:"Hadiah Anda telah diklaim.",failedTitle:"Check-in gagal",canceledTitle:"Check-in dibatalkan",errors:{userRejected:"Anda membatalkan operasi check-in",insufficientFunds:"Dana tidak cukup untuk membayar biaya Gas",alreadyCheckedIn:"Anda sudah check-in hari ini. Kembali lagi besok!",network:"Kesalahan jaringan. Silakan coba lagi nanti"}},store:{title:"Toko Permata",hot:"HOT",buy:"BELI",cancel:"Batal",unit:"Permata",successTitle:"Pembayaran Berhasil",successMessage:"Anda menerima {amount} permata!"},payment:{title:"Konfirmasi Pembelian",description:"Gunakan {amount} permata untuk membeli item game ini?",amountLabel:"{amount} permata",balance:"Saldo saat ini: {balance} permata",insufficientTitle:"Saldo Tidak Cukup",insufficientDesc:"Tersedia: {gems} Permata",insufficientMessage:"Saldo saat ini {balance} permata. Pembelian ini membutuhkan {amount} permata.",cancel:"Batal",confirm:"Konfirmasi",recharge:"Isi Ulang",successTitle:"Pembayaran Berhasil",successMessage:"{amount} permata telah dikurangi.",invalidRequest:"Permintaan pembayaran tidak valid."}};var Me={app:{title:"Permainan Mini Playsout",description:"Main permainan pantas tanpa log masuk."},home:{loggedIn:"Log masuk",logIn:"Log masuk",games:"Permainan",bannerAlt:"Permainan Playsout",searchPlaceholder:"Cari mengikut tajuk atau kategori",noGames:"Tiada permainan dijumpai"},profile:{title:"Profil",settings:"Tetapan",language:"Bahasa",recentGames:"Permainan Baru Dimainkan",noGames:"Belum ada permainan dimainkan",guest:"Pelawat",languages:{en:"English",zh:"\u4E2D\u6587",ja:"\u65E5\u672C\u8A9E",ko:"\uD55C\uAD6D\uC5B4",th:"\u0E44\u0E17\u0E22",vi:"Ti\u1EBFng Vi\u1EC7t",id:"Bahasa Indonesia",ms:"Bahasa Melayu",es:"Espa\xF1ol"}},categories:{Adventure:"Pengembaraan",Simulation:"Simulasi",Casual:"Santai",Arcade:"Arked",Moba:"Moba",Puzzle:"Teka-teki"},auth:{loginSuccess:"Log masuk berjaya!",loginTitle:"Log masuk Playsout",welcome:"Selamat datang ke platform permainan Playsout",prompt:"Log masuk untuk mula bermain",mustLogin:"Anda mesti log masuk untuk bermain",authorizeHint:"Klik butang di bawah untuk membenarkan log masuk",authorizing:"Membenarkan...",authorize:"Benarkan log masuk",terms:"Dengan membenarkan, anda bersetuju dengan Syarat Perkhidmatan kami",signingIn:"Sedang log masuk",signMessage:"Sila tandatangan mesej dalam dompet anda"},game:{loading:"Memuatkan",notFound:"Permainan tidak dijumpai",backHome:"Kembali ke laman utama",pageTitleSuffix:"Platform Permainan",header:{back:"Kembali",shareAria:"Kongsi permainan",toggleMenuAria:"Togol menu",fallbackTitle:"Permainan"}},menu:{favorite:"Kegemaran",favorited:"Dikegemarankan",profile:"Profil",login:"Log masuk",refresh:"Muat semula",loggedIn:"Log masuk"},share:{title:"Kongsi Permainan",closeLabel:"Tutup",retry:"Cuba lagi",loading:"Memuatkan...",imageAlt:"Imej kongsi permainan",shareUrlLabel:"URL Kongsi:",copied:"Disalin",copy:"Salin",saveShare:"Simpan & Kongsi",hint:"Imej termasuk kod QR yang memaut ke permainan ini",loadError:"Gagal memuatkan imej kongsi",downloadError:"Gagal memuat turun imej"},checkin:{successTitle:"Anda mendapat ganjaran!",successMessage:"Ganjaran anda telah dituntut.",failedTitle:"Daftar masuk gagal",canceledTitle:"Daftar masuk dibatalkan",errors:{userRejected:"Anda membatalkan operasi daftar masuk",insufficientFunds:"Dana tidak mencukupi untuk membayar yuran Gas",alreadyCheckedIn:"Anda sudah daftar masuk hari ini. Kembali lagi esok!",network:"Ralat rangkaian. Sila cuba lagi kemudian"}},store:{title:"Kedai Permata",hot:"HOT",buy:"BELI",cancel:"Batal",unit:"Permata",successTitle:"Pembayaran Berjaya",successMessage:"Anda menerima {amount} permata!"},payment:{title:"Sahkan Pembelian",description:"Gunakan {amount} permata untuk membeli item permainan ini?",amountLabel:"{amount} permata",balance:"Baki semasa: {balance} permata",insufficientTitle:"Baki Tidak Mencukupi",insufficientDesc:"Tersedia: {gems} Permata",insufficientMessage:"Baki semasa ialah {balance} permata. Pembelian ini memerlukan {amount} permata.",cancel:"Batal",confirm:"Sahkan",recharge:"Tambah Nilai",successTitle:"Pembayaran Berjaya",successMessage:"{amount} permata telah ditolak.",invalidRequest:"Permintaan pembayaran tidak sah."}};var K=r=>{if(typeof window>"u")return r;let t=l(r);return Se(t)},ht="https://games.playsout.com/resources/icon/fonts",F=r=>{if(typeof window>"u")return r;let t=r.replace(/^\.\//,"");return`${ht}/${t}`},C={en:Ee,zh:Te,ja:Ae,ko:Pe,th:Le,vi:Ce,id:Re,ms:Me};function ne(r,t){let e=t.split("."),a=r;for(let o of e)if(a&&typeof a=="object"&&o in a)a=a[o];else return t;return typeof a=="string"?a:t}function _e(r,t={}){return r.replace(/\{(\w+)\}/g,(e,a)=>String(t[a]??`{${a}}`))}var Oe=`
2
- :root {
3
- --playsout-primary: #6366f1;
4
- --playsout-bg: #0f1419;
5
- --playsout-bg-card: #1e2a3a;
6
- --playsout-text: #f8fafc;
7
- --playsout-text-muted: #94a3b8;
8
- --playsout-border: #334155;
9
- --playsout-radius: 8px;
10
- --playsout-padding: 12px;
11
- }
12
-
13
- /* Adelle Sans \u5B57\u4F53 */
14
- @font-face {
15
- font-family: "Adelle Sans";
16
- src: url('${F("./AdelleSans-Regular.woff2")}') format('woff2'),
17
- url('${F("./AdelleSans-Regular.woff")}') format('woff');
18
- font-style: normal;
19
- font-display: swap;
20
- font-weight: 300;
21
- }
22
- @font-face {
23
- font-family: "Adelle Sans";
24
- src: url('${F("./AdelleSans-Semibold.woff2")}') format('woff2'),
25
- url('${F("./AdelleSans-Semibold.woff")}') format('woff');
26
- font-style: normal;
27
- font-display: swap;
28
- font-weight: 600;
29
- }
30
-
31
- /* \u5168\u5C40\u5B57\u4F53 + \u80CC\u666F */
32
- * {
33
- box-sizing: border-box;
34
- margin: 0;
35
- padding: 0;
36
- font-family: "Adelle Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
37
- }
38
-
39
- /* \u684C\u9762\u7AEF\u5916\u5C42\u5BB9\u5668\uFF1A\u5C45\u4E2D + \u6E10\u53D8\u80CC\u666F */
40
- @media (min-width: 769px) {
41
- body {
42
- background: linear-gradient(135deg, #1e3a8a 0%, #1e1b4b 50%, #0f1419 100%);
43
- background-attachment: fixed;
44
- }
45
- }
46
-
47
- /* \u79FB\u52A8\u7AEF\u6EDA\u52A8\u5BB9\u5668 */
48
- .playsout-scroll-container {
49
- min-height: 100vh;
50
- overflow-y: auto;
51
- -webkit-overflow-scrolling: touch;
52
- scrollbar-width: none;
53
- -ms-overflow-style: none;
54
- }
55
- .playsout-scroll-container::-webkit-scrollbar {
56
- display: none;
57
- }
58
-
59
- /* mobile-container: \u4E0E demo \u5B8C\u5168\u4E00\u81F4 */
60
- .mobile-container {
61
- max-width: 414px; /* iPhone 13 Pro Max \u5BBD\u5EA6\uFF0C\u4E0E demo \u4E00\u81F4 */
62
- margin: 0 auto;
63
- background-color: #0f1419;
64
- min-height: 100vh;
65
- position: relative;
66
- box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
67
- border-radius: 0.25rem; /* rounded-md */
68
- }
69
-
70
- @media (max-width: 768px) {
71
- .mobile-container {
72
- max-width: none;
73
- margin: 0;
74
- box-shadow: none;
75
- border-radius: 0;
76
- }
77
- }
78
-
79
- .playsout-widget {
80
- background: var(--playsout-bg);
81
- color: var(--playsout-text);
82
- min-height: 100vh;
83
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
84
- }
85
-
86
- /* Header */
87
- .widget-header {
88
- display: flex;
89
- align-items: center;
90
- justify-content: space-between;
91
- padding: 1rem 1rem; /* py-4 px-4 */
92
- background: var(--playsout-bg);
93
- position: sticky;
94
- top: 0;
95
- z-index: 100;
96
- }
97
-
98
- .widget-logo {
99
- display: flex;
100
- align-items: center;
101
- gap: 4px;
102
- }
103
-
104
- .widget-logo img {
105
- width: 40px;
106
- height: 32px;
107
- object-fit: contain;
108
- }
109
-
110
- .widget-user {
111
- display: flex;
112
- align-items: center;
113
- gap: 0.75rem; /* gap-3 */
114
- }
115
-
116
- /* Gems Button: demo \u98CE\u683C */
117
- .widget-gems-btn {
118
- display: flex;
119
- align-items: center;
120
- gap: 0.375rem; /* gap-1.5 */
121
- padding: 0.375rem 0.75rem; /* py-1.5 px-3 */
122
- border-radius: 9999px; /* rounded-full */
123
- background: #1a1a1a;
124
- border: 1px solid #2a2a2a;
125
- color: #94a3b8;
126
- cursor: pointer;
127
- transition: background 0.15s;
128
- }
129
- .widget-gems-btn:hover {
130
- background: #2a3b50;
131
- }
132
- .widget-gems-amount {
133
- font-size: 0.875rem; /* text-sm */
134
- font-weight: 700;
135
- color: white;
136
- }
137
- .widget-gems-icon {
138
- color: #a855f7; /* \u7D2B\u8272 */
139
- width: 1rem;
140
- height: 1rem;
141
- fill: currentColor;
142
- stroke: currentColor;
143
- }
144
-
145
- /* Profile Button: demo \u98CE\u683C */
146
- .widget-profile-btn {
147
- display: flex;
148
- align-items: center;
149
- justify-content: center;
150
- width: 2.5rem; /* w-10 */
151
- height: 2.5rem; /* h-10 */
152
- border-radius: 50%;
153
- background: #1e2a3a;
154
- cursor: pointer;
155
- transition: background 0.15s;
156
- border: none;
157
- }
158
- .widget-profile-btn:hover {
159
- background: #2a3b50;
160
- }
161
- .widget-profile-btn svg {
162
- width: 1.25rem; /* w-5 h-5 */
163
- height: 1.25rem;
164
- color: #94a3b8;
165
- }
166
-
167
- /* Banner */
168
- .widget-banner {
169
- padding: 0 1rem 1.5rem; /* px-4 pb-6\uFF0C\u4E0E demo \u4E00\u81F4 */
170
- }
171
-
172
- .banner-image {
173
- width: 100%;
174
- height: auto;
175
- aspect-ratio: 750 / 300;
176
- object-fit: cover;
177
- border-radius: 1rem; /* rounded-2xl */
178
- border: 1px solid #1e2a3a; /* border-game-card */
179
- background: #1e2a3a;
180
- display: block;
181
- user-select: none;
182
- -webkit-user-drag: none;
183
- }
184
-
185
- /* Search */
186
- .widget-search {
187
- padding: 0 1rem 1.5rem; /* px-4 pb-6 */
188
- position: relative;
189
- }
190
-
191
- .search-wrapper {
192
- position: relative;
193
- display: flex;
194
- align-items: center;
195
- }
196
-
197
- .search-icon {
198
- position: absolute;
199
- left: 14px;
200
- top: 50%;
201
- transform: translateY(-50%);
202
- color: #94a3b8;
203
- pointer-events: none;
204
- display: flex;
205
- align-items: center;
206
- }
207
-
208
- .search-input {
209
- width: 100%;
210
- background: #1a1a1a;
211
- color: white;
212
- border: 1px solid #2a2a2a;
213
- border-radius: 1rem; /* rounded-2xl */
214
- padding: 0.875rem 1rem 0.875rem 2.75rem; /* py-3.5 pl-11 */
215
- font-size: 0.875rem;
216
- outline: none;
217
- transition: border-color 0.2s;
218
- -webkit-appearance: none;
219
- }
220
-
221
- .search-input:focus {
222
- border-color: #06b6d4; /* focus:border-cyan-500 */
223
- }
224
-
225
- .search-input::placeholder {
226
- color: #6b7280; /* placeholder-gray-500 */
227
- }
228
-
229
- /* \u53F3\u4FA7 Search \u6309\u94AE\uFF08\u4E0E demo \u4E00\u81F4\uFF09 */
230
- .search-btn {
231
- position: absolute;
232
- right: 0.5rem; /* right-2 */
233
- top: 50%;
234
- transform: translateY(-50%);
235
- width: 2.25rem; /* w-9 */
236
- height: 2.25rem; /* h-9 */
237
- border-radius: 0.75rem; /* rounded-xl */
238
- background: #2a3b50;
239
- border: none;
240
- cursor: pointer;
241
- display: flex;
242
- align-items: center;
243
- justify-content: center;
244
- color: #22d3ee; /* text-cyan-400 */
245
- transition: background 0.15s;
246
- }
247
- .search-btn:hover {
248
- background: #374151;
249
- }
250
-
251
- /* Categories */
252
- .widget-categories {
253
- padding: 0 1rem 2rem; /* px-4 mb-8 */
254
- }
255
-
256
- .categories-wrapper {
257
- display: flex;
258
- flex-wrap: wrap;
259
- gap: 0.75rem; /* gap-3 */
260
- }
261
-
262
- .category-btn {
263
- flex-shrink: 0;
264
- display: flex;
265
- align-items: center;
266
- gap: 0.5rem; /* gap-2 */
267
- padding: 0.375rem 0.75rem; /* py-1.5 px-3 */
268
- border-radius: 9999px; /* rounded-full */
269
- border: 1px solid transparent;
270
- font-size: 0.875rem; /* text-sm */
271
- font-weight: 500;
272
- cursor: pointer;
273
- transition: all 0.15s;
274
- background: #1E232F;
275
- white-space: nowrap;
276
- }
277
-
278
- .category-btn:hover {
279
- border-color: rgba(255, 255, 255, 0.1);
280
- }
281
-
282
- .category-btn.active {
283
- background: #1E232F;
284
- border-color: rgba(6, 182, 212, 0.5); /* border-cyan-500/50 */
285
- }
286
-
287
- .category-btn.active .category-label {
288
- color: white;
289
- }
290
-
291
- .category-icon {
292
- width: 1rem; /* w-4 */
293
- height: 1rem; /* h-4 */
294
- display: flex;
295
- align-items: center;
296
- justify-content: center;
297
- }
298
-
299
- .category-label {
300
- color: #9ca3af; /* text-gray-400 */
301
- transition: color 0.15s;
302
- }
303
-
304
- /* Games Section */
305
- .widget-games {
306
- padding: 0 1rem 1rem; /* px-4 pb-4 */
307
- }
308
-
309
- .section-title {
310
- font-size: 1rem; /* text-base \u2248 16px */
311
- font-weight: 600;
312
- margin-bottom: 1rem; /* mb-4 */
313
- color: #94a3b8; /* text-game-text */
314
- }
315
-
316
- .games-grid {
317
- display: grid;
318
- grid-template-columns: repeat(2, 1fr);
319
- gap: 0.5rem; /* gap-2\uFF088px\uFF09\uFF0C\u4E0E demo \u4E00\u81F4 */
320
- }
321
-
322
- /* Game Card: \u4E0E demo globals.css \u4E00\u81F4 */
323
- .game-card {
324
- background: #1e2a3a; /* bg-game-card */
325
- border-radius: 0.75rem; /* rounded-xl */
326
- overflow: hidden;
327
- cursor: pointer;
328
- user-select: none;
329
- -webkit-user-select: none;
330
- transition: transform 0.2s;
331
- display: flex;
332
- flex-direction: column;
333
- }
334
-
335
- .game-card:hover {
336
- transform: translateY(-2px); /* -translate-y-0.5 \u2248 2px */
337
- }
338
-
339
- .game-image-wrapper {
340
- position: relative;
341
- width: 100%;
342
- aspect-ratio: 1; /* 1:1 \u65B9\u5F62\uFF0C\u4E0E demo \u4E00\u81F4 */
343
- flex-shrink: 0;
344
- overflow: hidden;
345
- }
346
-
347
- .game-image {
348
- width: 100%;
349
- height: 100%;
350
- object-fit: cover;
351
- background: #1e2a3a;
352
- user-select: none;
353
- -webkit-user-drag: none;
354
- }
355
-
356
- /* NEW/HOT \u5FBD\u6807\uFF1A\u4E0E\u6807\u9898\u540C\u4E00\u884C */
357
- .title-row {
358
- display: flex;
359
- align-items: center;
360
- gap: 0.5rem; /* gap-2 */
361
- height: 1rem; /* height: 16px */
362
- min-height: 1rem;
363
- overflow: visible;
364
- }
365
-
366
- .game-tag {
367
- font-size: 0.5rem; /* text-[8px] */
368
- font-weight: 700;
369
- padding: 2px 3px;
370
- border-radius: 3px;
371
- flex-shrink: 0;
372
- text-transform: uppercase;
373
- line-height: 1;
374
- }
375
-
376
- .game-tag.new {
377
- background: #dc2626; /* \u7EA2\u8272\uFF0C\u4E0E demo \u4E00\u81F4 */
378
- color: white;
379
- }
380
-
381
- .game-tag.hot {
382
- background: #f59e0b; /* \u6A59\u8272\uFF0C\u4E0E demo \u4E00\u81F4 */
383
- color: white;
384
- }
385
-
386
- .game-info {
387
- padding: 6px;
388
- flex-shrink: 0;
389
- display: flex;
390
- flex-direction: column;
391
- background-color: rgba(30, 42, 58, 0.95); /* \u4E0E demo \u5B8C\u5168\u4E00\u81F4 */
392
- }
393
-
394
- .game-title {
395
- font-size: 0.6875rem; /* text-[11px] */
396
- font-weight: 600;
397
- color: white;
398
- margin: 0;
399
- white-space: nowrap;
400
- overflow: hidden;
401
- text-overflow: ellipsis;
402
- line-height: 1rem; /* line-height: 16px */
403
- user-select: text;
404
- -webkit-user-select: text;
405
- }
406
-
407
- .divider {
408
- height: 1px;
409
- background-color: #2a3b50; /* \u4E0E demo divider \u4E00\u81F4 */
410
- margin: 4px 0;
411
- }
412
-
413
- .game-category {
414
- font-size: 0.5625rem; /* text-[9px] */
415
- color: #64748b;
416
- margin: 0;
417
- line-height: 0.75rem; /* line-height: 12px */
418
- text-align: left;
419
- user-select: text;
420
- -webkit-user-select: text;
421
- }
422
-
423
- /* Empty State */
424
- .empty-state {
425
- text-align: center;
426
- padding: 48px 16px;
427
- color: var(--playsout-text-muted);
428
- }
429
-
430
- .empty-state-icon {
431
- font-size: 48px;
432
- margin-bottom: 16px;
433
- }
434
-
435
- /* Loading */
436
- .loading {
437
- display: flex;
438
- align-items: center;
439
- justify-content: center;
440
- min-height: 200px;
441
- color: var(--playsout-text-muted);
442
- }
443
-
444
- .loading-spinner {
445
- width: 32px;
446
- height: 32px;
447
- border: 3px solid var(--playsout-border);
448
- border-top-color: var(--playsout-primary);
449
- border-radius: 50%;
450
- animation: spin 1s linear infinite;
451
- }
452
-
453
- @keyframes spin {
454
- to {
455
- transform: rotate(360deg);
456
- }
457
- }
458
-
459
- /* No Results */
460
- .no-results {
461
- text-align: center;
462
- padding: 48px 16px;
463
- color: var(--playsout-text-muted);
464
- }
465
-
466
- /* ========== Store Modal ========== */
467
- .store-modal-overlay {
468
- position: fixed;
469
- inset: 0;
470
- z-index: 1000;
471
- background: rgba(0, 0, 0, 0.6);
472
- backdrop-filter: blur(4px);
473
- -webkit-backdrop-filter: blur(4px);
474
- display: flex;
475
- align-items: flex-end;
476
- justify-content: center;
477
- animation: modalFadeIn 0.2s ease-out;
478
- }
479
-
480
- /* ========== Profile Modal ========== */
481
- .profile-modal-overlay {
482
- position: fixed;
483
- inset: 0;
484
- z-index: 1000;
485
- background: rgba(0, 0, 0, 0.6);
486
- backdrop-filter: blur(4px);
487
- -webkit-backdrop-filter: blur(4px);
488
- display: flex;
489
- align-items: flex-end;
490
- justify-content: center;
491
- animation: modalFadeIn 0.2s ease-out;
492
- }
493
-
494
- .profile-modal {
495
- width: 100%;
496
- max-width: 28rem;
497
- background: #111827;
498
- border-top: 1px solid #374151;
499
- border-radius: 1.5rem 1.5rem 0 0;
500
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
501
- display: flex;
502
- flex-direction: column;
503
- max-height: 90vh;
504
- animation: modalSlideUp 0.3s ease-out;
505
- }
506
-
507
- @media (min-width: 640px) {
508
- .profile-modal {
509
- border-radius: 1.5rem;
510
- margin: 1rem;
511
- }
512
- }
513
-
514
- .profile-modal-header {
515
- display: flex;
516
- align-items: center;
517
- justify-content: space-between;
518
- padding: 0.75rem 1rem;
519
- border-bottom: 1px solid #374151;
520
- }
521
-
522
- .profile-modal-title {
523
- font-size: 1.125rem;
524
- font-weight: 700;
525
- color: white;
526
- }
527
-
528
- .profile-modal-close {
529
- background: none;
530
- border: none;
531
- color: #9ca3af;
532
- font-size: 1.25rem;
533
- cursor: pointer;
534
- padding: 0.25rem;
535
- line-height: 1;
536
- }
537
- .profile-modal-close:hover {
538
- color: white;
539
- }
540
-
541
- .profile-modal-content {
542
- flex: 1;
543
- overflow-y: auto;
544
- padding: 1rem;
545
- display: flex;
546
- flex-direction: column;
547
- gap: 1.5rem;
548
- }
549
-
550
- .profile-section {
551
- display: flex;
552
- flex-direction: column;
553
- gap: 0.75rem;
554
- }
555
-
556
- .profile-section-title {
557
- font-size: 1rem;
558
- font-weight: 600;
559
- color: #e5e7eb;
560
- border-left: 3px solid #06b6d4;
561
- padding-left: 0.75rem;
562
- }
563
-
564
- /* \u7528\u6237\u4FE1\u606F\u5FBD\u7AE0\uFF08\u7B80\u6D01\u98CE\u683C\uFF09 */
565
- .profile-user-badge {
566
- display: inline-flex;
567
- align-items: center;
568
- gap: 0.5rem;
569
- padding: 0.625rem 1rem;
570
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(139, 92, 246, 0.15));
571
- border: 1px solid rgba(99, 102, 241, 0.3);
572
- border-radius: 2rem;
573
- margin-bottom: 1.25rem;
574
- }
575
-
576
- .profile-user-icon {
577
- width: 1.25rem;
578
- height: 1.25rem;
579
- color: #a5b4fc;
580
- flex-shrink: 0;
581
- }
582
-
583
- .profile-username-text {
584
- font-size: 0.9375rem;
585
- font-weight: 600;
586
- color: #e0e7ff;
587
- }
588
-
589
- .profile-settings {
590
- background: #1a1a1a;
591
- border-radius: 0.75rem;
592
- border: 1px solid #2a2a2a;
593
- overflow: hidden;
594
- }
595
-
596
- .profile-setting-item {
597
- display: flex;
598
- align-items: center;
599
- justify-content: space-between;
600
- padding: 1rem;
601
- cursor: pointer;
602
- transition: background 0.15s;
603
- }
604
-
605
- .profile-setting-item:hover {
606
- background: #252525;
607
- }
608
-
609
- .profile-setting-label {
610
- color: white;
611
- font-weight: 500;
612
- font-size: 0.875rem;
613
- }
614
-
615
- .profile-setting-value {
616
- display: flex;
617
- align-items: center;
618
- gap: 0.5rem;
619
- color: #9ca3af;
620
- font-size: 0.875rem;
621
- }
622
-
623
- .profile-language-select {
624
- background: transparent;
625
- border: none;
626
- color: #9ca3af;
627
- font-size: 0.875rem;
628
- cursor: pointer;
629
- padding: 0.25rem;
630
- }
631
-
632
- .profile-language-select option {
633
- background: #1a1a1a;
634
- color: white;
635
- }
636
-
637
- /* ========== Language Select Modal ========== */
638
- .language-modal-overlay {
639
- position: fixed;
640
- inset: 0;
641
- z-index: 1001;
642
- background: rgba(0, 0, 0, 0.5);
643
- backdrop-filter: blur(4px);
644
- -webkit-backdrop-filter: blur(4px);
645
- display: flex;
646
- align-items: flex-end;
647
- justify-content: center;
648
- animation: modalFadeIn 0.2s ease-out;
649
- }
650
-
651
- .language-modal {
652
- width: 100%;
653
- max-width: 28rem;
654
- background: #1a1a1a;
655
- border-radius: 1.5rem 1.5rem 0 0;
656
- border: 1px solid #2a2a2a;
657
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
658
- max-height: 80vh;
659
- display: flex;
660
- flex-direction: column;
661
- animation: modalSlideUp 0.3s ease-out;
662
- }
663
-
664
- @media (min-width: 640px) {
665
- .language-modal {
666
- border-radius: 1.5rem;
667
- margin: 1rem;
668
- }
669
- }
670
-
671
- .language-modal-header {
672
- display: flex;
673
- align-items: center;
674
- justify-content: space-between;
675
- padding: 1rem;
676
- border-bottom: 1px solid #2a2a2a;
677
- }
678
-
679
- .language-modal-title {
680
- font-size: 1rem;
681
- font-weight: 700;
682
- color: white;
683
- }
684
-
685
- .language-modal-close {
686
- background: none;
687
- border: none;
688
- color: #9ca3af;
689
- font-size: 1.25rem;
690
- cursor: pointer;
691
- padding: 0.25rem;
692
- line-height: 1;
693
- }
694
- .language-modal-close:hover {
695
- color: white;
696
- }
697
-
698
- .language-modal-list {
699
- overflow-y: auto;
700
- padding: 0.5rem;
701
- max-height: 60vh;
702
- }
703
-
704
- .language-option {
705
- width: 100%;
706
- display: flex;
707
- align-items: center;
708
- justify-content: space-between;
709
- padding: 1rem;
710
- background: transparent;
711
- border: none;
712
- border-radius: 0.75rem;
713
- cursor: pointer;
714
- transition: all 0.15s;
715
- color: #d1d5db;
716
- }
717
-
718
- .language-option:hover {
719
- background: #252525;
720
- }
721
-
722
- .language-option.active {
723
- background: rgba(6, 182, 212, 0.1);
724
- color: #22d3ee;
725
- border: 1px solid rgba(6, 182, 212, 0.5);
726
- }
727
-
728
- .language-option-label {
729
- font-size: 1rem;
730
- font-weight: 500;
731
- }
732
-
733
- .language-option-check {
734
- font-size: 1rem;
735
- }
736
-
737
- .store-modal {
738
- width: 100%;
739
- max-width: 28rem; /* max-w-sm */
740
- background: #111827; /* gray-900 */
741
- border-top: 1px solid #374151;
742
- border-radius: 1.5rem 1.5rem 0 0; /* rounded-t-3xl */
743
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
744
- display: flex;
745
- flex-direction: column;
746
- max-height: 90vh;
747
- animation: modalSlideUp 0.3s ease-out;
748
- }
749
-
750
- @media (min-width: 640px) {
751
- .store-modal {
752
- border-radius: 1.5rem;
753
- margin: 1rem;
754
- }
755
- }
756
-
757
- .store-modal-header {
758
- display: flex;
759
- align-items: center;
760
- justify-content: center;
761
- padding: 0.75rem;
762
- border-bottom: 1px solid #374151;
763
- }
764
-
765
- .store-modal-title {
766
- font-size: 1.125rem; /* text-lg */
767
- font-weight: 700;
768
- color: white;
769
- letter-spacing: 0.025em;
770
- }
771
-
772
- .store-modal-content {
773
- flex: 1;
774
- overflow-y: auto;
775
- padding: 0.75rem;
776
- display: flex;
777
- flex-direction: column;
778
- gap: 0.5rem;
779
- }
780
-
781
- .store-pack {
782
- display: flex;
783
- align-items: center;
784
- justify-content: space-between;
785
- padding: 0.75rem;
786
- background: #1f2937; /* gray-800 */
787
- border-radius: 0.75rem;
788
- border: 1px solid #374151;
789
- transition: background 0.15s;
790
- position: relative;
791
- }
792
- .store-pack:hover {
793
- background: #1a2233;
794
- }
795
-
796
- .store-pack-hot {
797
- position: absolute;
798
- top: 0;
799
- right: 0;
800
- background: linear-gradient(135deg, #ef4444, #ec4899); /* red-500 to pink-500 */
801
- color: white;
802
- font-size: 0.625rem;
803
- font-weight: 700;
804
- padding: 2px 8px;
805
- border-radius: 0 0.75rem 0 0.5rem;
806
- text-transform: uppercase;
807
- letter-spacing: 0.05em;
808
- }
809
-
810
- .store-pack-left {
811
- display: flex;
812
- align-items: center;
813
- gap: 0.75rem;
814
- }
815
-
816
- .store-pack-icon {
817
- width: 2.5rem;
818
- height: 2.5rem;
819
- border-radius: 50%;
820
- background: #374151;
821
- display: flex;
822
- align-items: center;
823
- justify-content: center;
824
- border: 1px solid #4b5563;
825
- flex-shrink: 0;
826
- }
827
-
828
- .store-pack-icon svg {
829
- color: #9333ea; /* purple-600 */
830
- width: 1.25rem;
831
- height: 1.25rem;
832
- fill: rgba(147, 51, 234, 0.1);
833
- stroke: currentColor;
834
- }
835
-
836
- .store-pack-info {
837
- display: flex;
838
- flex-direction: column;
839
- }
840
-
841
- .store-pack-amount {
842
- font-size: 1rem;
843
- font-weight: 700;
844
- color: white;
845
- }
846
-
847
- .store-pack-amount span {
848
- font-size: 0.75rem;
849
- font-weight: 400;
850
- color: #a78bfa; /* purple-400 */
851
- }
852
-
853
- .store-pack-price {
854
- font-size: 0.75rem;
855
- color: #9ca3af; /* gray-400 */
856
- }
857
-
858
- .store-buy-btn {
859
- background: linear-gradient(135deg, #0891b2, #2563eb); /* cyan-600 to blue-600 */
860
- color: white;
861
- font-size: 0.75rem;
862
- font-weight: 700;
863
- padding: 0.375rem 1rem;
864
- border-radius: 9999px;
865
- border: none;
866
- cursor: pointer;
867
- transition: all 0.15s;
868
- box-shadow: 0 10px 15px -3px rgba(6, 182, 212, 0.2);
869
- }
870
- .store-buy-btn:hover {
871
- background: linear-gradient(135deg, #22d3ee, #3b82f6); /* cyan-500 to blue-500 */
872
- transform: scale(0.97);
873
- }
874
-
875
- .store-modal-footer {
876
- padding: 0.75rem;
877
- padding-bottom: 1.5rem;
878
- border-top: 1px solid #374151;
879
- border-radius: 0 0 1.5rem 1.5rem;
880
- background: #111827;
881
- }
882
-
883
- @media (min-width: 640px) {
884
- .store-modal-footer {
885
- padding-bottom: 0.75rem;
886
- border-radius: 0 0 1.5rem 1.5rem;
887
- }
888
- }
889
-
890
- .store-cancel-btn {
891
- width: 100%;
892
- text-align: center;
893
- font-size: 1rem;
894
- font-weight: 500;
895
- color: #9ca3af;
896
- background: none;
897
- border: none;
898
- cursor: pointer;
899
- transition: color 0.15s;
900
- padding: 0.25rem;
901
- }
902
- .store-cancel-btn:hover {
903
- color: #e5e7eb;
904
- }
905
-
906
- /* ========== Payment Modal ========== */
907
- .payment-modal-overlay {
908
- position: fixed;
909
- inset: 0;
910
- z-index: 1500;
911
- background: rgba(0, 0, 0, 0.6);
912
- backdrop-filter: blur(4px);
913
- -webkit-backdrop-filter: blur(4px);
914
- display: flex;
915
- align-items: flex-end;
916
- justify-content: center;
917
- animation: modalFadeIn 0.2s ease-out;
918
- }
919
-
920
- .payment-modal {
921
- width: 100%;
922
- max-width: 28rem;
923
- background: #ffffff;
924
- border-top: 1px solid #f3f4f6;
925
- border-radius: 1.5rem 1.5rem 0 0;
926
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
927
- overflow: hidden;
928
- animation: modalSlideUp 0.3s ease-out;
929
- }
930
-
931
- @media (min-width: 640px) {
932
- .payment-modal {
933
- max-width: 20rem;
934
- border-radius: 1.5rem;
935
- margin: 1rem;
936
- }
937
- }
938
-
939
- .payment-modal-content {
940
- padding: 1.5rem 1rem;
941
- display: flex;
942
- flex-direction: column;
943
- align-items: center;
944
- text-align: center;
945
- }
946
-
947
- .payment-modal-title {
948
- font-size: 1.125rem;
949
- font-weight: 700;
950
- color: #111827;
951
- margin-bottom: 0.5rem;
952
- }
953
-
954
- .payment-modal-desc {
955
- font-size: 0.8125rem;
956
- color: #6b7280;
957
- line-height: 1.375;
958
- margin-bottom: 1rem;
959
- }
960
-
961
- .payment-cost-card {
962
- width: 100%;
963
- display: flex;
964
- align-items: center;
965
- justify-content: center;
966
- gap: 0.75rem;
967
- background: #f9fafb;
968
- border: 1px solid #f3f4f6;
969
- border-radius: 1rem;
970
- padding: 0.75rem 1rem;
971
- margin-bottom: 0.75rem;
972
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04);
973
- }
974
-
975
- .payment-cost-amount {
976
- font-size: 1.875rem;
977
- font-weight: 900;
978
- color: #9333ea;
979
- line-height: 1;
980
- }
981
-
982
- .payment-cost-icon {
983
- width: 1.5rem;
984
- height: 1.5rem;
985
- color: #9333ea;
986
- fill: rgba(147, 51, 234, 0.12);
987
- stroke: currentColor;
988
- }
989
-
990
- .payment-balance {
991
- width: 100%;
992
- font-size: 0.75rem;
993
- color: #6b7280;
994
- margin-bottom: 1rem;
995
- }
996
-
997
- .payment-insufficient {
998
- width: 100%;
999
- background: #fef2f2;
1000
- border: 1px solid #fee2e2;
1001
- border-radius: 0.75rem;
1002
- color: #dc2626;
1003
- font-size: 0.75rem;
1004
- font-weight: 600;
1005
- padding: 0.625rem;
1006
- margin-bottom: 1rem;
1007
- }
1008
-
1009
- .payment-actions {
1010
- display: flex;
1011
- gap: 0.75rem;
1012
- width: 100%;
1013
- }
1014
-
1015
- .payment-action-btn {
1016
- flex: 1;
1017
- min-width: 0;
1018
- border: none;
1019
- border-radius: 0.75rem;
1020
- padding: 0.75rem 0.5rem;
1021
- font-size: 0.875rem;
1022
- font-weight: 700;
1023
- cursor: pointer;
1024
- transition: transform 0.15s, background 0.15s;
1025
- }
1026
-
1027
- .payment-action-btn:active {
1028
- transform: scale(0.97);
1029
- }
1030
-
1031
- .payment-cancel-btn {
1032
- background: #f3f4f6;
1033
- color: #4b5563;
1034
- }
1035
-
1036
- .payment-cancel-btn:hover {
1037
- background: #e5e7eb;
1038
- }
1039
-
1040
- .payment-confirm-btn {
1041
- background: linear-gradient(135deg, #22c55e, #059669);
1042
- color: #ffffff;
1043
- box-shadow: 0 10px 15px -3px rgba(5, 150, 105, 0.22);
1044
- }
1045
-
1046
- .payment-confirm-btn:hover {
1047
- background: linear-gradient(135deg, #4ade80, #10b981);
1048
- }
1049
-
1050
- /* ========== Toast ========== */
1051
- .toast-container {
1052
- position: fixed;
1053
- top: 1rem;
1054
- left: 50%;
1055
- transform: translateX(-50%);
1056
- z-index: 2000;
1057
- display: flex;
1058
- flex-direction: column;
1059
- align-items: center;
1060
- gap: 0.5rem;
1061
- pointer-events: none;
1062
- width: 100%;
1063
- max-width: 24rem;
1064
- }
1065
-
1066
- .toast {
1067
- background: #ffffff;
1068
- color: #0f172a;
1069
- border: 1px solid #e2e8f0;
1070
- border-radius: 1rem;
1071
- padding: 0.75rem 1rem;
1072
- font-size: 0.875rem;
1073
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2), 0 4px 6px -2px rgba(0, 0, 0, 0.1);
1074
- animation: toastIn 0.2s ease-out;
1075
- max-width: 100%;
1076
- text-align: center;
1077
- display: flex;
1078
- align-items: center;
1079
- gap: 0.75rem;
1080
- pointer-events: auto;
1081
- }
1082
-
1083
- .toast-icon {
1084
- flex-shrink: 0;
1085
- width: 2.5rem;
1086
- height: 2.5rem;
1087
- border-radius: 9999px;
1088
- background: #dcfce7;
1089
- border: 1px solid #bbf7d0;
1090
- display: flex;
1091
- align-items: center;
1092
- justify-content: center;
1093
- }
1094
-
1095
- .toast-icon svg {
1096
- width: 1.25rem;
1097
- height: 1.25rem;
1098
- color: #16a34a;
1099
- }
1100
-
1101
- .toast-warning .toast-icon {
1102
- background: #fef3c7;
1103
- border-color: #fde68a;
1104
- }
1105
-
1106
- .toast-warning .toast-icon svg {
1107
- color: #d97706;
1108
- }
1109
-
1110
- .toast-content {
1111
- flex: 1;
1112
- min-width: 0;
1113
- }
1114
-
1115
- .toast-title {
1116
- font-weight: 600;
1117
- color: #0f172a;
1118
- line-height: 1.375;
1119
- }
1120
-
1121
- .toast-message {
1122
- color: #475569;
1123
- font-size: 0.8125rem;
1124
- margin-top: 0.125rem;
1125
- line-height: 1.375;
1126
- }
1127
-
1128
- @keyframes modalFadeIn {
1129
- from { opacity: 0; }
1130
- to { opacity: 1; }
1131
- }
1132
-
1133
- @keyframes modalSlideUp {
1134
- from { transform: translateY(100%); }
1135
- to { transform: translateY(0); }
1136
- }
1137
-
1138
- @keyframes toastIn {
1139
- from { opacity: 0; transform: translateY(-20px); }
1140
- to { opacity: 1; transform: translateY(0); }
1141
- }
1142
-
1143
- /* \u767B\u5F55\u63D0\u793A Toast */
1144
- .login-prompt-toast {
1145
- background: linear-gradient(135deg, rgba(251, 191, 36, 0.15), rgba(245, 158, 11, 0.15));
1146
- border-color: rgba(251, 191, 36, 0.4);
1147
- }
1148
-
1149
- .login-prompt-toast .toast-icon {
1150
- color: #fbbf24;
1151
- }
1152
-
1153
- .login-prompt-toast .toast-title {
1154
- color: #fef3c7;
1155
- }
1156
-
1157
- /* ========== \u6E38\u620F\u8BE6\u60C5\u9875\u6837\u5F0F\uFF08iframe \u5D4C\u5165\u6A21\u5F0F\uFF09========== */
1158
- .detail-nav {
1159
- display: flex;
1160
- align-items: center;
1161
- padding: 0.75rem 0.5rem;
1162
- background-color: #1a2332;
1163
- border-bottom: 1px solid #1e2a3a;
1164
- color: #ffffff;
1165
- gap: 0.5rem;
1166
- position: sticky;
1167
- top: 0;
1168
- z-index: 100;
1169
- }
1170
-
1171
- .detail-back-btn {
1172
- display: flex;
1173
- align-items: center;
1174
- justify-content: center;
1175
- gap: 0.125rem;
1176
- padding: 0 0.5rem;
1177
- height: 2rem;
1178
- background: transparent;
1179
- border: none;
1180
- border-radius: 0.375rem;
1181
- color: #ffffff;
1182
- cursor: pointer;
1183
- transition: color 0.2s, background 0.2s;
1184
- flex-shrink: 0;
1185
- }
1186
-
1187
- .detail-back-btn:hover {
1188
- color: #3b82f6;
1189
- background-color: rgba(59, 130, 246, 0.1);
1190
- }
1191
-
1192
- .detail-back-btn:active {
1193
- background-color: rgba(59, 130, 246, 0.2);
1194
- }
1195
-
1196
- .detail-back-text {
1197
- font-size: 0.875rem;
1198
- font-weight: 500;
1199
- }
1200
-
1201
- .detail-title {
1202
- font-size: 1.125rem;
1203
- font-weight: 600;
1204
- flex: 1;
1205
- white-space: nowrap;
1206
- overflow: hidden;
1207
- text-overflow: ellipsis;
1208
- }
1209
-
1210
- .detail-spacer {
1211
- width: 2rem;
1212
- flex-shrink: 0;
1213
- }
1214
-
1215
- .detail-iframe-container {
1216
- flex: 1;
1217
- width: 100%;
1218
- overflow: hidden;
1219
- background-color: #0f1419;
1220
- }
1221
-
1222
- .detail-iframe {
1223
- width: 100%;
1224
- height: calc(100vh - 4rem);
1225
- border: none;
1226
- display: block;
1227
- }
1228
- `,Ne=`
1229
- <svg xmlns="http://www.w3.org/2000/svg" style="display:none">
1230
- <symbol id="icon-adventure" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1231
- <polyline points="14.5 17.5 3 6 3 3 6 3 17.5 14.5"/>
1232
- <line x1="13" x2="19" y1="19" y2="13"/>
1233
- <line x1="16" x2="20" y1="16" y2="20"/>
1234
- <line x1="19" x2="21" y1="21" y2="19"/>
1235
- </symbol>
1236
- <symbol id="icon-simulation" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1237
- <path d="m2 7 4.41-4.41A2 2 0 0 1 7.83 2h8.34a2 2 0 0 1 1.42.59L22 7"/>
1238
- <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
1239
- <path d="M15 22v-4a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4"/>
1240
- <path d="M2 7h20"/>
1241
- <path d="M22 7v3a2 2 0 0 1-2 2 2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 16 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 12 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 8 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 4 12a2 2 0 0 1-2-2V7"/>
1242
- </symbol>
1243
- <symbol id="icon-casual" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1244
- <line x1="6" x2="10" y1="11" y2="11"/>
1245
- <line x1="8" x2="8" y1="9" y2="13"/>
1246
- <line x1="15" x2="15.01" y1="12" y2="12"/>
1247
- <line x1="18" x2="18.01" y1="10" y2="10"/>
1248
- <path d="M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z"/>
1249
- </symbol>
1250
- <symbol id="icon-arcade" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1251
- <path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>
1252
- </symbol>
1253
- <symbol id="icon-moba" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1254
- <path d="M9 10h.01"/>
1255
- <path d="M15 10h.01"/>
1256
- <path d="M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z"/>
1257
- </symbol>
1258
- <symbol id="icon-puzzle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1259
- <path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"/>
1260
- <path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z"/>
1261
- <path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4"/>
1262
- <path d="M17.599 6.5a3 3 0 0 0 .399-1.375"/>
1263
- <path d="M6.003 5.125A3 3 0 0 0 6.401 6.5"/>
1264
- <path d="M3.477 10.896a4 4 0 0 1 .585-.396"/>
1265
- <path d="M19.938 10.5a4 4 0 0 1 .585.396"/>
1266
- <path d="M6 18a4 4 0 0 1-1.967-.516"/>
1267
- <path d="M19.967 17.484A4 4 0 0 1 18 18"/>
1268
- </symbol>
1269
- <symbol id="icon-search" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1270
- <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
1271
- </symbol>
1272
- <symbol id="icon-warning" viewBox="0 0 24 24" fill="currentColor">
1273
- <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
1274
- </symbol>
1275
- <symbol id="icon-gem" viewBox="0 0 24 24">
1276
- <path d="M10.5 3 8 9l4 13 4-13-2.5-6"/>
1277
- <path d="M17 3a2 2 0 0 1 1.6.8l3 4a2 2 0 0 1 .013 2.382l-7.99 10.986a2 2 0 0 1-3.247 0l-7.99-10.986A2 2 0 0 1 2.4 7.8l2.998-3.997A2 2 0 0 1 7 3z"/>
1278
- <path d="M2 9h20"/>
1279
- </symbol>
1280
- </svg>
1281
- `,pt=r=>{switch(r){case"Adventure":return"#FF7D54";case"Simulation":return"#4ADE80";case"Casual":return"#60A5FA";case"Arcade":return"#A78BFA";case"Moba":return"#FACC15";case"Puzzle":return"#FB923C";case"Doge OS":return"#FBBF24";default:return"#22d3ee"}},Ge=[{id:"Doge OS",name:"Doge OS",iconType:"image",iconSrc:"https://games.playsout.com/resources/icon/image/doge32.png"},{id:"Adventure",name:"Adventure",iconType:"icon",iconKey:"adventure",color:"#FF7D54"},{id:"Simulation",name:"Simulation",iconType:"icon",iconKey:"simulation",color:"#4ADE80"},{id:"Casual",name:"Casual",iconType:"icon",iconKey:"casual",color:"#60A5FA"},{id:"Arcade",name:"Arcade",iconType:"icon",iconKey:"arcade",color:"#A78BFA"},{id:"Moba",name:"Moba",iconType:"icon",iconKey:"moba",color:"#FACC15"},{id:"Puzzle",name:"Puzzle",iconType:"icon",iconKey:"puzzle",color:"#FB923C"}],R=class extends HTMLElement{constructor(){super();this._appId="";this._locale="zh";this.games=[];this.filteredGames=[];this.selectedCategory=null;this.searchQuery="";this.bannerUrl="";this.userPoints=1e3;this.avatarUrl="";this.recentGames=[];this._detailMode="iframe";this.currentView="list";this.currentGame=null;this.currentIframeSrc="";this.pendingPaymentResolver=null;this.gemPacks=[{amount:12,price:.99,hot:!1},{amount:60,price:4.99,hot:!0},{amount:180,price:14.99,hot:!1},{amount:360,price:29.99,hot:!1}];this.toastTimeout=null;this.shadow=this.attachShadow({mode:"open"}),this.bridge=new $({getIframe:()=>this.shadow.querySelector(".detail-iframe"),getGameUrl:()=>this.currentIframeSrc,getBalance:()=>this.userPoints,getUser:()=>this.getBridgeUser(),getLocale:()=>this._locale,requestPayment:e=>this.showPaymentModal(e)})}static get observedAttributes(){return["app-id","locale","banner-url","user-points","avatar-url","recent-games","detail-mode"]}t(e,a){let o=C[this._locale]??C.en,i=ne(o,e);if(i!==e)return _e(i,a??{});let n=ne(C.en,e);return _e(n,a??{})}hasTranslation(e){let a=C[this._locale]??C.en;return ne(a,e)!==e}getBridgeUser(){let e=window.__playsout_sdk_instance,a=typeof e?.isInitialized=="function"?e.isInitialized():e?.isInitialized,o=typeof e?.isLoggedIn=="function"?e.isLoggedIn():e?.isLoggedIn,i=a&&o&&typeof e?.getUser=="function"?e.getUser():null;return i?{uid:String(i.userId||i.id||i.username||"user"),nickname:String(i.username||i.name||"User"),avatarUrl:i.avatar||i.avatarUrl||""}:null}setUserPoints(e,a,o){let i=this.userPoints;this.userPoints=Math.max(0,Math.floor(e)),this.updateUI(),this.dispatchEvent(new CustomEvent("gem-balance-change",{bubbles:!0,composed:!0,detail:{balance:this.userPoints,previousBalance:i,delta:this.userPoints-i,reason:a,orderId:o}}))}connectedCallback(){this.bridge.attach(),this.render(),this.loadGames()}disconnectedCallback(){this.resolvePendingPayment({status:"cancelled",balance:this.userPoints}),this.bridge.detach(),this.toastTimeout&&(clearTimeout(this.toastTimeout),this.toastTimeout=null)}attributeChangedCallback(e,a,o){if(a!==o){switch(e){case"app-id":this._appId=o||"";break;case"locale":this._locale=o||"zh";break;case"banner-url":this.bannerUrl=o||"";break;case"user-points":{let i=parseInt(o||"1000",10);this.userPoints=Number.isFinite(i)?i:1e3}break;case"avatar-url":this.avatarUrl=o||"";break;case"recent-games":try{this.recentGames=o?JSON.parse(o):[]}catch{this.recentGames=[]}break;case"detail-mode":this._detailMode=o||"link";break}this.shadow.innerHTML&&(e==="locale"?(this.resolvePendingPayment({status:"cancelled",balance:this.userPoints}),this.bridge.cancelPendingPayment(),this.render(),this.loadGames()):this.updateUI())}}async loadGames(){this.showLoading();let e=window.__playsout_sdk_instance;if(!e||!e.isInitialized){let a=()=>{e&&e.isInitialized&&(b.off("initialized",a),this.loadGames())};e?b.on("initialized",a):this.pollForSDK();return}this.doLoadGames(e)}pollForSDK(){let e=setInterval(()=>{let a=window.__playsout_sdk_instance;a&&a.isInitialized&&(clearInterval(e),this.loadGames())},100);setTimeout(()=>{clearInterval(e),this.games.length||(this.showError(),console.warn("[PlaysoutWidget] SDK initialization timeout"))},1e4)}async doLoadGames(e){try{this.games=await e.getGames();let a=this.games.map(o=>{if(!o.image)return null;let i=window.__playsout_resolveAsset,n=typeof i=="function"?i(o.image):o.image;return typeof n!="string"?null:n.startsWith("http")?n:null}).filter(Boolean);a.length>0&&Ie(a,!0),this.filterGames()}catch(a){console.error("[PlaysoutWidget] Failed to load games:",a),this.showError()}}filterGames(){let e=[...this.games];if(this.selectedCategory&&(e=e.filter(a=>a.category===this.selectedCategory)),this.searchQuery){let a=this.searchQuery.toLowerCase();e=e.filter(o=>o.title.toLowerCase().includes(a)||o.category.toLowerCase().includes(a))}this.filteredGames=e,this.renderGames()}showLoading(){let e=this.shadow.querySelector(".widget-content");e&&(e.innerHTML=`
1282
- <div class="loading">
1283
- <div class="loading-spinner"></div>
1284
- </div>
1285
- `)}showError(){let e=this.shadow.querySelector(".widget-content");e&&(e.innerHTML=`
1286
- <div class="empty-state">
1287
- <div class="empty-state-icon">
1288
- <svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
1289
- <use href="#icon-warning"/>
1290
- </svg>
1291
- </div>
1292
- <p>Failed to load games</p>
1293
- </div>
1294
- `)}render(){let e=this.bannerUrl||l("./home-banner.webp");if(this.__criticalAssetsMarked!==!0){let a=l("./logowhite.png"),o=Ge.filter(i=>i.iconType==="image"&&i.iconSrc).map(i=>i.iconSrc);xe([a,e,...o]),this.__criticalAssetsMarked=!0}if(this.currentView==="detail"&&this.currentGame){this.renderGameDetail();return}this.shadow.innerHTML=`
1295
- <style>${Oe}</style>
1296
- ${Ne}
1297
- <div class="playsout-scroll-container">
1298
- <div class="mobile-container">
1299
- <div class="playsout-widget">
1300
- <!-- Header -->
1301
- <header class="widget-header">
1302
- <div class="widget-logo">
1303
- <img src="${K("./logowhite.png")}" alt="Playsout" />
1304
- </div>
1305
- <div class="widget-user">
1306
- <!-- Profile Button -->
1307
- <button class="widget-profile-btn" id="profile-btn" aria-label="Profile">
1308
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1309
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
1310
- <circle cx="12" cy="7" r="4"/>
1311
- </svg>
1312
- </button>
1313
- </div>
1314
- </header>
1315
-
1316
- <!-- Banner -->
1317
- <div class="widget-banner">
1318
- <img
1319
- class="banner-image"
1320
- src="${e?K(e):""}"
1321
- alt="Playsout Games"
1322
- />
1323
- </div>
1324
-
1325
- <!-- Search -->
1326
- <div class="widget-search">
1327
- <div class="search-wrapper">
1328
- <span class="search-icon">
1329
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1330
- <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
1331
- </svg>
1332
- </span>
1333
- <input
1334
- type="text"
1335
- class="search-input"
1336
- id="search-input"
1337
- placeholder="${this.t("home.searchPlaceholder")}"
1338
- />
1339
- <button class="search-btn" id="search-btn" aria-label="Search">
1340
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1341
- <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>
1342
- </svg>
1343
- </button>
1344
- </div>
1345
- </div>
1346
-
1347
- <!-- Categories -->
1348
- <div class="widget-categories">
1349
- <div class="categories-wrapper" id="categories">
1350
- ${Ge.map(a=>{let o=this.selectedCategory===a.id,i=a.color||pt(a.id),n=a.iconType==="image"&&a.iconSrc?`<img src="${K(a.iconSrc)}" alt="" style="width:1rem;height:1rem;object-fit:contain;" />`:`<svg width="1rem" height="1rem" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" color="${i}" style="color:${i}"><use href="#icon-${a.iconKey}"/></svg>`,s=this.hasTranslation(`categories.${a.id}`)?this.t(`categories.${a.id}`):a.name;return`
1351
- <button class="category-btn${o?" active":""}" data-category="${a.id}">
1352
- <span class="category-icon">${n}</span>
1353
- <span class="category-label">${s}</span>
1354
- </button>`}).join("")}
1355
- </div>
1356
- </div>
1357
-
1358
- <!-- Games Content -->
1359
- <div class="widget-content">
1360
- <div class="loading">
1361
- <div class="loading-spinner"></div>
1362
- </div>
1363
- </div>
1364
- </div>
1365
- </div>
1366
- </div>
1367
- `,this.attachEventListeners()}updateUI(){let e=this.shadow.querySelector(".banner-image");e&&this.bannerUrl&&(e.src=this.bannerUrl);let a=this.shadow.querySelector("#gems-amount");a&&(a.textContent=String(this.userPoints))}showStoreModal(){this.hideStoreModal();let e=document.createElement("div");e.className="store-modal-overlay",e.id="store-modal-overlay",e.innerHTML=`
1368
- <div class="store-modal" id="store-modal">
1369
- <div class="store-modal-header">
1370
- <h2 class="store-modal-title">${this.t("store.title")}</h2>
1371
- </div>
1372
- <div class="store-modal-content">
1373
- ${this.gemPacks.map(a=>`
1374
- <div class="store-pack">
1375
- ${a.hot?`<div class="store-pack-hot">${this.t("store.hot")}</div>`:""}
1376
- <div class="store-pack-left">
1377
- <div class="store-pack-icon">
1378
- <svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
1379
- <use href="#icon-gem"/>
1380
- </svg>
1381
- </div>
1382
- <div class="store-pack-info">
1383
- <span class="store-pack-amount">${a.amount} <span>${this.t("store.unit")}</span></span>
1384
- <span class="store-pack-price">US$${a.price}</span>
1385
- </div>
1386
- </div>
1387
- <button class="store-buy-btn" data-amount="${a.amount}">${this.t("store.buy")}</button>
1388
- </div>
1389
- `).join("")}
1390
- </div>
1391
- <div class="store-modal-footer">
1392
- <button class="store-cancel-btn" id="store-cancel">${this.t("store.cancel")}</button>
1393
- </div>
1394
- </div>
1395
- `,this.shadow.appendChild(e),e.querySelectorAll(".store-buy-btn").forEach(a=>{a.addEventListener("click",()=>{let o=parseInt(a.dataset.amount||"0",10);this.handleGemPurchase(o)})}),e.querySelector("#store-cancel")?.addEventListener("click",()=>{this.hideStoreModal()}),e.addEventListener("click",a=>{a.target===e&&this.hideStoreModal()})}hideStoreModal(){this.shadow.querySelector("#store-modal-overlay")?.remove()}showPaymentModal(e){return this.hidePaymentModal(),new Promise(a=>{this.pendingPaymentResolver=a;let o=document.createElement("div");o.className="payment-modal-overlay",o.id="payment-modal-overlay";let i=this.userPoints<e.amount;o.innerHTML=`
1396
- <div class="payment-modal" role="dialog" aria-modal="true" aria-labelledby="payment-modal-title">
1397
- <div class="payment-modal-content">
1398
- <h2 class="payment-modal-title" id="payment-modal-title">${this.t("payment.title")}</h2>
1399
- <p class="payment-modal-desc">${this.t("payment.description",{amount:e.amount})}</p>
1400
- <div class="payment-cost-card" aria-label="${this.t("payment.amountLabel",{amount:e.amount})}">
1401
- <span class="payment-cost-amount">${e.amount}</span>
1402
- <svg class="payment-cost-icon" viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
1403
- <use href="#icon-gem"/>
1404
- </svg>
1405
- </div>
1406
- <div class="payment-balance">${this.t("payment.balance",{balance:this.userPoints})}</div>
1407
- ${i?`<div class="payment-insufficient">${this.t("payment.insufficientMessage",{balance:this.userPoints,amount:e.amount})}</div>`:""}
1408
- <div class="payment-actions">
1409
- <button class="payment-action-btn payment-cancel-btn" id="payment-cancel-btn">${this.t("payment.cancel")}</button>
1410
- <button class="payment-action-btn payment-confirm-btn" id="payment-confirm-btn">${this.t("payment.confirm")}</button>
1411
- </div>
1412
- </div>
1413
- </div>
1414
- `,this.shadow.appendChild(o),o.querySelector("#payment-cancel-btn")?.addEventListener("click",()=>{this.resolvePendingPayment({status:"cancelled",balance:this.userPoints})}),o.querySelector("#payment-confirm-btn")?.addEventListener("click",()=>{if(this.userPoints<e.amount){this.showToast(this.t("payment.insufficientTitle"),this.t("payment.insufficientMessage",{balance:this.userPoints,amount:e.amount}),"warning"),this.resolvePendingPayment({status:"insufficient",balance:this.userPoints});return}this.setUserPoints(this.userPoints-e.amount,"payment",e.orderId),this.showToast(this.t("payment.successTitle"),this.t("payment.successMessage",{amount:e.amount})),this.resolvePendingPayment({status:"success",balance:this.userPoints})}),o.addEventListener("click",n=>{n.target===o&&this.resolvePendingPayment({status:"cancelled",balance:this.userPoints})})})}hidePaymentModal(){this.shadow.querySelector("#payment-modal-overlay")?.remove()}resolvePendingPayment(e){let a=this.pendingPaymentResolver;this.pendingPaymentResolver=null,this.hidePaymentModal(),a&&a(e)}showProfileModal(){this.hideProfileModal();let e=document.createElement("div");e.className="profile-modal-overlay",e.id="profile-modal-overlay";let a=window.__playsout_sdk_instance,n=((typeof a?.isInitialized=="function"?a.isInitialized():a?.isInitialized)?a.getUser():null)?.username||this.t("profile.guest");e.innerHTML=`
1415
- <div class="profile-modal" id="profile-modal">
1416
- <div class="profile-modal-header">
1417
- <h2 class="profile-modal-title">${this.t("profile.title")}</h2>
1418
- <button class="profile-modal-close" id="profile-close-btn">\u2715</button>
1419
- </div>
1420
- <div class="profile-modal-content">
1421
- <!-- \u7528\u6237\u4FE1\u606F\u5FBD\u7AE0 -->
1422
- <div class="profile-user-badge">
1423
- <svg class="profile-user-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1424
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
1425
- <circle cx="12" cy="7" r="4"></circle>
1426
- </svg>
1427
- <span class="profile-username-text">${n}</span>
1428
- </div>
1429
-
1430
- <section class="profile-section">
1431
- <h3 class="profile-section-title">${this.t("profile.settings")}</h3>
1432
- <div class="profile-settings">
1433
- <div class="profile-setting-item" id="profile-language-btn">
1434
- <span class="profile-setting-label">${this.t("profile.language")}</span>
1435
- <div class="profile-setting-value">
1436
- <span id="profile-current-lang">${this.t(`profile.languages.${this._locale}`)}</span>
1437
- <span>\u203A</span>
1438
- </div>
1439
- </div>
1440
- </div>
1441
- </section>
1442
- </div>
1443
- </div>
1444
- `,this.shadow.appendChild(e),e.querySelector("#profile-close-btn")?.addEventListener("click",()=>{this.hideProfileModal()}),e.addEventListener("click",f=>{f.target===e&&this.hideProfileModal()});let s=()=>{let f=window.__playsout_sdk_instance,E=(f?.getUser?f.getUser():null)?.username||this.t("profile.guest"),se=this.shadow.querySelector(".profile-username-text");se&&(se.textContent=E)},p=()=>{let f=this.shadow.querySelector(".profile-username-text");f&&(f.textContent=this.t("profile.guest")),this.hideProfileModal()},m=window.__playsout_sdk_instance;m?.on&&(m.on("login",s),m.on("logout",s),m.on("authExpired",p)),e.querySelector("#profile-language-btn")?.addEventListener("click",()=>{this.showLanguageSelectModal()})}hideProfileModal(){this.shadow.querySelector("#profile-modal-overlay")?.remove(),this.shadow.querySelector("#language-modal-overlay")?.remove()}showLanguageSelectModal(){this.shadow.querySelector("#language-modal-overlay")?.remove();let e=document.createElement("div");e.className="language-modal-overlay",e.id="language-modal-overlay";let a=[{code:"en",label:"English"},{code:"zh",label:"\u4E2D\u6587"},{code:"ja",label:"\u65E5\u672C\u8A9E"},{code:"ko",label:"\uD55C\uAD6D\uC5B4"},{code:"th",label:"\u0E44\u0E17\u0E22"},{code:"vi",label:"Ti\u1EBFng Vi\u1EC7t"},{code:"id",label:"Bahasa Indonesia"},{code:"ms",label:"Bahasa Melayu"},{code:"es",label:"Espa\xF1ol"}];e.innerHTML=`
1445
- <div class="language-modal">
1446
- <div class="language-modal-header">
1447
- <h3 class="language-modal-title">${this.t("profile.language")}</h3>
1448
- <button class="language-modal-close" id="language-close-btn">\u2715</button>
1449
- </div>
1450
- <div class="language-modal-list">
1451
- ${a.map(o=>`
1452
- <button class="language-option${o.code===this._locale?" active":""}" data-lang="${o.code}">
1453
- <span class="language-option-label">${o.label}</span>
1454
- ${o.code===this._locale?'<span class="language-option-check">\u2713</span>':""}
1455
- </button>
1456
- `).join("")}
1457
- </div>
1458
- </div>
1459
- `,this.shadow.appendChild(e),e.querySelector("#language-close-btn")?.addEventListener("click",()=>{this.shadow.querySelector("#language-modal-overlay")?.remove()}),e.addEventListener("click",o=>{o.target===e&&this.shadow.querySelector("#language-modal-overlay")?.remove()}),e.querySelectorAll(".language-option").forEach(o=>{o.addEventListener("click",()=>{let i=o.dataset.lang;if(i&&i!==this._locale){this._locale=i,this.setAttribute("locale",this._locale),this.dispatchEvent(new CustomEvent("locale-change",{bubbles:!0,composed:!0,detail:this._locale}));let n=this.shadow.querySelector("#profile-current-lang");n&&(n.textContent=this.t(`profile.languages.${this._locale}`)),this.shadow.querySelector("#language-modal-overlay")?.remove()}})})}handleGemPurchase(e){this.setUserPoints(this.userPoints+e,"store"),this.hideStoreModal(),this.showToast(this.t("store.successTitle"),this.t("store.successMessage",{amount:e}))}showToast(e,a="",o="success"){this.toastTimeout&&clearTimeout(this.toastTimeout),this.shadow.querySelector("#toast-container")?.remove();let i=document.createElement("div");i.className="toast-container",i.id="toast-container",i.innerHTML=`
1460
- <div class="toast${o==="warning"?" toast-warning":""}">
1461
- <div class="toast-icon">
1462
- <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
1463
- ${o==="warning"?'<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v4m0 4h.01M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>':'<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>'}
1464
- </svg>
1465
- </div>
1466
- <div class="toast-content">
1467
- <div class="toast-title">${e}</div>
1468
- ${a?`<div class="toast-message">${a}</div>`:""}
1469
- </div>
1470
- </div>
1471
- `,this.shadow.appendChild(i),this.toastTimeout=window.setTimeout(()=>{i.style.opacity="0",i.style.transition="opacity 0.2s",setTimeout(()=>i.remove(),200)},3e3)}renderGames(){let e=this.shadow.querySelector(".widget-content");if(e){if(this.filteredGames.length===0){e.innerHTML=`
1472
- <div class="widget-games">
1473
- <div class="no-results">
1474
- <p>${this.t("home.noGames")}</p>
1475
- </div>
1476
- </div>
1477
- `;return}e.innerHTML=`
1478
- <div class="widget-games">
1479
- <div class="games-grid">
1480
- ${this.filteredGames.map((a,o)=>this.renderGameCard(a,o)).join("")}
1481
- </div>
1482
- </div>
1483
- `,e.querySelectorAll(".game-card").forEach(a=>{a.addEventListener("click",()=>{let o=a.getAttribute("data-game-id"),i=this.games.find(n=>n.id===o);if(i){let n=window.__playsout_sdk_instance,s=typeof n?.isInitialized=="function"?n.isInitialized():n?.isInitialized,p=typeof n?.isLoggedIn=="function"?n.isLoggedIn():n?.isLoggedIn;if(!s||!p){this.showLoginPrompt();return}if(this.dispatchEvent(new CustomEvent("game-click",{detail:i,bubbles:!0,composed:!0})),this._detailMode==="iframe"&&i.externalUrl)this.currentGame=i,this.currentView="detail",this.render();else{let m=i.externalUrl||`/games/${i.id}`;window.location.href=m}}})})}}showLoginPrompt(){this.toastTimeout&&clearTimeout(this.toastTimeout),this.shadow.querySelector("#toast-container")?.remove();let e=document.createElement("div");e.className="toast-container";let a=this.t.bind(this);e.innerHTML=`
1484
- <div class="toast login-prompt-toast">
1485
- <div class="toast-icon">
1486
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1487
- <circle cx="12" cy="12" r="10"></circle>
1488
- <line x1="12" y1="8" x2="12" y2="12"></line>
1489
- <line x1="12" y1="16" x2="12.01" y2="16"></line>
1490
- </svg>
1491
- </div>
1492
- <div class="toast-content">
1493
- <div class="toast-title">${a("auth.mustLogin")}</div>
1494
- </div>
1495
- </div>
1496
- `,this.shadow.appendChild(e),this.toastTimeout=window.setTimeout(()=>{e.style.opacity="0",e.style.transform="translateY(10px)",e.style.transition="all 0.2s ease-out",setTimeout(()=>e.remove(),200)},1e3)}renderGameCard(e,a){let o=[];e.isNew&&o.push('<span class="game-tag new">NEW</span>'),e.isHot&&o.push('<span class="game-tag hot">HOT</span>');let i=a<8?"eager":"lazy";return`
1497
- <div class="game-card" data-game-id="${e.id}">
1498
- <div class="game-image-wrapper">
1499
- <img
1500
- class="game-image"
1501
- src="${K(e.image)}"
1502
- alt="${e.title}"
1503
- loading="${i}"
1504
- draggable="false"
1505
- />
1506
- </div>
1507
- <div class="game-info">
1508
- <div class="title-row">
1509
- <h3 class="game-title">${e.title}</h3>
1510
- ${o.length>0?o.join(""):""}
1511
- </div>
1512
- <div class="divider"></div>
1513
- <p class="game-category">${this.hasTranslation(`categories.${e.category}`)?this.t(`categories.${e.category}`):e.category}</p>
1514
- </div>
1515
- </div>
1516
- `}renderGameDetail(){if(!this.currentGame)return;let e=this.currentGame,a=e.externalUrl||`/games/${e.id}`;this.currentIframeSrc=a,this.shadow.innerHTML=`
1517
- <style>${Oe}</style>
1518
- ${Ne}
1519
- <div class="playsout-scroll-container">
1520
- <div class="mobile-container">
1521
- <div class="playsout-widget">
1522
- <!-- \u5BFC\u822A\u680F -->
1523
- <header class="detail-nav">
1524
- <button class="detail-back-btn" id="detail-back-btn" aria-label="${this.t("game.header.back")}">
1525
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1526
- <path d="M15 18l-6-6 6-6"/>
1527
- </svg>
1528
- <span class="detail-back-text">${this.t("game.header.back")}</span>
1529
- </button>
1530
- <span class="detail-title">${e.title}</span>
1531
- <div class="detail-spacer"></div>
1532
- </header>
1533
-
1534
- <!-- \u6E38\u620F iframe -->
1535
- <div class="detail-iframe-container">
1536
- <iframe
1537
- src="${a}"
1538
- class="detail-iframe"
1539
- allow="fullscreen"
1540
- sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
1541
- ></iframe>
1542
- </div>
1543
- </div>
1544
- </div>
1545
- </div>
1546
- `,this.shadow.getElementById("detail-back-btn")?.addEventListener("click",()=>{this.resolvePendingPayment({status:"cancelled",balance:this.userPoints}),this.bridge.cancelPendingPayment(),this.currentView="list",this.currentGame=null,this.currentIframeSrc="",this.render(),this.loadGames()})}attachEventListeners(){this.shadow.getElementById("gems-btn")?.addEventListener("click",()=>{this.showStoreModal()}),this.shadow.getElementById("profile-btn")?.addEventListener("click",()=>{this.showProfileModal()});let e=this.shadow.getElementById("search-input");e?.addEventListener("input",o=>{let i=o.target;this.searchQuery=i.value,this.filterGames()}),this.shadow.getElementById("search-btn")?.addEventListener("click",()=>{e?.focus()});let a=this.shadow.getElementById("categories");a?.addEventListener("click",o=>{let n=o.target.closest(".category-btn");if(n){let s=n.getAttribute("data-category")||"";this.selectedCategory===s?(this.selectedCategory=null,a.querySelectorAll(".category-btn").forEach(p=>{p.classList.remove("active")})):(this.selectedCategory=s,a.querySelectorAll(".category-btn").forEach(p=>{p.classList.remove("active")}),n.classList.add("active")),this.filterGames()}})}};customElements.get("playsout-widget")||customElements.define("playsout-widget",R);typeof customElements<"u"&&(customElements.get("playsout-widget")||customElements.define("playsout-widget",R));var{init:ft,mount:bt,unmount:yt,destroy:vt,Login:wt,logout:kt,getToken:xt,getUserInfo:It,getUser:St,setLocale:Et,getLocale:Tt,getGames:At,getCategories:Pt,on:Lt,off:Ct,isInitialized:Rt,isLoggedIn:Mt,instance:_t,PlaysoutSDKClass:Ot}=N;typeof window<"u"&&(window.Playsout=N,window.__playsout_sdk_instance=N.instance);return je(Nt);})();