PageSourceSearch

https://iampho.ru/var/cache/asset20_cf2fdc646aad7c5035ccacd1399677c5.js

js iampho.ru collected 2026-10-07 18:09:52 UTC 18,271 bytes, 194 lines download raw bytes

1app.scrollOverlapComponent={props:{value:{type:Object,default:function(){return{top:!1,bottom:!1}}}},data:function(){return{state:{top:!1,bottom:!1}}},mounted:function(){var self=this;var root=this.$refs.container;var emit=function(){self.$emit('input',{top:self.state.top,bottom:self.state.bottom})};this._topObserver=new IntersectionObserver(function(entries){self.state.top=entries[0].intersectionRatio<1;emit()},{root:root,threshold:1});this._bottomObserver=new IntersectionObserver(function(entries){self.state.bottom=entries[0].intersectionRatio<1;emit()},{root:root,threshold:1});this._topObserver.observe(this.$refs.top);this._bottomObserver.observe(this.$refs.bottom)},beforeDestroy:function(){if(this._topObserver)this._topObserver.disconnect();if(this._bottomObserver)this._bottomObserver.disconnect();},template:`
2    <div ref="container" class="scrollOverlap">
3        <div ref="top" class="scrollOverlap__edge scrollOverlap__edge--top"></div>
4        <slot></slot>
5        <div ref="bottom" class="scrollOverlap__edge scrollOverlap__edge--bottom"></div>
6    </div>
7    `};app.comboPartComponent={props:['section','selected'],computed:Object.assign({selectedDish:function(){if(!this.selected){return null}
8var options=this.section.options||[];for(var i=0;i<options.length;i++){if(options[i].id===this.selected.dishId){return options[i]}}
9return null},image:function(){var dish=this.selectedDish||(this.section.options&&this.section.options[0]);if(!dish){return null}
10var img=dish.image||(dish.media&&dish.media[0]);if(!img){return null}
11return img.preview||img.full||img.low||null},title:function(){if(this.selected){return this.selected.dishName}
12var match=this.section.title.match(/(.*)\s*\(.*\)/);return match?match[1].trim():this.section.title},sub:function(){if(this.selectedDish){return this.selectedDish.ingredients||null}
13var match=this.section.title.match(/\((.*)\)/);return match?match[1]:null},dishesCount:function(){return(this.section.options||[]).length},actionText:function(){return this.selected?(this.loc['btn/replace']||'Replace'):(this.loc['btn/choose']||'Choose')}},Vuex.mapState(['loc'])),template:`
14    <div class="comboPart" @click="$emit('open')">
15
16        <div class="comboPart__media">
17            <img v-if="image" :src="image" class="comboPart__img" alt="">
18            <div v-else class="comboPart__stub">
19                <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="1.5">
20                    <rect x="3" y="3" width="18" height="18" rx="2"/>
21                    <circle cx="8.5" cy="8.5" r="1.5"/>
22                    <path d="M21 15l-5-5L5 21"/>
23                </svg>
24            </div>
25        </div>
26
27        <div class="comboPart__body">
28            <div class="comboPart__info">
29                <div class="comboPart__title">{{ title }}</div>
30                <div v-if="sub" class="comboPart__sub">{{ sub }}</div>
31            </div>
32
33            <div class="comboPart__action" :class="{'comboPart__action--selected': selected}">
34                {{ actionText }}
35                <span class="comboPart__count">&middot; {{ dishesCount }}</span>
36                <svg class="comboPart__arrow" width="7" height="11" viewB
36ox="0 0 7 11" fill="none">
37                    <path d="M1 10L5.5 5.5L1 1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
38                </svg>
39            </div>
40        </div>
41
42        <transition name="comboPartCheck">
43            <svg v-if="selected" class="comboPart__check" width="20" height="20" viewBox="0 0 20 20" fill="none">
44                <circle cx="10" cy="10" r="10" fill="#34C759"/>
45                <path d="M6 10.5L8.5 13L14 7" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
46            </svg>
47        </transition>
48
49    </div>
50    `};app.comboAlternativesComponent={components:{'scroll-overlap':app.scrollOverlapComponent,},props:['section','currentDishId'],data:function(){return{overlap:{top:!1,bottom:!1}}},computed:Object.assign({dishes:function(){return this.section.options||[]}},Vuex.mapState(['loc'])),methods:{imgSrc:function(dish){var img=dish.image||(dish.media&&dish.media[0]);if(!img){return'/assets/company2/menu/i/bg.png'}
51return img.preview||img.full||img.low||'/assets/company2/menu/i/bg.png'},getModifiers:function(dish){var dishModifiers=dish.modifiers||[];var sectionModifiers=this.section.modifiers||[];if(dishModifiers.length<2){return dishModifiers.concat(sectionModifiers)}
52return dishModifiers},selectDish:function(dish){if(!dish.comboPos){this.$emit('topping',{dish:dish,modifiers:this.getModifiers(dish)});return}
53this.$emit('select',app.buildComboSelection(dish))},locButton:function(dish){if(this.currentDishId===dish.id){return this.loc['btn/selected']||'Selected'}
54return this.loc['btn/choose']||'Choose'},isActive:function(dish){return this.currentDishId===dish.id}},template:`
55    <div class="comboSection"
56         :class="{
57            'comboSection--overlapTop': overlap.top,
58            'comboSection--overlapBottom': overlap.bottom
59         }">
60        <scroll-overlap v-model="overlap" class="comboSection__scroll">
61            <div class="comboSection__grid">
62                <div v-for="dish in dishes"
63                     :key="dish.id"
64                     class="comboSection__dish"
65                     :class="{'comboSection__dish--active': isActive(dish)}"
66                     @click="selectDish(dish)">
67
68                    <div class="comboSection__image">
69                        <img :src="imgSrc(dish)"
70                             alt=""
71                             loading="lazy"
72                             class="comboSection__img">
73                    </div>
74
75                    <div class="comboSection__info">
76                        <div>
77                            <div class="comboSection__name">{{ dish.name }}</div>
78                            <div v-if="dish.ingredients" class="comboSection__ingredients">{{ dish.ingredients }}</div>
79                        </div>
80
81                        <button class="comboSection__btn"
82                                :class="{'comboSection__btn--active': isActive(dish)}"
83                                @click.stop="selectDish(dish)">
84                            <svg v-if="isActive(dish)" class="comboSection__btnCheck" width="13" height="11" viewB
84ox="0 0 13 11" fill="none">
85                                <path d="M1 5.5L4.5 9L12 1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
86                            </svg>
87                            {{ locButton(dish) }}
88                        </button>
89                    </div>
90
91                </div>
92            </div>
93        </scroll-overlap>
94    </div>
95    `};app.comboViewPartsComponent={components:{'tp-shell':app.tpShellComponent,'combo-part':app.comboPartComponent,},props:['dish','comboSections','comboSelected','modifiers','comboTotalFormatted','allComboPicked'],computed:Vuex.mapState(['loc']),template:`
96    <div class="combo__view">
97        <tp-shell :dish="dish" :allModifiers="modifiers" :recalc="function(){}" :callWaiter="function(){}">
98            <template #content>
99                <div class="combo__sections">
100                    <combo-part
101                        v-for="(section, idx) in comboSections"
102                        :key="section.id"
103                        :section="section"
104                        :selected="comboSelected[idx]"
105                        @open="$emit('open-section', idx)"/>
106                </div>
107            </template>
108            <template #submit>
109                <div class="tsubmit">
110                    <div class="tsubmit__buttons">
111                        <div class="tsubmit__button" :class="{'tsubmit__button--disabled': !allComboPicked}" @click="$emit('submit')">
112                            <div class="tsubmit__text">{{ loc['topping/add'] }}</div>
113                            <svg class="tsubmit__delimiter" width="2" height="20" viewBox="0 0 2 20" fill="none" xmlns="http://www.w3.org/2000/svg">
114                                <line x1="0.865723" y1="0.590576" x2="0.865722" y2="18.5906" stroke="currentColor" stroke-linecap="round" stroke-dasharray="1 4"/>
115                            </svg>
116                            <div class="tsubmit__total">{{ comboTotalFormatted }}</div>
117                        </div>
118                    </div>
119                </div>
120            </template>
121        </tp-shell>
122    </div>
123    `};app.buildComboSelection=function(dish){return{dishId:dish.id,dishPos:dish.comboPos,dishName:dish.name,dishTotal:dish.priceRaw||0,}};var findPreselectedOption=function(section){if(!section.preselectedDishId){return null}
124var options=section.options||[];for(var i=0;i<options.length;i++){if(options[i].id===section.preselectedDishId&&options[i].comboPos){return options[i]}}
125return null};var buildState=function(params){var modifiers=params.modifiers||[];var sizes=modifiers[0]||{options:[],selected:0};if(sizes.selected===undefined){sizes.selected=0}
126var comboSections=[];for(var i=1;i<modifiers.length;i++){if(modifiers[i].type==='combo'){comboSections.push(modifiers[i])}}
127var comboSelected=new Array(comboSections.length).fill(null);for(var p=0;p<comboSections.length;p++){var option=findPreselectedOption(comboSections[p]);if(option){comboSelected[p]=app.buildComboSelection(option)}}
128var preselected=params.dish.combo&&params.dish.combo.selected;if(preselected){for(var s=0;s<preselected.length&&s<comboSections.length;s++){if(preselected[s]){comboSelected[s]=preselected[s]}}}
129return{dish:params.dish,modifiers:modifiers,sizes:sizes,comboSections:comboSections,comboSelected:comboSelected,comboView:'parts',comboSectionIdx:null,comboSubDish:null,forceAddress:params.forceAddress,forceRemoveDish:params.forceRemoveDish,subDishKey:0,}};var buildSubSelection=function(comboSubDish,dishPosId){var mods=comboSubDish.modifiers||[];var subSizes=mods[0]||{options:[{pos:0,price:0}],selected:0};var sizeKey=subSizes.selected||0;var sizeOption=subSizes.options&&subSizes.options[sizeKey];var dishTotal=sizeOption?(sizeOption.price||0):0;var modifierNames=[];for(var m=1;m<mods.length;m++){var options=mods[m].options||[];for(var n=0;n<options.length;n++){var opt=options[n];if(opt.count&&typeof opt.price==='number'){dishTotal+=opt.price*opt.count}
130if(opt.count&&opt.name){modifierNames.push(opt.count>1?opt.name+' ×'+opt.count:opt.name)}}}
131var fullName=comboSubDish.dish.name;if(modifierNames.length){fullName+=' + '+modifierNames.join(', ')}
132return{dishId:comboSubDish.dish.id,dishPos:dishPosId,dishName:fullName,dis
132hTotal:dishTotal,}};app.buildComboOrchestratorComponent=function(params){return{components:{'combo-view-parts':app.comboViewPartsComponent,'combo-alternatives':app.comboAlternativesComponent,'tp-shell':app.tpShellComponent,},provide:function(){var mods=params.modifiers||[];var sizes=mods[0]||{options:[{pos:0,price:0}],selected:0};if(sizes.selected===undefined){sizes.selected=0}
133return{store:{isAppearanceTiles:!1,isAppearanceInput:!1,dish:params.dish,sectionId:0,modifiers:mods,forceAddress:params.forceAddress,forceRemoveDish:params.forceRemoveDish},sizes:sizes,modifiers:[],ingredients2:params.dish.ingredients2,nutrients:params.dish.nutrients,loc:this.$store.state.loc,isQuarterActive:!1}},data:function(){return buildState(params)},computed:Object.assign({allComboPicked:function(){for(var i=0;i<this.comboSections.length;i++){if(!this.comboSelected[i]){return!1}}
134return!0},comboTotalFormatted:function(){var sizeKey=this.sizes.selected||0;var sizeOption=this.sizes.options&&this.sizes.options[sizeKey];var basePrice=sizeOption?(sizeOption.price||0):0;var partsPrice=0;for(var j=0;j<this.comboSelected.length;j++){if(this.comboSelected[j]){partsPrice+=this.comboSelected[j].dishTotal||0}}
135var currency=this.company?this.company.currency:'';var separator=this.company?this.company.priceSeparator:'';return app.price.format(basePrice+partsPrice,currency,separator)},sectionTitle:function(){if(this.comboView==='section'&&this.comboSectionIdx!==null){var section=this.comboSections[this.comboSectionIdx];if(section){var match=section.title.match(/(.*)\s*\(.*\)/);return match?match[1].trim():section.title}}
136if(this.comboView==='subTopping'&&this.comboSubDish){return this.comboSubDish.dish.name}
137return''},isDesktopVersion:function(){return this.isKiosk||!this.mobile}},Vuex.mapState(['loc','mobile','isKiosk','company'])),methods:{openSection:function(idx){this.comboSectionIdx=idx;this.comboView='section'},backToParts:function(){this.comboView='parts';this.comboSectionIdx=null;this.comboSubDish=null},onComboSelect:function(idx,selection){this.$set(this.comboSelected,idx,selection);this.backToParts()},onComboTopping:function(idx,payload){var data=JSON.parse(JSON.stringify(payload));data._sectionIdx=idx;this.comboSubDish=data;this.subDishKey++;this.comboView='subTopping'},backToSection:function(){var idx=this.comboSubDish?this.comboSubDish._sectionIdx:null;this.comboSubDish=null;this.comboView='section';if(idx!==null){this.comboSectionIdx=idx}},subToppingRecalc:function(dishPosId){var idx=this.comboSubDish?this.comboSubDish._sectionIdx:null;if(idx!==null){this.$set(this.comboSelected,idx,buildSubSelection(this.comboSubDish,dishPosId))}
138this.backToParts()},comboSubmit:function(){if(!this.allComboPicked){var missing='';for(var i=0;i<this.comboSections.length;i++){if(!this.comboSelected[i]){missing=this.comboSections[i].title.split(' (')[0];break}}
139app.alert((this.loc['topping/warning/comboNotFilled']||'Please select: {section}').replace('{section}',missing),'danger');return}
140if(this.forceAddress){PubSub.publish(this.forceAddress,{forceReload:!0,openDishAfterReload:{id:this.dish.id,name:this.dish.name}});return}
141var sizeKey=this.sizes.selected||0;var comboParts=[];for(var j=0;j<this.comboSelected.length;j++){if(this.comboSelected[j]){comboParts.push(this.comboSelected[j].dishPos)}}
142var dishPosId=this.dish.id+'_'+sizeKey+'#'+comboParts.join('#');PubSub.publish('dishSelected',{dishPosId:dishPosId,count:1,forceRemoveDish:this.forceRemoveDish,});this.$emit('close')},callWaiter:function(){var self=this;setTimeout(function(){PubSub.publish('showWaiter',{action:'call-waiter'})},600);self.$emit('close')}},store:app.store,template:`
143        <div class="combo">
144            <svg xmlns="http://www.w3.org/2000/svg" style="display: none">
145                <symbol id="icon__arrow" viewBox="0 0 9 15" xmlns="http://www.w3.org/2000/svg">
146                    <path d="M7.85501 14.509L9.00001 13.349L2.90601 7.254L9.00001 1.16L7.85501 0L0.600006 7.255L7.85501 14.509Z" fill="currentColor"/>
147                </symbol>
148                <symbol id="tp__pointIcon" width="16" height="14" viewBox="0 0 16 14" fill="none">
149                    <path d="M6.5 1.25C9.67564 1.25 12.25 3.82436 12.25 7C12.25 10.1756 9.67564 12.75 6.5 12.75C3.32436 12.75 0.75 10.1756 0.75 7C0.75 3.82436 3.32436 1.25 6.5 1.25Z" stroke="currentColor" stroke-width="1.5"/>
150                    <path d="M11.0867 13.1664C13.0422 11.7611 14.3164 9.46186 14.3164 6.86393C14.3164 4.22779 13.0044 1.89919 11 0.5C13.7024 1.33499 15.6666 3.86075 15.6666 6.84694C15.6666 9.80109 13.7444 12.3046 11.0867 13.1664Z" fill="currentColor"/>
151                </symbol>
152            </svg>
153            <combo-view-parts
154                v-if="comboView === 'parts'"
155                :dish="dish" :comboSections="comboSections" :comboSelected="comboSelected"
156                :modifiers="modifiers"
157                :comboTotalFormatted="comboTotalFormatted" :allComboPicked="allComboPicked"
158                @open-section="openSection" @submit="comboSubmit"/>
159            <div v-else-if="comboView === 'section'" class="combo__view combo__view--section">
160                <div class="combo__nav">
161                    <button class="combo__back" @click="backToParts">
162                        <svg width="9" height="15" viewBox="0 0 9 15" fill="none">
163                            <path d="M7.855 14.509L9 13.349L2.906 7.254L9 1.16L7.855 0L0.6 7.255L7.855 14.509Z" fill="currentColor"/>
164                        </svg>
165                    </button>
166                    <div class="combo__navTitle">{{ sectionTitle }}</div>
167                </div>
168                <div class="combo__sectionContent">
169                    <combo-alternatives
170                        v-if="comboSections[comboSectionIdx]"
171                        :section="comboSections[comboSectionIdx]"
172                        :currentDishId="comboSelected[comboSectionIdx] ? comboSelected[comboSectionIdx].dishId : null"
173                        @select="onComboSelect(comboSectionIdx, $event)"
174                        @topping="onComboTopping(comboSectionIdx, $event)"/>
175                </div>
176            </div>
177            <div v-else-if="comboView === 'subTopping'" class="combo__view combo__view--subTopping">
178                <button class="combo__backOverlay" @click="backToSection">
179                    <svg width="9" height="15" viewBox="0 0 9 15" fill="none">
180                        <path d="M7.855 14.509L9 13.349L2.906 7.254L9 1.16L7.855 0L0.6 7.255L7.855 14.509Z" fill="currentColor"/>
181                    </svg>
182                </button>
183                <tp-shell
184                    :key="subDishKey"
185                    :dish="comboSubDish.dish"
186                    :allModifiers="comboSubDish.modifiers"
187                    :recalc="subToppingRecalc"
188                    :callWaiter="callWaiter"
189                    :submitText="loc['btn/choose']"
190                    :hideCounter="true"/>
191            </div>
192        </div>
193        `}};app.addModule(function(){var show=function(vrParams){var runVm=function(params){app.openViewer({desktop:{maxWidth:'1050px',disableAutogrow:!0,overflow:'hidden'},mobile:{withTick:!0,withClose:!1,minHeight:'90dvh',maxHeight:'90dvh',backgroundColor:'transparent',},className:'tp__viewer',component:app.buildComboOrchestratorComponent(params),})};if(vrParams.preload){app.fetch('/cart/topping/get',vrParams.preload,function(response){if(response.error){return}
194response.dish.combo={active:!0};runVm(response)})}else{runVm(vrParams)}};PubSub.subscribe('showCombo',function(e,params){show(params);if(params.dish){PubSub.publish('gtmNotify',{event:'view_item',item:params.dish})}})});

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.