PageSourceSearch

https://xn--80aefpcdffkkkhughbp6n.com/var/cache/asset20_05f0f86e2e13fec84cb07901101a1887.js

js xn--80aefpcdffkkkhughbp6n.com collected 2026-10-07 18:10:51 UTC 31,963 bytes, 268 lines download raw bytes

1app.addModule(()=>{PubSub.subscribe('showDialog',(e,params)=>{const onClose=params.onClose;app.openViewer({mobile:{withTick:!0,maxHeight:'calc(100dvh - 10px)'},desktop:{maxWidth:'550px',},onClose:onClose,component:{data(){return{title:params.title,text:params.text,}},computed:{...Vuex.mapState(['loc']),buttonText(){return this.loc['common/ok']}},methods:{close(){this.$emit('close')}},store:app.store,template:`
2                    <div class="dialog" 
3                        :class="{'dialog--withTitle': title}">
4                        <h3 v-if="title" class="dialog__title">{{ title }}</h3>
5                        <p class="dialog__text" v-html="text"></p>
6                        <button v-press
7                                class="dialog__button"
8                                @click="close">
9                                {{ buttonText }}
10                        </button>
11                    </div>
12                `}})})});app.storyTimelineComponent={props:['count','current'],data(){return{progress:0,}},methods:{fillStyle(index){const scale=index<this.current?1:index>this.current?0:this.progress;return{transform:`scaleX(${scale})`}},},template:`
13    <div class="timeline">
14        <div v-for="index in count"
15             :key="index"
16             class="timeline__item">
17            <div class="timeline__itemFill" :style="fillStyle(index - 1)"></div>
18        </div>
19    </div>
20    `};app.storyActionComponent={props:['action','compact'],data(){return{startAnimationShine:!1,isActiveRipple:!1,positions:{x:0,y:0,},}},computed:{...Vuex.mapState(['loc','cart']),stylePositionRipple(){return{left:`${this.positions.x}px`,top:`${this.positions.y}px`,}},isPromocode(){return this.action.type==='promo'},isDescription(){return this.action.type==='description'},isCompactInfo(){return this.compact&&this.isDescription},buttonText(){return this.action.text},isShowAppliedPromo(){if(!this.cart||!this.cart.promo){return}
21return this.isPromocode&&this.action.meta.promocode===this.cart.promo.code},locApplied(){return this.loc['promo/stories/promoCode/applied']},},methods:{apply(e){if(!this.isShowAppliedPromo&&this.isPromocode){this.startAnimationShine=!0;const rect=e.currentTarget.getBoundingClientRect();this.positions.x=e.clientX-rect.left;this.positions.y=e.clientY-rect.top;this.isActiveRipple=!0;setTimeout(()=>{this.isActiveRipple=!1;this.positions.x=0;this.positions.y=0},1000)}
22this.$emit('action',this.action)}},template:`
23    <div class="action"
24         v-press
25         :class="{'action--compact': isCompactInfo}"
26         @click.stop="apply">
27        <span v-if="isActiveRipple" class="action__animationRipple" :style="stylePositionRipple"></span>
28        <p v-if="isShowAppliedPromo" class="action__animationShine">
29
30             <svg class="action__appliedIco appliedIco appliedIco--play" viewBox="0 0 18 13" aria-hidden="true">
31                 <g transform="translate(9.0001 6.5001)">
32                     <g class="appliedIco__g1">
33                         <path class="appliedIco__p2" d="M-7.536 0.844L-3.075 5.305L7.536 -5.305" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke="#ffffff" pathLength="1" visibility="hidden" stroke-dasharray="0 2" fill="none"/>
34                     </g>
35                 </g>
36             </svg>
37
38            {{ locApplied }}
39
40        </p>
41        <template v-else>
42            <span v-if="isCompactInfo" class="action__icon">
43                <svg width="2" height="12" viewBox="0 0 2 12" fill="none" xmlns="http://www.w3.org/2000/svg">
44                    <circle cx="1" cy="1" r="1" fill="currentColor"/>
45                    <rect y="4" width="2" height="8" rx="1" fill="currentColor"/>
46                </svg>
47            </span>
48            <p v-else class="action__text" :class="{'action__animationShine action__animationShine--start': startAnimationShine}">
49             {{ buttonText }}
50            </p>
51        </template>
52    </div>
53    `};app.storyComponent={components:{'story-timeline':app.storyTimelineComponent,'story-action':app.storyActionComponent,},props:['story','near','active','playing','held'],data(){return{slideIndex:0,isImageReady:!1,isVideoWaiting:!0,isVideoBlocked:!1,}},computed:{slides(){return this.story.photo.slides},slide(){return this.slides[this.slideIndex]},isVideo(){return this.slide.type==='video'},isFirstSlide(){return this.slideIndex===0},isLastSlide(){return this.slideIndex===this.slides.length-1},isSpinner(){return this.isVideo?this.isVideoWaiting&&!this.isVideoBlocked:!this.isImageReady},},watch:{near(isNear){if(isNear){this.preloadImages();return}
54this.stopVideo();this.slideIndex=0},active(){this.restart();this.syncVideo();this.emitSlide()},playing(){this.syncVideo()},slideIndex(){this.isImageReady=!1;this.isVideoWaiting=!0;this.isVideoBlocked=!1;this.$nextTick(()=>{const image=this.$refs.image;
54if(image&&image.complete&&image.naturalWidth){this.isImageReady=!0}
55this.restart();this.syncVideo();this.emitSlide()})},},created(){this.raf=0;this.lastTs=0;this.elapsed=0},mounted(){if(this.near){this.preloadImages()}
56this.restart();this.syncVideo();this.emitSlide()},beforeDestroy(){cancelAnimationFrame(this.raf);this.stopVideo()},methods:{tick(ts){const dt=Math.min(ts-this.lastTs,100);this.lastTs=ts;let progress=0;if(this.isVideo){const video=this.$refs.video;if(video&&video.duration){progress=video.currentTime/video.duration}}else{if(this.playing&&this.isImageReady){this.elapsed+=dt}
57progress=this.elapsed/10000;if(progress>=1){this.next();return}}
58this.$refs.timeline.progress=Math.min(progress,1);this.raf=requestAnimationFrame(this.tick)},restart(){cancelAnimationFrame(this.raf);this.elapsed=0;this.$refs.timeline.progress=0;const video=this.$refs.video;if(video&&video.currentTime){video.currentTime=0}
59if(this.active){this.lastTs=performance.now();this.raf=requestAnimationFrame(this.tick)}},syncVideo(){const video=this.$refs.video;if(!video)return;if(!this.active||!this.playing){video.pause();return}
60const promise=video.play();promise&&promise.then(()=>this.isVideoBlocked=!1).catch((e)=>{if(e&&e.name==='NotAllowedError'){this.isVideoBlocked=!0}})},emitSlide(){if(!this.active)return;this.$emit('slide',{media:{el:this.isVideo?this.$refs.video:this.$refs.image},isFirst:this.isFirstSlide,isLast:this.isLastSlide,})},preloadImages(){this.slides.forEach((slide)=>{if(slide.type!=='video'&&slide.preview){const img=new Image();img.src=slide.preview;img.decode&&img.decode().catch(()=>{})}})},stopVideo(){const video=this.$refs.video;if(video){video.pause();video.removeAttribute('src');video.load()}},onVideoError(){if(this.active)this.next();},next(){if(!this.active)return;if(this.isLastSlide){this.$emit('next')}else{this.slideIndex++}},prev(){if(this.isFirstSlide){this.$emit('prev')}else{this.slideIndex--}},tap(ratioX){if(this.isVideoBlocked){this.syncVideo();return}
61ratioX<1/3?this.prev():this.next()},handleAction(action){if(!action)return;const actionType=action.type;if(actionType==='description'){this.$emit('dialog',!0);PubSub.publish('showDialog',{title:action.meta.name,text:action.meta.text,onClose:()=>{this.$emit('dialog',!1)}});return}
62if(actionType==='url'){window.open(action.meta.url,'_blank')}
63if(actionType==='product'){let forceAddress=!1;if(app.store.state.address&&app.store.state.address.warning){forceAddress='showUserAddress'}
64const dish=action.meta;PubSub.publish('showTopping',{dish:{id:dish.id,name:dish.name,ingredients:dish.ingredients,nutrients:dish.nutrients?dish.nutrients:'',prices:dish.prices,price:dish.priceFromFormatted?dish.priceFromFormatted:dish.priceCoreFormatted,balance:dish.balance||'',media:dish.media?dish.media:null,size:dish.sizeCoreFormatted?dish.sizeCoreFormatted:'',params:dish.params,photo:{full:dish.photo&&dish.photo.full||'',low:dish.photo&&dish.photo.low||'',ratio:dish.photo&&dish.photo.ratio||'',},extraPhotos:dish.extraPhotos?dish.extraPhotos:null},forceAddress:forceAddress,modifiers:dish.modifiers?JSON.parse(JSON.stringify(dish.modifiers)):null,})}
65if(actionType==='promo'){PubSub.publish('recalcCart',{cartSwitchConfirmed:!0,changePromocode:action.meta.promocode,});return}
66this.$emit('close')},},template:`
67    <div class="story" :class="{'story--held': held}">
68
69        <video v-if="near && isVideo"
70               ref="video"
71               :key="slide.id"
72               class="story__media story__media--video"
73               :src="slide.preview"
74               preload="auto"
75               muted playsinline webkit-playsinline
76               @waiting="isVideoWaiting = true"
77               @playing="isVideoWaiting = false"
78               @ended="next"
79               @error="onVideoError" />
80        <!-- Без :key: при смене фото-слайда браузер держит старую картинку, пока не готова новая.
81             С новым <img> на каждый слайд один кадр был пустым — мигал чёрный фон сторис -->
82        <img v-else-if="near"
83             ref="image"
84             class="story__media"
85             :src="slide.preview"
86             @load="isImageReady = true"
87             @error="isImageReady = true" />
88
89        <div class="story__spinner" :class="{'story__spinner--shown': active && isSpinner}"></div>
90        <div v-if="active && isVideoBlocked" class="story__play"></div>
91
92        <div class="story__header">
93            <div class="story__shadow"></div>
94            <div class="story__close" @click="$emit('close')"></div>
95            <story-timeline ref="timeline" :count="slides.length" :current="slideIndex" />
96        </div>
97
98        <div v-if="slide.actions && slide.actions.length"
99             class="story__actions">
100            <story-action v-for="(action, i) in slide.actions"
101                          :key="i"
102                          :action="action"
103                          :compact="slide.actions.length > 1"
104                          @action="handleAction" />
105        </div>
106    </div>
107    `};app.storiesBlurComponent={props:['media'],watch:{media(){this.update()},},mounted(){this.layer=null;this.token=null;this.update()}
107,methods:{update(){const media=this.media&&this.media.el;if(!media)return;const token={};this.token=token;if(media.tagName==='VIDEO'){let isDrawn=!1;const draw=()=>{if(isDrawn||media.readyState<2)return;isDrawn=!0;const canvas=document.createElement('canvas');canvas.width=72;canvas.height=128;canvas.getContext('2d').drawImage(media,0,0,canvas.width,canvas.height);this.show(canvas,token)};if(media.readyState>=2){draw()}else{media.addEventListener('loadeddata',draw,{once:!0});media.addEventListener('playing',draw,{once:!0})}
108return}
109const img=new Image();img.onload=()=>this.show(img,token);img.src=media.src},show(layer,token){if(this.token!==token||!this.$el)return;layer.className='storiesBlur__layer';this.$el.appendChild(layer);const old=this.layer;this.layer=layer;void layer.offsetWidth;layer.classList.add('storiesBlur__layer--shown');if(old){setTimeout(()=>old.remove(),600)}},},template:`<div class="storiesBlur"></div>`};app.storiesViewerComponent={components:{'story':app.storyComponent,'stories-blur':app.storiesBlurComponent,},props:['stories','active'],data(){return{current:Math.max(0,this.stories.findIndex(story=>story.id===this.active)),isMobile:window.innerWidth<=700,isVisible:!1,width:0,dragX:0,dragY:0,isDragging:!1,isHeld:!1,isDialog:!1,isClosing:!1,isHidden:document.hidden,isBlurred:!1,activeMedia:null,isFirstSlide:!0,isLastSlide:!0,}},computed:{isPlaying(){return!this.isHeld&&!this.isDragging&&!this.isDialog&&!this.isClosing&&!this.isHidden&&!this.isBlurred},isFirstStory(){return this.current===0},isLastStory(){return this.current===this.stories.length-1},isPrevDisabled(){return this.isFirstStory&&this.isFirstSlide},isNextDisabled(){return this.isLastStory&&this.isLastSlide},trackStyle(){return{transform:`translateY(${this.dragY}px)`}},bgStyle(){if(this.isClosing){return{opacity:0}
109}
110const isEdge=(this.isFirstStory&&this.dragX>0)||(this.isLastStory&&this.dragX<0);const edgePull=isEdge?Math.abs(this.dragX)/(this.width/4):0;return{opacity:1-Math.min(this.dragY/160+edgePull,1)}},},mounted(){document.body.appendChild(this.$el);this.holdTimer=0;this.pointer=null;this.measure();window.addEventListener('resize',this.measure);window.addEventListener('keydown',this.onKeyDown);window.addEventListener('blur',this.onWindowBlur);window.addEventListener('focus',this.onWindowFocus);document.addEventListener('visibilitychange',this.onVisibilityChange);setTimeout(()=>{this.isVisible=!0},this.isMobile?0:200)},beforeDestroy(){clearTimeout(this.holdTimer);window.removeEventListener('resize',this.measure);window.removeEventListener('keydown',this.onKeyDown);window.removeEventListener('blur',this.onWindowBlur);window.removeEventListener('focus',this.onWindowFocus);document.removeEventListener('visibilitychange',this.onVisibilityChange)},methods:{isNear(index){return Math.abs(index-this.current)<=1},storyStyle(index){const offset=this.dragX/this.width*100||0;const isCurrent=index===this.current;const depth=isCurrent?0:95-Math.abs(offset);const shiftX=100*(index-this.current)*(1+depth/2000);return{transform:`translateX(${shiftX + offset}%) translateZ(${-depth}px)`,zIndex:isCurrent?3:2,}},activeStory(){const ref=this.$refs['story'+this.current];return Array.isArray(ref)?ref[0]:ref},measure(){this.width=this.$refs.stage.clientWidth},analytics(event){PubSub.publish('sendAnalytics',{type:'story',event:event,payload:{storyId:this.stories[this.current].id,slideIndex:0,},})},onClose(){if(this.isClosing)return;this.isClosing=!0;this.$emit('close');this.analytics('close')},goTo(index){if(index<0||index>=this.stories.length){this.onClose();return}
111this.current=index;this.analytics('slide')},onSlide(slide){this.activeMedia=slide.media;this.isFirstSlide=slide.isFirst;this.isLastSlide=slide.isLast},nextSlide(){const story=this.activeStory();story&&story.next()},prevSlide(){const story=this.activeStory();story&&story.prev()},onKeyDown(e){if(this.isDialog)return;if(e.key==='Escape')this.onClose();if(e.key==='ArrowRight')this.nextSlide();if(e.key==='ArrowLeft')this.prevSlide();},onVisibilityChange(){this.isHidden=document.hidden},onWindowBlur(){this.isBlurred=!0},onWindowFocus(){this.isBlurred=!1},onPointerDown(e){if(this.isDialog||e.target.closest('.story__close, .story__actions'))return;e.preventDefault();this.pointer={x:e.clientX,y:e.clientY,t:performance.now(),axis:null};this.$refs.stage.setPointerCapture(e.pointerId);this.holdTimer=setTimeout(()=>{this.isHeld=!0},200)},onPointerMove(e){const pointer=this.pointer;if(!pointer)return;const dx=e.clientX-pointer.x;const dy=e.clientY-pointer.y;if(!pointer.axis){if(Math.hypot(dx,dy)<10)return;pointer.axis=Math.abs(dx)>Math.abs(dy)||!this.isMobile?'x':'y';clearTimeout(this.holdTimer);this.isHeld=!1;this.isDragging=!0}
112if(pointer.axis==='y'){this.dragY=Math.max(dy,0);return}
113const isEdge=(this.isFirstStory&&dx>0)||(this.isLastStory&&dx<0);const limit=this.width/4;this.dragX=isEdge?Math.sign(dx)*limit*Math.abs(dx)/(Math.abs(dx)+2*limit):Math.max(-this.width,Math.min(this.width,dx))},onPointerUp(e){const pointer=this.pointer;if(!pointer)return;clearTimeout(this.holdTimer);this.pointer=null;if(!pointer.axis){if(this.isHeld){this.isHeld=!1;return}
114if(e.type==='pointerup'){const rect=this.$refs.stage.getBoundingClientRect();const story=this.activeStory();story&&story.tap((e.clientX-rect.left)/rect.width)}
115return}
116const time=performance.now()-pointer.t;const velocityX=(e.clientX-pointer.x)/time;const velocityY=(e.clientY-pointer.y)/time;const shift=this.dragX/this.width;const isAtEdge=(this.isFirstStory&&shift>0)||(this.isLastStory&&shift<0);const dragY=this.dragY;this.isDragging=!1;this.dragX=0;if(pointer.axis==='y'){if(dragY>120||velocityY>0.6){this.dragY=window.innerHeight;this.onClose()}else{this.dragY=0}}else if(isAtEdge){if(Math.abs(velocityX)>0.4||Math.abs(e.clientX-pointer.x)>this.width/2){this.dragX=Math.sign(shift)*this.width;this.onClose()}}else if(shift<-0.25||(velocityX<-0.4&&shift<0)){this.goTo(this.current+1)}else if(shift>0.25||(velocityX>0.4&&shift>0)){this.goTo(this.current-1)}},},template:`
117    <div class="storiesViewer"
118         :class="{
119            'storiesViewer--visible': isVisible,
120            'storiesViewer--dragging': isDragging,
121         }">
122        <div class="storiesViewer__bg" :style="bgStyle"></div>
123        <stories-blur v-if="!isMobile" :media="activeMedia" />
124
125        <div class="stories__arrow stories__arrow--left"
126             :class="{'stories__arrow--disabled': isPrevDisabled}"
127             @click="!isPrevDisabled && prevSlide()">
128            <svg width="15" height="24" viewBox="0 0 15 24" fill="none" xmlns="http://www.w3.org/2000/svg">
129                <path d="M13 2L3 12L13 22" stroke="currentColor" stroke-width="3" stroke-linecap="round"/>
130            </svg>
131        </div>
132
133        <div ref="stage"
134             class="storiesViewer__stage"
135             @pointerdown="onPointerDown"
136             @pointermove="onPointerMove"
137             @pointerup="onPointerUp"
138             @pointercancel="onPointerUp">
139            <div class="storiesViewer__track" :style="trackStyle">
140                <story v-for="(story, index) in stories"
141                       :key="story.id"
142                       :ref="'story' + index"
143                       :style="storyStyle(index)"
144                       :story="story"
145                       :near="isNear(index)"
146                       :active="index === current"
147                       :playing="isPlaying"
148                       :held="isHeld && index === current"
149                       @next="goTo(current + 1)"
150                       @prev="goTo(current - 1)"
151                       @close="onClose"
152                       @dialog="isDialog = $event"
153                       @slide="onSlide" />
154            </div>
155        </div>
156
157        <div class="stories__arrow stories__arrow--right"
158             :class="{'stories__arrow--disabled': isNextDisabled}"
159             @click="!isNextDisabled && nextSlide()">
160            <svg width="15" height="24" viewBox="0 0 15 24" fill="none" xmlns="http://www.w3.org/2000/svg">
161                <path d="M13 2L3 12L13 22" stroke="currentColor" stroke-width="3" stroke-linecap="round"/>
162            </svg>
163        </div>
164    </div>
165    `,};app.gameViewerComponent={components:{spinner:app.commonSpinnerComponent,},props:{slug:{type:String,required:!0},loc:{type:Object,default:()=>({})},onAuthRequired:{type:Function,default:null},locale:{type:String,default:''},iframeBase:{type:String,default:''},companyId:{type:[String,Number],default:''},},data(){return{protocol:'foodpicasso.game',msgVersion:'1',state:'loading',session:null,errorMsg:'',errorCode:'',retryAtText:'',iframeReady:!1,finishing:!1,}},computed:{encodedSlug(){return encodeURIComponent(this.slug)},iframeSrc(){const path='games/'+this.encodedSlug+'?v=1.0.0'+(this.companyId?'&company='+this.companyId:'');if(!this.iframeBase){return'/'+path}
166const base=this.iframeBase.slice(-1)==='/'?this.iframeBase:this.iframeBase+'/';return base+path},iframeTitle(){return this.locValue('profile/games/iframe/title','Game')},resolvedLocale(){return this.locale||document.documentElement.lang||'ru'},iframeOrigin(){return this.iframeBase?'*':window.location.origin},isLoading(){return this.state==='loading'},isError(){return this.state==='error'},isAuthRequired(){return this.errorCode==='auth_required'},showIframe(){return this.state==='ready'||this.state==='playing'},authTitle(){return this.locValue('profile/games/auth/title','Sign in to play')},authText(){return this.locValue('profile/games/auth/text','Sign in to spin the wheel and claim prizes')},authButton(){return this.locValue('profile/games/auth/button','Sign in')},},mounted(){this.startSession();window.addEventListener('message',this.onMessage)},beforeDestroy(){window.removeEventListener('message',this.onMessage)},methods:{signIn(){if(this.onAuthRequired){this.onAuthRequired(()=>this.startSession())}},startSession(){this.state='loading';this.session=null;this.errorMsg='';this.errorCode='';this.retryAtText='';this.iframeReady=!1;this.finishing=!1;app.fetch('/games/'+this.encodedSlug+'/start',{},(res)=>{if(res.error||(res.code&&res.code!=='attempt_denied')){this.state='error';this.errorCode=res.code||'';this.retryAtText=res.retryAtText||'';this.errorMsg=this.errorMessage(res,'start');return}
167this.session=res;this.state='ready';this.onIframeLoad()})},refreshSession(){app.fetch('/games/'+this.encodedSlug+'/start',{},(res)=>{if(res.error||(res.code&&res.code!=='attempt_denied')){this.state='error';this.errorCode=res.code||'';this.retryAtText=res.retryAtText||'';this.errorMsg=this.errorMessage(res,'start');return}
168this.session=res;this.sendToIframe('game:init',{config:res.config||{},prizes:res.prizes||[],sessionId:res.sessionId,locale:this.resolvedLocale,loc:this.gameLabels(),runtimeVersion:'1.0.0',sdkVersion:'sdk@1',})})},onIframeLoad(){if(!this.session||!this.iframeReady){return}
169this.sendToIframe('game:init',{config:this.session.config||{},prizes:this.session.prizes||[],sessionId:this.session.sessionId,locale:document.documentElement.lang||'ru',loc:this.gameLabels(),runtimeVersion:'1.0.0',sdkVersion:'sdk@1',});this.state='playing'},onMessage(event){const iframe=this.$refs.gameIframe;if(!iframe||event.source!==iframe.contentWindow){return}
170const data=event.data;if(!data||data.protocol!==this.protocol||data.version!==this.msgVersion){return}
171if(data.type==='game:ready'){this.iframeReady=!0;this.onIframeLoad()}else if(data.type==='game:finish'){this.finishSession(data.payload?data.payload.prizeId:null)}else if(data.type==='game:retry'){this.refreshSession()}else if(data.type==='game:error'&&data.payload&&data.payload.fatal){this.state='error';this.errorMsg=data.payload.message||this.locValue('profile/games/error/generic','Game error')}},finishSession(prizeId){if(!this.session||this.finishing){return}
172this.finishing=!0;app.fetch('/games/session/'+this.session.sessionId+'/finish',{prizeId:prizeId!==undefined?prizeId:null},(res)=>{if(res.error||res.code){this.state='error';this.errorMsg=this.errorMessage(res,'finish');this.finishing=!1;return}
173this.sendToIframe('game:result',res);this.finishing=!1})},errorMessage(res,action){const code=res?res.code:null;const messages={attempt_denied:this.attemptDeniedMessage(res),game_not_found:this.locValue('profile/games/error/gameNotFound','Game is unavailable'),session_expired:this.locValue('profile/games/error/sessionExpired','Game session expired'),session_not_found:this.locValue('profile/games/error/sessionNotFound','Game session not found'),invalid_prize:this.locValue('profile/games/error/invalidPrize','Prize is unavailable'),prize_exhausted:this.locValue('profile/games/error/prizeExhausted','Prize is no longer available'),};return messages[code]||this.locValue('profile/games/error/'+action,'')||(res&&res.message?res.message:'')||this.locValue('profile/games/error/generic','Game error')},attemptDeniedMessage(res){if(res&&res.retryAtText){return this.locValue('profile/games/error/attemptDenied/messageWithTime','No attempts left today. New attempts will be available at {time}.').replace('{time}',res.retryAtText)}
174return this.locValue('profile/games/error/attemptDenied/messageLater','No attempts left today. Please come back later.')},gameLabels(){return{title:this.locValue('profile/games/wheelOfFortune/title','Wheel of fortune'),spin:this.locValue('profile/games/wheelOfFortune/spin','Spin'),retry:this.locValue('profile/games/wheelOfFortune/retry','Try again'),prizeFallback:this.locValue('profile/games/wheelOfFortune/prizeFallback','Prize'),noPrizes:this.locValue('profile/games/wheelOfFortune/noPrizes','No prizes available'),}},locValue(key,fallback){return this.loc&&this.loc[key]?this.loc[key]:fallback},sendToIframe(type,payload){const iframe=this.$refs.gameIframe;if(!iframe||!iframe.contentWindow){return}
175iframe.contentWindow.postMessage({protocol:this.protocol,version:this.msgVersion,type:type,id:this.uuid(),payload:payload},this.iframeOrigin)},uuid(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,(c)=>{const r=(Math.random()*16)|0;return(c==='x'?r:(r&0x3)|0x8).toString(16)})},},template:`
176        <div class="gameViewer" v-cloak>
177            <div class="gameViewer__grab"></div>
178            <div v-if="isLoading" class="gameViewer__loader">
179                <spinner/>
180            </div>
181            <div v-else-if="isError" class="gameViewer__error">
182                <div v-if="isAuthRequired" class="gameViewerAuth">
183                    <div class="gameViewerAuth__icon">
184                        <svg viewBox="0 0 24 24" aria-hidden="true">
185                            <circle cx="12" cy="8" r="4" fill="none" stroke="currentColor" stroke-width="1.8"></circle>
186                            <path d="M4 20c0-3.6 3.6-6 8-6s8 2.4 8 6" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path>
187                        </svg>
188                    </div>
189                    <div class="gameViewerAuth__title">{{ authTitle }}</div>
190                    <div class="gameViewerAuth__text">{{ authText }}</div>
191                    <button type="button" class="gameViewerAuth__btn" @click="sign
191In">{{ authButton }}</button>
192                </div>
193                <p v-else>{{ errorMsg }}</p>
194            </div>
195            <iframe v-if="showIframe"
196                    ref="gameIframe"
197                    :src="iframeSrc"
198                    sandbox="allow-scripts allow-same-origin"
199                    referrerpolicy="no-referrer"
200                    loading="eager"
201                    class="gameViewer__iframe"
202                    :title="iframeTitle"></iframe>
203        </div>
204    `,};app.addModule(function(){const showGameViewer=function(params){const slug=params&&params.slug;if(!slug){return}
205const encodedSlug=encodeURIComponent(slug);app.openViewer({desktop:{maxWidth:'400px',borderRadius:'32px',overflow:'hidden',bgClose:!0,},mobile:{maxHeight:'90dvh',withTick:!0,},url:`${window.location.pathname}${window.location.search}#game-${encodedSlug}`,component:app.gameViewerComponent,props:{slug:slug,loc:(app.store&&app.store.state)?app.store.state.loc:{},iframeBase:'',companyId:'',onAuthRequired:function(retry){PubSub.publish('showAuth',{cb:function(){retry()},})},},})};PubSub.subscribe('showGameViewer',function(e,params){showGameViewer(params)})});app.storiesItemComponent={components:{'lazyVideo':app.commonVideoComponent},props:['story'],computed:{isVideo(){return this.story.photo.type==='video'}},methods:{onClick(){this.$emit('click')},},template:`
206    <div class="stories__card" @click=onClick>
207         <div class="stories__cardWrap lazyload__wrap">
208             <template v-if="isVideo">
209                  <lazyVideo :src="story.photo.preview"
210                              root-margin="300px 200px"
211                              loaded-class="stories__video--loaded"
212                              video-class="stories__cardImg"
213                              :muted="true"
214                              :loop="true"
215                              :playsinline="true">
216                  </lazyVideo>
217              </template>
218             <img class="stories__cardImg lazyload"
219                  :data-lowsrc="story.photo.low"
220                  :data-src="story.photo.high" />
221         </div>
222    </div>
223    `};app.promoStoriesComponent={components:{'story':app.storiesItemComponent,'stories-viewer':app.storiesViewerComponent,},props:['promos','isPresentation','syncHash'],data(){return{isShowViewer:!1,activeStoryId:null,isMobile:window.innerWidth<=700,isDragged:!1,}},computed:{stories(){return this.promos||[]},isMany(){return this.stories.length>(this.isMobile?3:4)},isScrollable(){return this.isMobile?this.isMany:this.isMany&&this.isPresentation},isMouseDraggable(){return this.isMany&&!this.isMobile},},mounted(){this.drag=null;window.addEventListener('resize',this.onResize);
223if(this.syncHash){const story=this.stories.find(story=>`#promo${story.id}`===window.location.hash);story&&this.handleClickStory(story.id)}
224if(this.isMouseDraggable){this.initObserve()}},beforeDestroy(){window.removeEventListener('resize',this.onResize);this.observer&&this.observer.disconnect()},methods:{onResize(){this.isMobile=window.innerWidth<=700},handleClickStory(id){if(this.isDragged)return;const story=this.stories.find(story=>story.id===id);if(story&&story.gameSlug){PubSub.publish('showGameViewer',{slug:story.gameSlug});return}
225this.activeStoryId=id;this.isShowViewer=!0;if(this.syncHash){this.previousURL=window.location.pathname+window.location.search;history.replaceState(null,'',`${this.previousURL}#promo${id}`)}
226PubSub.publish('sendAnalytics',{type:'story',event:'open',payload:{storyId:id,slideIndex:0,},})},onClose(){this.isShowViewer=!1;if(this.syncHash){history.replaceState(null,'',this.previousURL)}},initObserve(){this.observer=new IntersectionObserver((entries)=>{entries.forEach((entry)=>{const position=entry.target===this.$refs.beforeEl?'Left':'Right';this.$el.classList.toggle('stories__shadow'+position,!entry.isIntersecting)})},{root:null,rootMargin:'0px 2px 0px 0px',threshold:1,});[this.$refs.beforeEl,this.$refs.afterEl].forEach((el)=>this.observer.observe(el))},onPointerDown(e){this.isDragged=!1;if(!this.isMouseDraggable||e.pointerType!=='mouse')return;this.drag={x:e.clientX,scrollLeft:this.$refs.storiesWrap.scrollLeft,pointerId:e.pointerId}},onPointerMove(e){const drag=this.drag;if(!drag)return;const dx=e.clientX-drag.x;if(!this.isDragged&&Math.abs(dx)>5){this.isDragged=!0;this.$refs.storiesWrap.setPointerCapture(drag.pointerId)}
227if(this.isDragged){this.$refs.storiesWrap.scrollLeft=drag.scrollLeft-dx}},onPointerUp(){this.drag=null},scrollByCard(direction){const card=this.$refs.storiesWrap.querySelector('.stories__card');if(!card)return;this.$refs.storiesWrap.scrollBy({left:direction*(card.offsetWidth+20),behavior:'smooth'})},},template:`
228        <div v-if="stories.length"
229             class="stories"
230             :class="{'stories--many': isScrollable}">
231
232            <div class="stories__shadow"></div>
233            <div class="stories__before"></div>
234            <div class="stories__wrapArrow stories__wrapArrow--left" @click="scrollByCard(-1)"></div>
235            <div class="stories__wrapper"
236                 ref="storiesWrap"
237                 @pointerdown="onPointerDown"
238                 @pointermove="onPointerMove"
239                 @pointerup="onPointerUp"
240                 @pointercancel="onPointerUp">
241                <div key="before"
242                     ref="beforeEl"
243                     class="stories__card--hide"></div>
244                <story v-for="story in stories"
245                       :key="story.id"
246                       :story="story"
247                       @click="handleClickStory(story.id)" />
248                <div key="after"
249                     ref="afterEl"
250                     class="stories__card--hide"></div>
251            </div>
252            <div class="stories__wrapArrow stories__wrapArrow--right" @click="scrollByCard(1)"></div>
253            <div class="stories__after"></div>
254            <div class="stories__shadow"></div>
255
256            <transition name="fade">
257                <stories-viewer v-if="isShowViewer"
258                                :active="activeStoryId"
259                                :stories="stories"
260                                @close="onClose" />
261            </transition>
262        </div>
263    `,};app.addModule(()=>{const promoEl=document.getElementById('promoStories__module');if(!promoEl){return}
264const store=JSON.parse(promoEl.dataset.store);new Vue({components:{'promo-stories':app.promoStoriesComponent,},data(){return{promos:store.promos,isPresentation:store.template==='presentation',}},template:`
265            <promo-stories :promos="promos"
266                           :is-presentation="isPresentation"
267                           :sync-hash="true" />
268        `,store:app.store,}).$mount('#promoStories__module')});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.