- ID de l'analyse :
- 19824cdf-6995-452e-8d86-b83c634921dbTerminée
- URL soumise :
- https://shellshockers.silkandpepper.com/
- Fin du rapport :
Liens : 2 trouvé(s)
Liens sortants identifiés à partir de la page
Lien | texte |
---|---|
https://adinplay.com/privacy-and-cookies-policy/ | Privacy notice |
https://adinplay.com/?utm_source=publishers&utm_medium=cmp |
Variables JavaScript : 323 trouvée(s)
Les variables JavaScript globales chargées dans l'objet fenêtre d'une page sont des variables déclarées en dehors des fonctions et accessibles depuis n'importe quel endroit du code au sein du champ d'application actuel
Nom | Type |
---|---|
0 | object |
1 | object |
2 | object |
3 | object |
4 | object |
5 | object |
6 | object |
7 | object |
8 | object |
onbeforetoggle | object |
Messages de journal de console : 8 trouvé(s)
Messages consignés dans la console web
Type | Catégorie | Enregistrement |
---|---|---|
error | security |
|
error | security |
|
error | security |
|
error | security |
|
log | other |
|
log | other |
|
warning | other |
|
log | other |
|
HTML
Le corps HTML de la page en données brutes
<!DOCTYPE html><html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" class="mdl-js"><head>
<script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/destination?id=AW-662950613&l=dataLayer&cx=c"></script><script type="text/javascript" async="" src="https://static.hotjar.com/c/hotjar-1519513.js?sv=7"></script><script async="" type="text/javascript" src="https://api.adinplay.com/libs/aiptag/assets/adsbygoogle.js"></script><script async="" type="text/javascript" src="https://btloader.com/tag?o=5130683165442048&upapi=true"></script><script async="" type="text/javascript" src="https://securepubads.g.doubleclick.net/tag/js/gpt.js?network-code=421469808"></script><script async="" src="https://c.amazon-adsystem.com/aax2/apstag.js"></script><script src="https://connect.facebook.net/signals/config/446896919250308?v=2.9.174&r=stable&domain=shellshockers.silkandpepper.com&hme=ead923021ccd3483ef3b9b04703d0a78b943fbdc01e8d7cec21c5059f1f4a5e9&ex_m=70%2C121%2C107%2C111%2C61%2C4%2C100%2C69%2C16%2C97%2C89%2C51%2C54%2C172%2C175%2C187%2C183%2C184%2C186%2C29%2C101%2C53%2C77%2C185%2C167%2C170%2C180%2C181%2C188%2C131%2C41%2C189%2C190%2C34%2C143%2C15%2C50%2C194%2C193%2C133%2C18%2C40%2C1%2C43%2C65%2C66%2C67%2C71%2C93%2C17%2C14%2C96%2C92%2C91%2C108%2C52%2C110%2C39%2C109%2C30%2C94%2C26%2C168%2C171%2C140%2C86%2C56%2C84%2C33%2C73%2C0%2C95%2C32%2C28%2C82%2C83%2C88%2C47%2C46%2C87%2C37%2C11%2C12%2C13%2C6%2C7%2C25%2C22%2C23%2C57%2C62%2C64%2C75%2C102%2C27%2C76%2C9%2C8%2C80%2C48%2C21%2C104%2C103%2C105%2C98%2C10%2C20%2C3%2C38%2C74%2C19%2C5%2C90%2C81%2C44%2C35%2C85%2C2%2C36%2C63%2C42%2C106%2C45%2C79%2C68%2C112%2C60%2C59%2C31%2C99%2C58%2C55%2C49%2C78%2C72%2C24%2C113%2C200%2C199%2C201%2C206%2C207%2C208%2C204%2C196%2C132%2C134%2C163%2C195%2C197%2C122%2C157%2C145%2C151%2C129%2C232%2C116%2C126%2C127%2C233%2C165%2C119%2C235%2C166%2C136%2C123%2C154%2C148%2C114%2C128" async=""></script><script src="https://connect.facebook.net/signals/config/771186996377132?v=2.9.174&r=stable&domain=shellshockers.silkandpepper.com&hme=ead923021ccd3483ef3b9b04703d0a78b943fbdc01e8d7cec21c5059f1f4a5e9&ex_m=70%2C121%2C107%2C111%2C61%2C4%2C100%2C69%2C16%2C97%2C89%2C51%2C54%2C172%2C175%2C187%2C183%2C184%2C186%2C29%2C101%2C53%2C77%2C185%2C167%2C170%2C180%2C181%2C188%2C131%2C41%2C189%2C190%2C34%2C143%2C15%2C50%2C194%2C193%2C133%2C18%2C40%2C1%2C43%2C65%2C66%2C67%2C71%2C93%2C17%2C14%2C96%2C92%2C91%2C108%2C52%2C110%2C39%2C109%2C30%2C94%2C26%2C168%2C171%2C140%2C86%2C56%2C84%2C33%2C73%2C0%2C95%2C32%2C28%2C82%2C83%2C88%2C47%2C46%2C87%2C37%2C11%2C12%2C13%2C6%2C7%2C25%2C22%2C23%2C57%2C62%2C64%2C75%2C102%2C27%2C76%2C9%2C8%2C80%2C48%2C21%2C104%2C103%2C105%2C98%2C10%2C20%2C3%2C38%2C74%2C19%2C5%2C90%2C81%2C44%2C35%2C85%2C2%2C36%2C63%2C42%2C106%2C45%2C79%2C68%2C112%2C60%2C59%2C31%2C99%2C58%2C55%2C49%2C78%2C72%2C24%2C113" async=""></script><script async="" src="https://connect.facebook.net/en_US/fbevents.js"></script><script async="" src="https://www.googletagmanager.com/gtm.js?id=GTM-K5MSJHJ"></script><script>
var gameServerRoot = null;
var dynamicContentRoot = null;
var dynamicContentPrefix = '';
</script>
<script>
class Loader {
static show () {
let container = document.createElement('div');
container.id = 'progress-container';
container.style = `
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
z-index: 2000;
background-image: var(--ss-lightoverlay);
`;
const progressWrapper = document.createElement('div');
progressWrapper.id = 'progress-wrapper';
progressWrapper.className = 'load_screen';
progressWrapper.style = `
position: absolute;
left: 50%;
top: -6em;
transform: translateX(-50%);
background-image: none;
`;
const blueWizLogo = document.createElement('img');
blueWizLogo.src = 'img/BlueWizard-Logo-min.png';
blueWizLogo.style=`
width: 16em;
display: block;
margin: 5em auto 0;
z-index: 2000;
position: absolute;
left: 50%;
bottom: 8em;
transform: translateX(-50%);
`;
let logo = document.createElement('img');
logo.src = 'img/logo.svg';
logo.style = 'height: 16em';
logo.id = 'logo-svg';
// container.appendChild(logo);
const progressOuter = document.createElement('div');
progressOuter.id = 'progress-outer';
progressOuter.style = `
position: relative;
background: #643219;
border-radius: 2em;
height: 3.3em;
width: 24em;
margin-top: 2em;
`;
let progress = document.createElement('div');
progress.style = `
margin-top: 1em;
width: 23em;
height: 2.2em;
background: white;
padding: 0.5em;
border-radius: 2em;
margin: .3em .5em 0;
`;
container.appendChild(progress);
let progressBar = document.createElement('span');
progressBar.id = 'progressBar';
progressBar.style = `
display: block;
width: 20%;
height: 100%;
background: orange;
border-radius: 2em;
margin-left: 80%;
margin: 0 .3em .5em 0;
opacity: 0;
transition: margin-left linear 500ms;
transition-timing-function: ease-in-out;
`;
const progressBarOutside = document.createElement('div');
progress.appendChild(progressBar);
progressWrapper.appendChild(logo);
progressOuter.appendChild(progress);
progressWrapper.appendChild(progressOuter);
container.appendChild(progressWrapper);
container.appendChild(blueWizLogo);
// Minor for the progress bar intial load
setTimeout(() => progressBar.style.opacity = 1, 600);
Loader.barInterval = setInterval(() => {
if (Loader.progressBar.style.marginLeft == '0%') {
Loader.progressBar.style.marginLeft = '80%';
}
else {
Loader.progressBar.style.marginLeft = '0%';
}
}, 500);
Loader.progressBar = progressBar;
Loader.container = container;
let app = document.body;
app.appendChild(container);
}
static hide () {
Loader.container.style = "opacity : 0; transition: opacity 1s;";
setTimeout(() => { Loader.container.remove(); }, 1000);
}
static addTask () {
let id = Loader.loaded.length;
//console.log('Loading tasks: ', ++Loader.actualTasks);
Loader.loaded.push(0);
return id;
}
static finish (id) {
clearInterval(Loader.barInterval);
if (Loader.progressBar) {
Loader.progressBar.style.marginLeft = '0%';
Loader.progressBar.style.transition = '';
Loader.loaded[id] = 1;
Loader.updateBar();
}
}
static progress (id, value, total) {
clearInterval(Loader.barInterval);
if (Loader.progressBar) {
Loader.progressBar.style.marginLeft = '0%';
Loader.progressBar.style.transition = '';
Loader.loaded[id] = value / total;
Loader.updateBar();
}
return id;
}
static updateBar () {
let loadedTotal = 0;
for (let l of Loader.loaded) {
loadedTotal += l;
}
Loader.progressBar.style.width = loadedTotal / Loader.tasks * 95 + 5 + '%';
}
static loadJS (path, callback) {
let p = path;
(function (p, cb) {
let xhr = new XMLHttpRequest();
xhr.open('GET', p, true);
let id = Loader.addTask();
xhr.onprogress = event => {
if (Loader.progressBar) {
id = Loader.progress(id, event.loaded, event.total);
}
};
xhr.onload = () => {
if (xhr.status != 200) {
console.log(`Error ${xhr.status}: ${xhr.statusText}`);
}
else {
Loader.finish(id);
let script = document.createElement('script');
script.innerHTML = xhr.response;
document.body.appendChild(script);
if (cb) cb();
}
};
xhr.send();
})(path, callback);
}
}
Loader.actualTasks = 0;
Loader.tasks = 16;
Loader.loaded = [];
window.Loader = Loader;
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
function openFirebaseDb () {
return new Promise((resolve, reject) => {
let req = window.indexedDB.open('firebaseLocalStorageDb');
req.onsuccess = () => {
let db = req.result;
let transaction = db.transaction(['firebaseLocalStorage'], 'readwrite');
let store = transaction.objectStore('firebaseLocalStorage');
resolve({ db, store });
}
req.onerror = err => reject(err);
req.onupgradeneeded = () => {
let db = req.result;
let store = db.createObjectStore('firebaseLocalStorage', { keyPath: 'fbase_key' });
resolve({ db, store });
}
});
}
var redirectIframe
function postStorageAndRedirect (iframe, storage, firebaseDb) {
iframe.contentWindow.postMessage({ storage, firebaseDb }, '*');
window.location = 'https://shellshock.io' + window.location.search + window.location.hash;
}
window.addEventListener('DOMContentLoaded', () => {
Loader.show();
});
</script><!-- title, seo meta and favicons -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="facebook-domain-verification" content="6lfua33vx0abiv1asnt9p13aac29xy">
<!-- <link rel="manifest" href="manifest.json"> -->
<title>Shell Shockers | Alt URL: geometry.best.</title>
<meta name="Description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs.">
<meta name="Keywords" content="Play, Free, Online, Multiplayer, Games, IO, ShellShockers, Shooter, Bullets, Top Down">
<meta name="author" content="Blue Wizard Digital">
<meta name="theme-color" content="#0B93BD">
<meta name="background-color" content="#0B93BD">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="favicon192.png" sizes="192x192">
<link rel="icon" href="https://shellshock.io/favicon256.png" sizes="512x512">
<meta property="og:url" content="https://www.shellshock.io">
<meta property="og:type" content="website">
<meta property="og:image:width" content="1000">
<meta property="og:image:height" content="500">
<meta property="og:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg">
<meta name="image" property="og:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg">
<meta property="og:title" content="Shell Shockers | by Blue Wizard Digital">
<meta property="og:description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs.">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@eggcombat">
<meta name="twitter:creator" content="@eggcombat">
<meta name="twitter:title" content="Shell Shockers | by Blue Wizard Digital">
<meta name="twitter:description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs.">
<meta name="twitter:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg">
<!-- Styles & Fonts -->
<link href="https://fonts.googleapis.com/css?family=Sigmar+One|Nunito:100,200,600,700,900" rel="stylesheet">
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="styles/transitions.css%3F1651709060.css">
<link rel="stylesheet" href="styles/forms.css%3F1651709060.css">
<link rel="stylesheet" href="styles/style.css%3F1654110505.css">
<link rel="stylesheet" href="styles/game.css%3F1653069567.css"><script>
function storageFactory(getStorage) {
const inMemoryStorage = {};
function isSupported() {
try {
var testKey = "__some_random_key_you_are_not_going_to_use__";
getStorage().setItem(testKey, testKey);
getStorage().removeItem(testKey);
return true;
} catch (e) {
return false;
}
}
function clear() {
if (isSupported()) {
getStorage().clear();
} else {
inMemoryStorage = {};
}
}
function getItem(name) {
if (isSupported()) {
return getStorage().getItem(name);
}
if (inMemoryStorage.hasOwnProperty(name)) {
return inMemoryStorage[name];
}
return null;
}
function key(index) {
if (isSupported()) {
return getStorage().key(index);
} else {
return Object.keys(inMemoryStorage)[index] || null;
}
}
function removeItem(name) {
if (isSupported()) {
getStorage().removeItem(name);
} else {
delete inMemoryStorage[name];
}
}
function setItem(name, value) {
if (isSupported()) {
getStorage().setItem(name, value);
} else {
inMemoryStorage[name] = String(value);
}
}
function length() {
if (isSupported()) {
return getStorage().length;
} else {
return Object.keys(inMemoryStorage).length;
}
}
return {
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
key: key,
get length() {
return length();
}
};
}
const localStore = storageFactory(() => localStorage);
const sessionStore = storageFactory(() => sessionStorage);
</script><style>
.eggIcon {
display: inline-block;
color: #444444;
width: 1em;
height: 1em;
fill: currentColor;
}
</style>
<style>
.crazy-banner-container {
display: flex;
align-items: center;
justify-content: center;
}
</style><script src="https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151606" async=""></script><script async="" type="text/javascript" charset="UTF-8" src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script><meta http-equiv="origin-trial" content="AlK2UR5SkAlj8jjdEc9p3F3xuFYlF6LYjAML3EOqw1g26eCwWPjdmecULvBH5MVPoqKYrOfPhYVL71xAXI1IBQoAAAB8eyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiV2ViVmlld1hSZXF1ZXN0ZWRXaXRoRGVwcmVjYXRpb24iLCJleHBpcnkiOjE3NTgwNjcxOTksImlzU3ViZG9tYWluIjp0cnVlfQ=="><meta http-equiv="origin-trial" content="Amm8/NmvvQfhwCib6I7ZsmUxiSCfOxWxHayJwyU1r3gRIItzr7bNQid6O8ZYaE1GSQTa69WwhPC9flq/oYkRBwsAAACCeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiV2ViVmlld1hSZXF1ZXN0ZWRXaXRoRGVwcmVjYXRpb24iLCJleHBpcnkiOjE3NTgwNjcxOTksImlzU3ViZG9tYWluIjp0cnVlfQ=="><meta http-equiv="origin-trial" content="A9wSqI5i0iwGdf6L1CERNdmsTPgVu44ewj8QxTBYgsv1LCPUVF7YmWOvTappqB1139jAymxUW/RO8zmMqo4zlAAAAACNeyJvcmlnaW4iOiJodHRwczovL2RvdWJsZWNsaWNrLm5ldDo0NDMiLCJmZWF0dXJlIjoiRmxlZGdlQmlkZGluZ0FuZEF1Y3Rpb25TZXJ2ZXIiLCJleHBpcnkiOjE3MzY4MTI4MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><meta http-equiv="origin-trial" content="A+d7vJfYtay4OUbdtRPZA3y7bKQLsxaMEPmxgfhBGqKXNrdkCQeJlUwqa6EBbSfjwFtJWTrWIioXeMW+y8bWAgQAAACTeyJvcmlnaW4iOiJodHRwczovL2dvb2dsZXN5bmRpY2F0aW9uLmNvbTo0NDMiLCJmZWF0dXJlIjoiRmxlZGdlQmlkZGluZ0FuZEF1Y3Rpb25TZXJ2ZXIiLCJleHBpcnkiOjE3MzY4MTI4MDAsImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"><script src="https://securepubads.g.doubleclick.net/pagead/managed/js/gpt/m202410240101/pubads_impl.js?cb=31088436" async=""></script><script src="https://config.aps.amazon-adsystem.com/configs/53b902f9-cf9c-4605-aec3-2c8ce65042b8" type="text/javascript" async="async"></script><script async="" src="https://script.hotjar.com/modules.67d7d905831ab88336d0.js" charset="utf-8"></script><script attributionsrc="" type="text/javascript" async="" src="https://www.googleadservices.com/pagead/conversion/662950613/?random=1730107356692&cv=11&fst=1730107356692&bg=ffffff&guid=ON&async=1&gtm=45be4ao0v894691764z8812812352za201zb812812352&gcd=13l3lPl2l1l1&dma_cps=syphamo&dma=1&tcfd=10001&tag_exp=101533421~101823848&u_w=1&u_h=1&url=https%3A%2F%2Fshellshockers.silkandpepper.com%2F&label=u82gCJTLqdcBENWlj7wC&hn=www.googleadservices.com&frm=0&tiba=Shell%20Shockers%20%7C%20Alt%20URL%3A%20geometry.best.&value=0&bttype=purchase&npa=1&us_privacy=error&pscdl=noapi&auid=1224583539.1730107357&uaa=&uab=&uafvl=&uamb=0&uam=&uap=&uapv=&uaw=0&fdr=SA&rfmt=3&fmt=4"></script><script async="" src="https://fundingchoicesmessages.google.com/i/421469808?ers=3"></script></head><body><div id="cmpbox" class="cmpbox cmpstyleroot cmpbox3 cmpboxWelcomeGDPR cmpBoxWelcomeOI" aria-modal="true" role="dialog" lang="EN" aria-labelledby="cmpboxheadline1" data-nosnippet="" dir="ltr" style="display: block;"><div class="cmpboxinner" role="document"><div id="cmpboxcontent" class="cmpboxcontent"><div class="cmpboxtxtdiv "><div class="cmpboxhl cmptxt_hl" role="heading" aria-level="1" id="cmpboxheadline1">Consent to Cookies & Data processing</div><div class="cmpboxtxt cmptxt_txt">On this website we use cookies and similar functions to process end device information and personal data (e.g. such as IP-addresses or browser information). The processing is used for purposes such as to integrate content, external services and elements from third parties, statistical analysis/measurement, personalized advertising and the integration of social media. Depending on the function, data is passed on to up to <a class="cmplink cmplinkvendors" href="#" draggable="false" data-cmp-vendor="">545 third parties</a> and processed by them. This consent is voluntary, not required for the use of our website and can be revoked at any time using the icon on the bottom left.</div></div><div class="cmpboxwelcomeprps" role="form" title="Purpose"><div class="cmpwelcomeprps"><div class="cmpwelcomeprpsbtn"><a href="#" data-cmp-purpose="1" role="checkbox" aria-checked="false" aria-label="Purpose: Store and/or access information on a device" aria-labelledby="cmppurposelabelp1" draggable="false"><span class="cmptogglespan cmpvnspan-1x1" id="cmpvnspan-1x1"><svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 512 256" class="cmpimgyesno cmptoggle0" aria-label="Store and/or access information on a device" aria-labelledby="cmppurposelabelp1"><g><ellipse ry="111.500004" rx="113" cy="120.89999" cx="386" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></ellipse><rect height="222" width="256.999992" y="9.899994" x="140.000002" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></rect><ellipse ry="111.500004" rx="113" cy="118.399998" cx="125" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></ellipse><g><path d="m477.867004,119.466583c0,-47.053009 -38.281006,-85.333008 -85.333008,-85.333008c-44.168976,0 -80.596985,33.740997 -84.89801,76.800018l-188.168983,0c-4.719002,0 -8.533005,3.822998 -8.533005,8.53299c0,4.709991 3.814003,8.53299 8.533005,8.53299l188.169014,0c4.300995,43.059021 40.72998,76.800018 84.89798,76.800018c47.052002,0.001007 85.333008,-38.279999 85.333008,-85.333008zm-153.600006,0c0,-37.640991 30.626007,-68.266998 68.266998,-68.266998c37.640991,0 68.266998,30.626007 68.266998,68.266998c0,37.640991 -30.626007,68.266998 -68.266998,68.266998c-37.640991,0 -68.266998,-30.625977 -68.266998,-68.266998z" fill="#F64C4E" class="cmpsvgredfill"></path><path d="m412.100006,151.099579c1.664001,1.664001 3.848999,2.5 6.03299,2.5c2.185028,0 4.369019,-0.835999 6.03302,-2.5c3.335999,-3.337006 3.335999,-8.72998 0,-12.06601l-19.567017,-19.566986l19.567017,-19.566986c3.335999,-3.337006 3.335999,-8.730011 0,-12.06601c-3.337006,-3.335999 -8.730011,-3.335999 -12.06601,0l-19.566986,19.566986l-19.567017,-19.566986c-3.337006,-3.335999 -8.730011,-3.335999 -12.06601,0c-3.335999,3.337006 -3.335999,8.730011 0,12.06601l19.567017,19.566986l-19.567017,19.567017c-3.335999,3.337006 -3.335999,8.730011 0,12.06601c1.664001,1.664001 3.848999,2.5 6.03299,2.5c2.184998,0 4.369019,-0.835999 6.03302,-2.5l19.566986,-19.567017l19.567017,19.566986z" fill="#F64C4E" class="cmpsvgredfill"></path><path d="m392.53299,0.00058l-281.600006,0c-0.905006,0 -1.783005,0.162018 -2.611,0.444c-27.196007,0.485992 -52.855003,11.408997 -72.508003,30.916016c-22.76698,22.596008 -35.81398,54.707001 -35.81398,88.105988c0,65.878021 49.765999,119.46701 110.932999,119.46701l247.466995,0c4.718994,0 8.53299,-3.822998 8.53299,-8.53299s-3.813995,-8.53302 -8.53299,-8.53302l-247.466995,0c-51.754997,0 -93.866999,-45.934998 -93.866999,-102.399994c0,-28.88501 11.212999,-56.584991 30.771002,-75.997986c17.125996,-16.998016 38.673,-25.976013 62.353001,-25.976013c0.222,0 0.451996,0.009003 0.682999,0.009003c0.673996,0.026001 1.707001,-0.153992 2.526001,-0.434998l279.134018,0c56.464996,0 102.399994,45.934998 102.399994,102.399994c0,56.464996 -45.934998,102.399994 -102.399994,102.399994c-4.719025,0 -8.53302,3.822998 -8.53302,8.53302s3.813995,8.53299 8.53302,8.53299c65.877991,0 119.46698,-53.588989 119.46698,-119.46701s-53.588989,-119.466003 -119.46701,-119.466003z" fill="#ddd" class="cmpsvgsilver2fill"></path></g></g></svg></span></a></div><div data-cmp-purpose="1" id="cmppurposelabelp1" class="cmpwelcomeprpstxt " draggable="false">Store and/or access information on a device</div></div><div class="cmpwelcomeprps"><div class="cmpwelcomeprpsbtn"><a href="#" draggable="false" aria-label="Purpose: Personalised advertising and content, advertising and content measurement, audience research and services development
" aria-labelledby="cmppurposelabelst42" role="checkbox" aria-checked="false" data-cmp-stack="42"><span class="cmptogglespan cmpvnspan-1xst42" id="cmpvnspan-1xst42"><svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 512 256" class="cmpimgyesno cmptoggle0" aria-label="Personalised advertising and content, advertising and content measurement, audience research and services development
" aria-labelledby="cmppurposelabelst42"><g><ellipse ry="111.500004" rx="113" cy="120.89999" cx="386" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></ellipse><rect height="222" width="256.999992" y="9.899994" x="140.000002" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></rect><ellipse ry="111.500004" rx="113" cy="118.399998" cx="125" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="0" stroke="#000000" fill="#e5e5e5" class="cmpsvgsilverfill"></ellipse><g><path d="m477.867004,119.466583c0,-47.053009 -38.281006,-85.333008 -85.333008,-85.333008c-44.168976,0 -80.596985,33.740997 -84.89801,76.800018l-188.168983,0c-4.719002,0 -8.533005,3.822998 -8.533005,8.53299c0,4.709991 3.814003,8.53299 8.533005,8.53299l188.169014,0c4.300995,43.059021 40.72998,76.800018 84.89798,76.800018c47.052002,0.001007 85.333008,-38.279999 85.333008,-85.333008zm-153.600006,0c0,-37.640991 30.626007,-68.266998 68.266998,-68.266998c37.640991,0 68.266998,30.626007 68.266998,68.266998c0,37.640991 -30.626007,68.266998 -68.266998,68.266998c-37.640991,0 -68.266998,-30.625977 -68.266998,-68.266998z" fill="#F64C4E" class="cmpsvgredfill"></path><path d="m412.100006,151.099579c1.664001,1.664001 3.848999,2.5 6.03299,2.5c2.185028,0 4.369019,-0.835999 6.03302,-2.5c3.335999,-3.337006 3.335999,-8.72998 0,-12.06601l-19.567017,-19.566986l19.567017,-19.566986c3.335999,-3.337006 3.335999,-8.730011 0,-12.06601c-3.337006,-3.335999 -8.730011,-3.335999 -12.06601,0l-19.566986,19.566986l-19.567017,-19.566986c-3.337006,-3.335999 -8.730011,-3.335999 -12.06601,0c-3.335999,3.337006 -3.335999,8.730011 0,12.06601l19.567017,19.566986l-19.567017,19.567017c-3.335999,3.337006 -3.335999,8.730011 0,12.06601c1.664001,1.664001 3.848999,2.5 6.03299,2.5c2.184998,0 4.369019,-0.835999 6.03302,-2.5l19.566986,-19.567017l19.567017,19.566986z" fill="#F64C4E" class="cmpsvgredfill"></path><path d="m392.53299,0.00058l-281.600006,0c-0.905006,0 -1.783005,0.162018 -2.611,0.444c-27.196007,0.485992 -52.855003,11.408997 -72.508003,30.916016c-22.76698,22.596008 -35.81398,54.707001 -35.81398,88.105988c0,65.878021 49.765999,119.46701 110.932999,119.46701l247.466995,0c4.718994,0 8.53299,-3.822998 8.53299,-8.53299s-3.813995,-8.53302 -8.53299,-8.53302l-247.466995,0c-51.754997,0 -93.866999,-45.934998 -93.866999,-102.399994c0,-28.88501 11.212999,-56.584991 30.771002,-75.997986c17.125996,-16.998016 38.673,-25.976013 62.353001,-25.976013c0.222,0 0.451996,0.009003 0.682999,0.009003c0.673996,0.026001 1.707001,-0.153992 2.526001,-0.434998l279.134018,0c56.464996,0 102.399994,45.934998 102.399994,102.399994c0,56.464996 -45.934998,102.399994 -102.399994,102.399994c-4.719025,0 -8.53302,3.822998 -8.53302,8.53302s3.813995,8.53299 8.53302,8.53299c65.877991,0 119.46698,-53.588989 119.46698,-119.46701s-53.588989,-119.466003 -119.46701,-119.466003z" fill="#ddd" class="cmpsvgsilver2fill"></path></g></g></svg></span></a></div><div data-cmp-stack="42" id="cmppurposelabelst42" class="cmpwelcomeprpstxt " draggable="false">Personalised advertising and content, advertising and content measurement, audience research and services development
</div></div></div></div><div class="cmpboxbtns" role="form"><span id="cmpwelcomebtnyes" class="cmpboxbtnspan"><a class="cmpboxbtn cmpboxbtnyes cmptxt_btn_yes" role="button" href="#" draggable="false"><svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" height="32px" viewBox="0 0 32 32" width="32px" class="cmpicosvgfill"><path id="cmpsvgacceptbtn" role="presentation" d="M27 4l-15 15-7-7-5 5 12 12 20-20z"></path></svg> <span id="cmpbntyestxt">Accept all</span></a></span><span id="cmpwelcomebtncustom" class="cmpboxbtnspan"><a class="cmpboxbtn cmpboxbtncustom cmptxt_btn_settings" role="button" href="#" draggable="false"><span id="cmpbntcustomtxt">Settings</span></a></span><span style="display:none;" id="cmpwelcomebtnsave" class="cmpboxbtnspan"><a class="cmpboxbtn cmpboxbtnsave cmptxt_btn_save" role="button" href="#" draggable="false"><span id="cmpbntsavetxt">Save + Exit</span></a></span><div class="cmpmore"><span id="cmpcustomchoiceslink" style="display:none;"><a class="cmpmorelink cmptxt_btn_custom" href="#" draggable="false">Customize your choice</a><span class="cmpmoredivider"> | </span></span><a class="cmpmorelink cmptxt_cookies" href="#" draggable="false">Cookies</a><span class="cmpmoredivider"> | </span><a class="cmpmorelink cmptxt_btn_more" href="https://adinplay.com/privacy-and-cookies-policy/" target="_blank">Privacy notice</a></div></div></div><div class="cmplogo"><a href="https://adinplay.com/?utm_source=publishers&utm_medium=cmp" target="blank"><img class="cmpdl" alt="Logo" data-cmp-ab="1" src="https://cdn.consentmanager.net/delivery/img/logo1592405744x390.gif" loading="lazy"></a></div><div class="cmplanguage" id="cmplanguage" title="Language: en" role="button" draggable="false" tabindex="0"><img class="cmplangicon" src="https://cdn.consentmanager.net/delivery/flags/en.gif" width="16" height="11" aria-hidden="true" alt="Language: en" title="Language: en" data-cmp-ab="1" loading="lazy"></div></div><svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-egg" viewBox="0 0 14.59 18.12">
<path class="eggFill" d="M14.49,10.79c0-3.96-3.02-10.66-6.98-10.66s-7.36,6.7-7.36,10.66s3.21,7.17,7.17,7.17S14.49,14.75,14.49,10.79z"></path>
</symbol>
</defs>
</svg>
<style>
.eggIconLocked {
display: inline-block;
color: #444444;
width: 1em;
height: 1em;
fill: currentColor;
}
</style>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-egg-locked" viewBox="0 0 14.59 18.12">
<g>
<path class="st0" d="M7.3,5.4c-0.6,0-1.1,0.5-1.1,1.1v1.3h2.2V6.5C8.4,5.9,7.9,5.4,7.3,5.4z"></path>
<path class="st0" d="M7.5,0.1c-4,0-7.4,6.7-7.4,10.7S3.4,18,7.3,18c3.9,0,7.2-3.2,7.2-7.2S11.5,0.1,7.5,0.1z M11.3,12.5
c0,0.9-0.7,1.6-1.6,1.6H4.8c-0.9,0-1.6-0.7-1.6-1.6V7.8h1.5V6.5C4.8,5.1,5.9,4,7.3,4c1.4,0,2.5,1.1,2.5,2.5v1.3h1.5V12.5z"></path>
</g>
</symbol>
</defs>
</svg><!-- ParsedURL -->
<script>
var parsedUrl = (function parseUrl () {
var url = {};
var loc = window.location;
url.root = loc.origin + loc.pathname;
var query = loc.search.substring(1).split('&');
url.query = {};
for (let i = 0; i < query.length; i++) {
var arr = query[i].split('=');
if (arr[0]) {
if (arr[1] === undefined) {
arr[1] = true;
} else if (!isNaN(arr[1])) {
arr[1] = parseFloat(arr[1]);
}
url.query[arr[0]] = arr[1];
}
}
url.hash = loc.hash.substring(1);
var host = loc.host.split('.');
url.dom = host[0];
url.top = host[1];
if (url.hash.length == 0) url.hash = undefined;
return url;
})();
</script>
<!-- third party globals -->
<script>
// Third party globals
var crazysdk = {inviteLink: function () {}},
pokiActive = false,
crazyGamesActive = false,
thirdPartyAdblocker = false,
testCrazy = false;
</script><!-- Crazy Games -->
<script src="https://sdk.crazygames.com/crazygames-sdk-v1.js"></script>
<script type="text/javascript">
const crazyAdDetect = (e) => {
if (e.hasAdblock) {
thirdPartyAdblocker = true;
}
};
// const crazyInitialized = (e) => {
// console.log('INITIALIZED: ', e);
// };
if (window.CrazyGames && CrazyGames.CrazySDK) {
const { CrazySDK } = window.CrazyGames;
crazysdk = CrazySDK.getInstance(); //Getting the SDK
crazysdk.addEventListener('bannerRendered', (e) => {
console.log(`Banner for container ${e.containerId} has been rendered!`);
});
crazysdk.addEventListener('bannerError', (e) => {
console.log(`Banner render error: ${e.error}`);
if (e.containerId === 'shellshockers_respawn_banner_2_ad' || e.containerId === 'shellshockers_respawn_banner-new_ad') {
// We only reset the timeout if both banners fail during the same request
if (++vueData.cGrespawnBannerErrors >= 2) {
vueData.cGrespawnBannerErrors = 0;
if (vueData.cGrespawnBannerTimeout) {
clearTimeout(vueData.cGrespawnBannerTimeout);
vueData.cGrespawnBannerTimeout = null;
}
}
}
});
// crazysdk.addEventListener('initialized', crazyInitialized);
crazysdk.addEventListener('adblockDetectionExecuted', crazyAdDetect);
crazysdk.init(); //Initializing the SDK, call as early as possible
}
if (parsedUrl.query.testCrazy) {
testCrazy = true;
}
</script><div style="position: fixed; display: none; width: 100%; height: 100%; inset: 0px; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, 0.5); z-index: 10000;"></div><!-- European Union detection -->
<script>isFromEU = 0 ? true : false</script>
<!-- AdInPlay -->
<meta name="viewport" content="minimal-ui, user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width">
<script>
var aiptag = aiptag || {};
aiptag.cmd = aiptag.cmd || [];
aiptag.cmd.display = aiptag.cmd.display || [];
aiptag.cmd.player = aiptag.cmd.player || [];
</script>
<script async="" src="https://api.adinplay.com/libs/aiptag/pub/SSK/shellshock.io/tag.min.js"></script>
<!-- GTM -->
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-K5MSJHJ');</script>
<!-- End Google Tag Manager --><!-- In house ads -->
<script>
window.googletag = window.googletag || {cmd: []};
let inHouseSlot;
const slots = [];
const dpfNetwork = /21743024831/,
inHouseAdSlot = 'ShellShockers_LoadingScreen_HouseAds'
inHouseAdSize = [[468, 60], [970, 90], [970, 250], [728, 90]],
inHouseAdDiv = 'ShellShockers_LoadingScreen_HouseAds',
adSlots = [];
// Helper to setup slots and add to slot array
const adDefineSlot = (slot, sizes, id) => {
return adSlots.push([{slot, sizes, id}]);
};
// Defining the slots for the the array
const loadingScreeningAd = adDefineSlot(inHouseAdSlot, inHouseAdSize, inHouseAdDiv);
// Helper to add slots to google service
function addServiceToSlot() {
slots.forEach(slot => {
slot.addService(googletag.pubads());
});
}
// Get all the slots, add to google ad defineSlot method
function getAllDefinedSlots(allSlots) {
let definedSlots = [];
allSlots.forEach(adSlot => {
for (var i = 0, len = adSlot.length; i < len; i++) {
slots.push(googletag.defineSlot(dpfNetwork + adSlot[i].slot, adSlot[i].sizes, adSlot[i].id));
}
})
return addServiceToSlot(slots);
}
const gtagInHouseLoadingBannerIntialLoad = () => {
if (typeof hasPoki !== 'undefined') {
console.log('haspoki', typeof(hasPoki));
return;
}
googletag.cmd.push(function() {
getAllDefinedSlots(adSlots);
googletag.pubads().disableInitialLoad();
googletag.enableServices();
});
};
gtagInHouseLoadingBannerIntialLoad();
const adRenderedEvent = () => {
return googletag.pubads().addEventListener('slotRenderEnded', (event) => {
vueApp.disaplyAdEventObject(event);
});
};
const gtagInHouseLoadingBanner = () => {
googletag.cmd.push(function() {
googletag.pubads().refresh([slots[0]]);
adRenderedEvent();
});
};
const destroyInhouseAdForPaid = () => {
googletag.destroySlots([slots[0]]);
};
</script><!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/7.21.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.21.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/ui/4.6.1/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.6.1/firebase-ui-auth.css">
<!-- Facebook -->
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '771186996377132');
fbq('track', 'PageView');
</script>
<noscript>
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=771186996377132&ev=PageView&noscript=1"/>
</noscript>
<!-- DO NOT MODIFY -->
<!-- End Facebook Pixel Code -->
<!-- OneSignal -->
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
var osAppId = 'dae68bc6-167c-4012-8644-90fe9db39950';
if (!location.hostname.startsWith('shellshock')) {
if (location.hostname.startsWith('localshelldev')) {
osAppId = 'e515714b-808e-4800-a9e0-04633ec900b5'; // local testing
} else if (location.hostname.startsWith('dev')) {
osAppId = '20bd47ca-cce1-428e-b34f-1a240f643112'; // dev testing
} else if (location.hostname.startsWith('localhost')) {
osAppId = '884bfbf7-5bcb-4170-9bf4-bba6b6e0046e';// localhost testing
} else {
osAppId = '166e17cb-5c02-4c7d-8bff-8ec69729f725'; // internal testing
}
}
var OneSignal = window.OneSignal || [];
OneSignal.push(function() {
OneSignal.init({
appId: osAppId,
// autoResubscribe:true,
// allowLocalhostAsSecureOrigin: true
});
});
</script><!-- progressive web app -->
<!-- <button id="addToHomescreen" style="z-index:333;display: none; position:absolute; top:0px; right: 75%; cursor:pointer;" class="ss_button btn_yolk bevel_yolk">Add to your desktop!</button> -->
<script>
let pwaBlockAds = false;
// if ('serviceWorker' in navigator) {
// console.log("Will the service worker register?");
// navigator.serviceWorker.register('service-worker.js')
// .then(function(reg){
// console.log("Yes, it did.");
// }).catch(function(err) {
// console.log("No it didn't. This happened:", err)
// });
// }
if (window.matchMedia('(display-mode: standalone)').matches) {
pwaBlockAds = 'utm_source' in parsedUrl.query && parsedUrl.query.utm_source === 'homescreen';
ga('send', 'event', 'pwa', 'desktop opened');
}
</script>
<!-- Music audio tag -->
<audio id="theAudio" preload="metadata"></audio><!-- VueJS -->
<script src="js/vue/vue.min.2.6.10.js"></script><!-- tools and varibles -->
<script>
let changeLogData;
var version;
fetch('./changelog/changelog.json?1653515333', {cache: "no-cache"})
.then(response => response.json())
.then(data => {
changeLogData = data;
version = changeLogData[0].version;
});
localStore.removeItem('brbTime');
String.prototype.format = String.prototype.f = function() {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
function getKeyByValue (obj, value) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (obj[prop] === value) {
return prop;
}
}
}
}
function objToStr (obj) {
var str = JSON.stringify(obj, null, 4).replace(/\\|"/g, '');
//str = str.replace(/\\|"/g, '');
return str;
}
function detectChromebook() {
return /\bCrOS\b/.test(navigator.userAgent);
}
function removeChildNodes (name) {
var myNode = document.getElementById(name);
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
}
function logCallStack() {
var stack = new Error().stack;
console.log(stack);
}
function getRequest (url, callback) {
if (url.startsWith('./')) url = url.slice(2);
url = dynamicContentPrefix + url;
var req = new XMLHttpRequest();
if (!req) {
return false;
}
if (typeof callback != 'function') callback = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
callback(null, req.responseText) : callback(req.status, null);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
function hasValue (a) {
return (a !== undefined && a !== null && a !== 0);
}
Array.prototype.shallowClone = function() {
return this.slice(0);
}
function deepClone (o) {
return JSON.parse(JSON.stringify(o));
}
function isString (value) {
return typeof value === 'string' || value instanceof String;
}
const theTimeTracker = (startTime, gaVar, gaLabel) => {
const endTime = new Date();
const timerResult = endTime - startTime;
if (!Number.isInteger(timerResult) && !timerResult ) {
return;
}
return ga('send', 'timing', vueData.googleAnalytics.cat.playerStats, gaVar, timerResult, gaLabel);
};
const isShellIframe = () => window.self === window.top;
const iframeParent = () => {
const parent = (window.location != window.parent.location)
? document.referrer
: document.location.href,
domain = new URL(parent).hostname.replace(/(www.)/, '').split('.');
if (!Array.isArray(domain) && !domain.length) {
return false;
}
const index = domain.length - 2;
return {
domain: domain,
index: index,
};
};
const iframeWhitelist = (domains) => {
if (isShellIframe()) {
return;
}
const parent = iframeParent(),
domain = parent.domain,
index = parent.index;
// if in iframe and url hostname is in approved whitelist return true or false if not in list
return domains.includes(domain[index]) || domains.includes(domain[index - 1]);
};
const playShellshockers = () => {
//if not in a iframe return true
if (isShellIframe()) {
console.log('Not playing in iframe');
return true;
}
console.log('Playing in iframe');
const gamePortals = [
'poki',
'poki-gdn',
'poki.compoki',
'games.poki',
'crazygames',
'1001juegos',
'ioground',
'gogy',
'playgamesio',
'iogames',
'iogames',
'wingsiofree',
'vseigru',
'miniclip',
'red-ball4',
'speelspelletjes',
'onlinegame',
'addictinggames'
];
const parent = iframeParent(),
domain = parent.domain,
index = parent.index;
// if in iframe and url hostname is in approved whitelist return true or false if not in list
//return gamePortals.includes(domain[index]) || gamePortals.includes(domain[index - 1]);
return true; // Disabling this for now because server outages caused everyone to be blacklisted for some insane, currently unknown reason.
};
const capitalize = (s) => {
if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1)
};
var servers = [
{ name: 'US East', subdom: 'useast2.', locKey: 'server_useast', id: 'us-e1' },
{ name: 'US West', subdom: 'uswest2.', locKey: 'server_uswest', id: 'us-w1' },
{ name: 'US Central', subdom: 'uscentral2.', locKey: 'server_uscentral', id: 'us-c1' },
{ name: 'Brazil', subdom: 'brazil2.', locKey: 'server_brazil', id: 'br-1' },
{ name: 'Germany', subdom: 'frankfurt.', locKey: 'server_germany', id: 'de-1' },
{ name: 'Singapore', subdom: 'singapore2.', locKey: 'server_singapore', id: 'si-1' },
{ name: 'Sydney', subdom: 'sydney.', locKey: 'server_sydney', id: 'au-1' },
];
var debug = false;
var servicesServer = 'wss://' + window.location.hostname + '/services/';
const isLocalShellDev = location.hostname.startsWith('localshelldev'),
isLocalHost = location.hostname.startsWith('localhost');
if (dynamicContentRoot) {
servicesServer = 'wss://' + dynamicContentRoot + '/services/';
}
else if (isLocalHost || isLocalShellDev) {
servicesServer = isLocalHost ? 'ws://localhost:4242' : 'ws://localshelldev.bluewizard.com:4242/';
debug = true;
if (isLocalShellDev)
servers.push({ name: 'Local VM', subdom: 'localshelldev.', root: 'bluewizard.com', locKey: 'server_localshelldev', id: 'lucyskydiamonds' });
servers.push({ name: 'local', subdom: '', locKey: '_server_local', id: 'local' });
servers.push({ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_gamedev', id: 'gamedev' });
}
else if (location.hostname.startsWith('staging.shellshock.io')) {
debug = true;
servers = [{ name: 'Staging', subdom: 'staging.', locKey: 'server_staging', id: 'staging' }];
var servicesServer = 'wss://staging.shellshock.io:8443/services/';
}
if (location.search.includes('portalTest')) {
gameServerRoot = 'shellshock.io';
dynamicContentRoot = 'dev.shellshock.io';
dynamicContentPrefix = 'https://dev.shellshock.io/';
servers = [{ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_dev', id: 'dev' }];
}
if (!dynamicContentRoot && location.hostname.startsWith('dev.shellshock.io') || dynamicContentRoot == 'dev.shellshock.io') {
servers = [{ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_dev', id: 'dev' }];
servicesServer = 'wss://dev.shellshock.io/services/';
}
function getGameServerUrl (server) {
// Dump the www from the hostname if it exists
var hostname = window.location.hostname;
var fields = hostname.split('.');
if (fields.length > 2) {
hostname = fields[1] + '.' + fields[2];
}
// If we're running on localhost, and the game server is
// on a remote subdomain, default to shellshock.io domain
var rootName = server.root || hostname;
if (server.subdom && rootName == 'localhost') {
rootName = 'shellshock.io';
}
var subdom = server.subdom || '';
if (gameServerRoot) rootName = gameServerRoot;
if (server.subdom == '' && rootName === 'localhost' || rootName === 'bluewizard.com') {
return 'ws://' + subdom + rootName + ':4430';
} else {
return 'wss://' + subdom + rootName;
}
}
function getServerIndex (server) {
return servers.map(s => s.id).indexOf(server.id);
}
function getStoredNumber (name, def) {
var num = localStore.getItem(name);
if (!num) {
return def;
}
return Number(num);
}
function getStoredBool (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return str == 'true' ? true : false;
}
function getStoredString (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return str;
}
function getStoredObject (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return JSON.parse(str);
}
var shellColors = [
'#ffffff',
'#c4e3e8',
'#e2bc8b',
'#d48e52',
'#cb6d4b',
'#8d3213',
'#5e260f',
'#e70a0a',
'#aa24ce',
'#f17ff9',
'#FFD700',
'#33a4ea',
'#3e7753',
'#59db27',
//'#99953a'
];
var freeColors = shellColors.slice(0, 7);
var paidColors = shellColors.slice(7, shellColors.length);
var Slot = {
Primary: 0,
Secondary: 1
};
var EGGCOLOR = {
white: 0,
skyblue: 1,
beige: 2,
tan: 3,
brown: 4,
caramel: 5,
chocolate: 6,
red: 7,
purple: 8,
violet: 9,
yellow: 10,
babyblue: 11,
darkgreen: 12,
green: 13
}
// Type matches contents of the item_type table (could be generated from a db query but ... meh)
var ItemType = {
Hat: 1,
Stamp: 2,
Primary: 3,
Secondary: 4,
Grenade: 6
}
var CharClass = {
Soldier: 0,
Scrambler: 1,
Ranger: 2,
Eggsploder: 3,
Whipper: 4,
Crackshot: 5,
TriHard: 6
};
const SOCIALMEDIA = [
'fa-facebook-square',
'fa-instagram-square',
'fa-tiktok',
'fa-discord',
'fa-youtube',
'fa-twitter-square',
'fa-twitch'
];
</script><!-- shellshockers js -->
<script>
function ssJSComplete () {
window.onloadingcomplete();
}
Loader.loadJS('src/shellshock.js?1654121223', ssJSComplete);
</script>
<!-- google tag manager noscript -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K5MSJHJ"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) --> <!-- Ads -->
<div id="gameAdContainer" class="hideme">
<!-- <div id="multisizeBannerAdPlaceholder"></div>
<div id="shellshock-io_multisize"></div> -->
<!-- AdInPlay tag ID -->
<!-- ShellShock_Respawn_Banner -->
<!-- <div id='div-gpt-ad-ShellShock_Respawn_Banner'>
<script type='text/javascript'>
googletag.cmd.push(function() { googletag.display('div-gpt-ad-ShellShock_Respawn_Banner'); });
</script>
</div> -->
</div>
<div id="shellshockers_titlescreen">
</div>
<div id="shellshockers_chicken_nugget_banner">
</div>
<div id="shellshockers_respawn_banner_2">
</div>
<!-- <div id="shellshockers_respawn_banner">
</div> -->
<div id="shellshockers_respawn_banner-new">
</div>
<div id="ShellShockers_LoadingScreen_HouseAds">
</div>
<div id="videoAdContainer">
<div id="preroll"></div>
</div>
<!-- <div class="video_ad_wrapper">
<video id="asc_video_ad" class="video-js vjs-default-skin" controls preload="auto" width="640" height="360" muted="true" style="display: none;">
<source src="video/tiny.mp4" type="video/mp4" />
</video>
</div> -->
<div id="ss_background"></div>
<!-- Instantiate the Vue instance -->
<div id="app" :class="[currentLanguageCode, portalClass]"> <!-- vue instance div: all vue-controlled elements MUST be inside this tag -->
<!-- <asc-video-player id="mainVideoPlayer" ref="mainVideoPlayer" adTagUrl="adTagUrl"></asc-video-player> -->
<div class="firebaseID">firebase ID: {{ firebaseId }}, maskedEmail: {{ maskedEmail }} isAnonymous: {{ isAnonymous }}, isEmailVerified: {{ isEmailVerified }}</div>
<!-- Canvas -->
<canvas id="canvas" ref="canvas" class="gameCanvas"></canvas>
<!-- Overlays -->
<light-overlay id="lightOverlay" ref="lightOverlay"></light-overlay>
<dark-overlay id="darkOverlay" ref="darkOverlay"></dark-overlay>
<spinner-overlay id="spinnerOverlay" ref="spinnerOverlay" :loc="loc" :hide-ads="hideAds"></spinner-overlay>
<!-- GDPR -->
<gdpr id="gdpr" ref="gdpr" :loc="loc"></gdpr>
<!-- Screens -->
<home-screen id="home_screen" ref="homeScreen" v-show="(ui.showScreen === ui.screens.home)"></home-screen>
<equip-screen id="equip_screen" ref="equipScreen" v-show="(ui.showScreen === ui.screens.equip)"></equip-screen>
<game-screen id="game_screen" ref="gameScreen" v-show="(ui.showScreen === ui.screens.game)" :kname="killName" :kdname="killedName"></game-screen>
<!-- Popup: Settings -->
<large-popup id="settingsPopup" ref="settingsPopup" @popup-closed="onSharedPopupClosed" @popup-opened="onSettingsPopupOpened" @popup-x="onSettingsX">
<template slot="content">
<settings id="settings" ref="settings" :loc="loc" :settings-ui="settingsUi" :languages="languages" :current-language-code="currentLanguageCode" :show-privacy-options="showPrivacyOptions" @privacy-options-opened="onPrivacyOptionsOpened" :is-from-eu="showPrivacyOptions" :controller-id="controllerId" :controller-type="controllerType" :lang-option="locLanguage" :is-vip="(hideAds || contentCreator)"></settings>
</template>
</large-popup>
<!-- Popup: Privacy Options -->
<small-popup id="privacyPopup" ref="privacyPopup" hide-cancel="true" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc.p_settings_privacy }}</template>
<template slot="content">
<label class="ss_checkbox label"> {{ loc.p_settings_of_age }}
<input id="ofAgeCheck" type="checkbox" v-model="isOfAge" @change="ofAgeChanged($event)">
<span class="checkmark"></span>
</label>
<label class="ss_checkbox label"> {{ loc.p_settings_target_ads }}
<input id="targetedAdsCheck" type="checkbox" v-model="showTargetedAds" @change="targetedAdsChanged($event)">
<span class="checkmark"></span>
</label>
<!--
<input id="ofAgeCheck" type="checkbox" v-model="isOfAge" @change="ofAgeChanged($event)"> {{ loc.p_settings_of_age }}<br>
<input id="targetedAdsCheck" type="checkbox" v-model="showTargetedAds" @change="targetedAdsChanged($event)"> <span id="targetedAdsText">{{ loc.p_settings_target_ads }}</span>
-->
</template>
<template slot="confirm">{{ loc.ok }}</template>
</small-popup>
<!-- Popup: Help & Feedback -->
<large-popup id="helpPopup" ref="helpPopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed">
<template slot="content">
<help id="help" ref="help" :loc="loc"></help>
</template>
</large-popup>
<!-- Popup: VIP Help & Feedback -->
<large-popup id="vipPopup" ref="vipPopup" stop-key-capture="true" @popup-closed="onVipHelpClosed">
<template slot="content">
<vip-help id="vip-help" ref="help" :loc="loc" :is-vip="isSubscriber">
</vip-help></template>
</large-popup>
<!-- Popup: Egg Store -->
<large-popup id="eggStorePopup" ref="eggStorePopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="false">
<template slot="content">
<egg-store id="help" ref="help" :loc="loc" :products="eggStoreItems" :sale-event="isSale"></egg-store>
</template>
</large-popup>
<img v-show="blackFridayBanner" class="black-friday-banner" style="display: none" src="img/black-friday-banner.jpg" alt="Black Friday Sale">
<!-- Popup: VIP store -->
<large-popup id="subStorePopup" ref="subStorePopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="true">
<template slot="content">
<subscription-store id="shell-subscriptions" ref="shell-subscriptions" :loc="loc" :subs="subStoreItems">
</subscription-store></template>
</large-popup>
<!-- Popup: VIP ended -->
<small-popup id="vipEnded" ref="vipEnded" stop-key-capture="true" @popup-confirm="showSubStorePopup" @popup-closed="onSharedPopupClosed" :overlay-close="true" class="vip">
<template slot="content">
<figure>
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Shell Shockers VIP">
</figure>
<div class="vip-ended-popup">
Yo! Your VIP subscription has expired! If you'd like to keep your awesome benefits (and your Golden Wings!) then click below to join again!
</div>
</template>
<template slot="confirm">Join again!</template>
<template slot="cancel">No, i don't like stuff</template>
</small-popup>
<!-- Popup: Egg Store single -->
<large-popup id="popupEggStoreSingle" ref="popupEggStoreSingle" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="false" class="popup-store-single">
<template slot="content">
<egg-store-item v-for="item in premiumShopItems" :key="item.sku" :item="item" :loc="loc" :account-set="accountSettled" v-if="eggStorePopupSku && item.sku === eggStorePopupSku"></egg-store-item>
</template>
</large-popup>
<!-- Popup: Unsupported Platform -->
<large-popup id="unsupportedPlatformPopup" ref="unsupportedPlatformPopup" hide-close="true">
<template slot="content">
<h2>{{ loc['unsupported_platform'] }}</h2>
<div>{{ loc[unsupportedPlatformPopup.contentLocKey] }}</div>
</template>
</large-popup>
<!-- Popup: Missing Features -->
<large-popup id="missingFeaturesPopup" ref="missingFeaturesPopup" hide-close="true">
<template slot="content">
<h2>{{ loc['oh_no'] }}</h2>
<span>{{ loc['missing_features'] }}</span>
<ul>
<li v-for="f in missingFeatures" v-html="f"></li>
</ul>
<span>{{ loc['missing_help'] }}</span>
</template>
</large-popup>
<!-- Popup: No Anon -->
<small-popup id="noAnonPopup" ref="noAnonPopup" @popup-confirm="onNoAnonPopupConfirm" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc.no_anon_title }}</template>
<template slot="content">
<div>{{ loc.no_anon_msg1 }}</div>
<div>{{ loc.no_anon_msg2 }}</div>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.no_anon_signup }}</template>
</small-popup>
<!-- Popup: Give Stuff -->
<give-stuff-popup ref="giveStuffPopup" id="giveStuffPopup" :loc="loc" :give-stuff-popup="giveStuffPopup"></give-stuff-popup>
<!-- Popup: Open URL -->
<small-popup id="openUrlPopup" ref="openUrlPopup" @popup-confirm="onOpenUrlPopupConfirm" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc[openUrlPopup.titleLocKey] }}</template>
<template slot="content">
<!-- content not loc'd (yet) -->
{{ openUrlPopup.content }}
</template>
<template slot="cancel">{{ loc[openUrlPopup.cancelLocKey] }}</template>
<template slot="confirm">{{ loc[openUrlPopup.confirmLocKey] }}</template>
</small-popup>
<!-- Popup: Changelog -->
<large-popup id="changelogPopup" ref="changelogPopup" @popup-closed="onSharedPopupClosed">
<template slot="content">
<h1 id="popup_title nospace" class="roundme_sm">
{{ loc.changelog_title }}
</h1>
<div class="changelog_content">
<section v-for="(log, idx) in changelog.current">
<h3>{{ log.version }} - <i><time>{{ log.date }}</time></i></h3>
<ul>
<li v-for="data in log.content" v-html="data"></li>
</ul>
<hr class="blue">
</section>
</div>
<div id="btn_horizontal">
<button v-if="changelog.showHistoryBtn" @click="showHistoryChangelogPopup" class="ss_button btn_green bevel_green">More</button>
<button @click="hideChangelogPopup" class="ss_button btn_red bevel_red">{{ loc.close }}</button>
</div>
</template>
</large-popup>
<!-- Popup: Golden Chicken -->
<!-- <large-popup id="goldChickenPopup" ref="goldChickenPopup" :overlay-close="false">
<template slot="content">
<gold-chicken-popup id="gold_chicken" ref="gold_chicken" :loc="loc"></gold-chicken-popup>
</template>
</large-popup> -->
<!-- Popup: Chicken Nugget -->
<large-popup id="chicknWinner" ref="chicknWinner" :hide-close="true" :overlay-close="false">
<template slot="content">
<chicken-nugget-popup id="chickenNugget" ref="chickenNugget" :loc="loc" :amount-given="miniEggGameAmount" :ad-units="adUnits"></chicken-nugget-popup>
</template>
</large-popup>
<!-- Popup: Generic Message -->
<small-popup id="genericPopup" ref="genericPopup" :popup-model="genericMessagePopup" :hide-cancel="true" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc[genericMessagePopup.titleLocKey] }}</template>
<template slot="content">{{ loc[genericMessagePopup.contentLocKey] }}</template>
<template slot="confirm">{{ loc[genericMessagePopup.confirmLocKey] }}</template>
</small-popup>
<!-- Popup: Anon warning message -->
<small-popup v-if="isAnonymous" id="anonWarningPopup" ref="anonWarningPopup" :hide-close="true" :overlay-close="false" @popup-cancel="anonWarningPopupCancel" @popup-confirm="anonWarningPopupConfrim">
<template slot="header">{{ loc.account_anon_warn_popup_title }}!</template>
<template slot="content">
<p v-html="loc.account_anon_warn_paragraph_block"></p>
<p v-html="loc.account_anon_warn_paragraph_block_two"></p>
</template>
<template slot="cancel">{{ loc.account_anon_warn_confirm }}</template>
<template slot="confirm">{{ loc.sign_in }}</template>
</small-popup>
<!-- Popup: Need More eggs popup -->
<small-popup id="needMoreEggsPopup" ref="needMoreEggsPopup" @popup-confirm="showEggStorePopup">
<template slot="header">{{ loc.p_buy_isf_title }}!</template>
<template slot="content">
<p>{{ loc.p_buy_isf_content }}.</p>
</template>
<template slot="cancel">{{ loc.p_buy_item_cancel }}</template>
<template slot="confirm">{{ loc.account_title_eggshop }}</template>
</small-popup>
<!-- Popup: Firebase Sign In -->
<large-popup id="firebaseSignInPopup" ref="firebaseSignInPopup" :overlay-close="false">
<template slot="content">
<h1 class="nospace">{{ loc.p_signin_head }}</h1>
<div id="firebaseui-auth-container"></div>
<div id="btn_horizontal" class="f_center">
<button @click="onSignInCancelClicked()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
</div>
</template>
</large-popup>
<small-popup ref="adBlockerPopup" id="adBlockerPopup" :overlay-close="false" hide-confirm="true" hide-cancel="true" hide-close="true">
<template slot="header">
We've detected ad blocker!
</template>
<template slot="content">
<p>To <i>avoid</i> this message please turn <i>off</i> ad blocker.</p>
<h4>Please wait</h4>
<h3>{{adBlockerCountDown}}</h3>
</template>
</small-popup>
<!-- Popup: PWA -->
<small-popup id="pwaPopup" class="pwa-popup" ref="pwaPopup" hide-confirm="true" @popup-closed="onSharedPopupClosed">
<!-- <template slot="header">{{ loc.p_settings_privacy }}</template> -->
<template slot="content">
<p>{{loc.pwa_desc_one}}</p>
<p>{{loc.pwa_desc_two}}</p>
<button @click="pwaBtnClick" class="ss_button btn_big btn_green bevel_green btn_height_auto btn-pwa-download">
<div class="pwa-btn-img-box roundme_lg bg-darkgreen">
<img src="favicon192.png" alt="Egg yolk">
<i class="fas fa-share" aria-hidden="true"></i>
</div>
{{loc.pwa_btn_line_one}}<br>{{loc.pwa_btn_line_two}}
</button>
</template>
<template slot="cancel">{{loc.pwa_no_thanks}}</template>
</small-popup>
<large-popup id="adBlockerVideo" ref="adBlockerVideo" @popup-closed="onSharedPopupClosed" :overlay-close="false" hide-confirm="true" hide-cancel="true" hide-close="true">
<template slot="content">
<p class="text-center">{{ loc.ad_blocker_big_popup_title }}<br> <span v-html="loc.ad_blocker_big_popup_desc"></span></p>
<img src="img/shellshockers-unite-lg.png" alt="">
<!-- <house-ad id="house-ad-video-replacement" ref="house-ad-video-replacement" :data="bannerHouseAd" :isshowing="showAdBlockerVideoAd"></house-ad> -->
</template>
</large-popup>
<large-popup ref="mobileAdPopup" id="mobileAdPopup" :overlay-close="true" hide-confirm="true" hide-cancel="true">
<template slot="content">
<img src="img/mobile/shell-mobile-popup-bg-qr.png" alt="Get Shell Shockers Mobile app!">
</template>
</large-popup>
<large-popup ref="kotcInstrucPopup" id="kotcInstrucPopup" :overlay-close="true" hide-confirm="true" hide-cancel="true">
<template slot="content">
<img class="kotc-wordmark" src="img/kotc/kotc-wordmark.svg" alt="">
<div class="kotc-how-to-play-wrapper box_aboslute">
<h2 class="kotc-how-to-play-title text-center"><span class="roundme_md">{{ loc.home_kotc_popup_how_to }}</span><br>{{ loc.home_play }}!</h2>
<img src="img/kotc/kotc-arrow.svg" aria-hidden="true">
</div>
<div class="display-grid grid-column-2-eq grid-gap-space-lg fullwidth ss_margintop_xxxxl">
<div class="img-container roundme_lg fullwidth step-one">
<div class="fullwidth">
<p class="text-center"><span class="sr-only">Step </span>1</p>
<h6 class="text-center">{{loc.home_kotc_popup_step_one}}</h6>
</div>
</div>
<div class="img-container roundme_md fullwidth step-two">
<div class="fullwidth">
<p class="text-center"><span class="sr-only">Step </span>2</p>
<h6 class="text-center">{{loc.home_kotc_popup_step_two}}</h6>
</div>
</div>
</div>
<div class="display-grid grid-column-2-eq grid-gap-space-lg roundme_md fullwidth ss_margintop_lg kotc-play-now step-three-wrapper">
<div class="fullwidth box_relative step-three">
<img class="kotc-logo box_aboslute" src="img/kotc/kotc-rooster.svg" alt="The King of the Coop Rooster">
<div>
<p class="text-center"><span class="sr-only">Step </span>3</p>
<h6 class="text-center" v-html="loc.home_kotc_popup_step_three"></h6>
</div>
</div>
<div class="fullwidth f_col f_space_between">
<div class="display-grid grid-column-5-eq kotc-crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
</div>
<button class="ss_button btn_big btn_green bevel_green fullwidth" @click="onClickPlayKotcNow"><i class="fa fa-play fa-sm"></i> {{ loc.home_play }}</button>
</div>
</div>
</template>
</large-popup>
<!-- <div id="kotc-play-kotc" class="kotc-play-kotc display-grid">
<img class="kotc-play-kotc-watermark" src="img/kotc/kotc-crown-indicator.svg" alt="">
<img class="kotc-play-kotc-arrow" src="img/kotc/kotc-arrow.svg" aria-hidden="true">
</div> -->
<!-- #kotc-play-kotc -->
</div> <!-- End of vue instance div -->
<script>
var vueApp;
var vueData = {
ready: false,
accountSettled: false,
missingFeatures: [],
changelogVersion: version,
changeLogData: [],
showChangelogHistoryBtn: true,
changelog: {
current: [],
history: [],
showHistoryBtn: true
},
firebaseId: null,
photoUrl: null,
maskedEmail: null,
isEmailVerified: false,
isAnonymous: true,
showPrivacyOptions: isFromEU,
isOfAge: false,
showTargetedAds: false,
delayTheCracking: false,
displayAdFunction: Function,
titleScreenDisplayAd: Function,
displayAdObject: false,
hideAds: false,
isPoki: false,
isPokiGameLoad: false,
pokiRewardReady: false,
isPokiNewRewardTimer: false,
videoRewardTimers: {
initial: 300000,
primary: 420000
},
pokiRewNum: 1,
adUnits: {
display: {
respawn: 'shellshockers_respawn_banner',
respawnTwo: 'shellshockers_respawn_banner_2',
respawnThree: "shellshockers_respawn_banner-new",
home: 'shellshockers_titlescreen',
nugget: 'shellshockers_chicken_nugget_banner',
house: 'ShellShockers_LoadingScreen_HouseAds'
}
},
cGrespawnBannerTimeout: null,
cGrespawnBannerErrors: 0,
classIdx: 0,
playerName: '',
eggs: 0,
kills: 0,
deaths: 0,
kdr: 0,
streak: 0,
isUpgraded: false,
upgradeName: '',
isSubscriber: false,
serverList: [], // Populated by pingServers()
currentServerId: null,
currentServerLocKey: null,
currentGameType: 0,
volume: 0,
getMusicVolume: 0.5,
currentLanguageCode: 'en',
ui: {
showScreen: 0,
screens: {
home: 0,
equip: 1,
game: 2
},
overlayType: {
none: 0,
dark: 1,
light: 2,
},
overlayClass: {
inGame: 'overlay_game'
},
team: {
blue: 1,
red: 2
},
houseAds: {
small: null,
big: null
},
showCornerButtons: true,
},
isTwitchEvent: false,
twitchLinked: 0,
twitchName: '',
languages: [
{ name: 'English', code: 'en' },
{ name: 'French', code: 'fr' },
{ name: 'German', code: 'de' },
{ name: 'Russian', code: 'ru' },
{ name: 'Spanish', code: 'es' },
{ name: 'Portuguese', code: 'pt' },
{ name: 'Korean', code: 'ko' },
{ name: 'Chinese', code: 'zh' },
{ name: 'Dutch', code: 'nl' }
],
locLanguage: {},
playTypes: {
joinPublic: 0,
createPrivate: 1,
joinPrivate: 2
},
gameTypes: [
{ locKey: 'gametype_ffa', value: 0 },
{ locKey: 'gametype_teams', value: 1 },
{ locKey: 'gametype_ctf', value: 2 },
{ locKey: 'gametype_king', value: 3 }
],
// This makes me mad, but until Vue is put in the clojure with GameType,
// where it should have been to begin with, HERE IT IS >:(
gameTypeKeys: [
'FFA',
'Teams',
'Spatula',
'King'
],
twitchStreams: [],
youtubeStreams: [],
newsfeedItems: [
{ message: "Test 1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.", image: "img/ico_news.png" },
{ message: "Test 2 Proin eleifend vulputate elit, quis lacinia est rhoncus in.", image: "img/ico_news.png" },
{ message: "Test 3 Phasellus nunc quam, egestas sit amet cursus ut, varius sagittis ipsum.", image: "img/ico_news.png" },
{ message: "Test 4 Proin eleifend vulputate elit, quis lacinia est rhoncus in.", image: "img/ico_news.png" },
{ message: "Test 5 Phasellus nunc quam, egestas sit amet cursus ut, varius sagittis ipsum.", image: "img/ico_news.png" }
],
maps: [],
settingsUi: {
adjusters: {
misc: [
{ id: 'volume', locKey: 'p_settings_mastervol', min: 0, max: 1, step: 0.01, value: 1, multiplier: 100 }
],
mouse: [
{ id: 'mouseSpeed', locKey: 'p_settings_mousespeed', min: 1, max: 100, step: 1, value: 30 }
],
gamepad: [
{ id: 'sensitivity', locKey: 'p_settings_sensitivity', min: 1, max: 100, step: 1, value: 30 },
{ id: 'deadzone', locKey: 'p_settings_deadzone', min: 0, max: 1, step: 0.01, value: 0.3, precision: 2 }
],
// music: [
// { id: 'musicVolume', locKey: 'p_settings_music_volume', min: 0, max: 1, step: 0.01, value: 0.5, multiplier: 100 }
// ],
},
togglers: {
misc: [
{ id: 'holdToAim', locKey: 'p_settings_holdtoaim', value: true },
{ id: 'enableChat', locKey: 'p_settings_enablechat', value: true },
{ id: 'safeNames', locKey: 'p_settings_safenames', value: false },
{ id: 'autoDetail', locKey: 'p_settings_autodetail', value: true },
{ id: 'shadowsEnabled', locKey: 'p_settings_shadows', value: true },
{ id: 'highRes', locKey: 'p_settings_highres', value: false },
{ id: 'hideBadge', locKey: 'p_settings_badge_hide', value: false },
// { id: 'musicStatus', locKey: 'p_settings_music', value: true }
],
mouse: [
{ id: 'mouseInvert', locKey: 'p_settings_invertmouse', value: false },
{ id: 'fastPollMouse', locKey: 'p_settings_fastpollmouse', value: false },
],
gamepad: [
{ id: 'controllerInvert', locKey: 'p_settings_invertcontroller', value: false },
]
},
controls: {
keyboard: {
// The ids map to the field names in settings.controls[category]
game: [
{ id: 'up', side: 'left', locKey: 'keybindings_forward', value: 'W' },
{ id: 'down', side: 'left', locKey: 'keybindings_backward', value: 'S' },
{ id: 'left', side: 'left', locKey: 'keybindings_left', value: 'A' },
{ id: 'right', side: 'left', locKey: 'keybindings_right', value: 'D' },
{ id: 'jump', side: 'left', locKey: 'keybindings_jump', value: 'SPACE' },
{ id: 'fire', side: 'right', locKey: 'keybindings_fire', value: 'MOUSE 0' },
{ id: 'scope', side: 'right', locKey: 'keybindings_aim', value: 'SHIFT' },
{ id: 'reload', side: 'right', locKey: 'keybindings_reload', value: 'R' },
{ id: 'swap_weapon', side: 'right', locKey: 'keybindings_swapweapon', value: 'E' },
{ id: 'grenade', side: 'right', locKey: 'keybindings_grenade', value: 'Q' }
],
spectate: [
{ id: 'ascend', locKey: 'keybindings_spectate_ascend', value: 'SPACE' },
{ id: 'descend', locKey: 'keybindings_spectate_descend', value: 'SHIFT' }
]
},
gamepad: {
// The ids map to the field names in settings.gamepad[category]
game: [
{ id: 'jump', locKey: 'keybindings_jump', value: '0' },
{ id: 'fire', locKey: 'keybindings_fire', value: '1' },
{ id: 'scope', locKey: 'keybindings_aim', value: '2' },
{ id: 'reload', locKey: 'keybindings_reload', value: '3' },
{ id: 'swap_weapon', locKey: 'keybindings_swapweapon', value: '4' },
{ id: 'grenade', locKey: 'keybindings_grenade', value: '5' }
],
spectate: [
{ id: 'ascend', locKey: 'keybindings_spectate_ascend', value: '1' },
{ id: 'descend', locKey: 'keybindings_spectate_descend', value: '2' }
]
}
}
},
songChanged: false,
music: {
isMusic: false,
musicJson: 'data/sponsors.json',
musicSrc: '',
theAudio: '',
playing: false,
sponsors: {},
sponsor: '',
currIndex: 0,
currentTime: 0,
duration: 0,
timer: null,
progress: 0,
volume: 10,
hideClass: 'music-widget--fade-out',
serverTracks: {
id: '',
title: '',
artist: '',
album: '',
albumArt: '',
url: '',
trackUrltest: 'https://shellshock.io',
sponsor: '',
sponsorUrl: '',
}
},
home: {
joinPrivateGamePopup: {
code: '',
showInvalidCodeMsg: false,
validate: function () {
if (this.code.length == 0) {
console.log('failed validation');
this.showInvalidCodeMsg = true;
BAWK.play('ui_reset');
return false;
}
console.log('passed validation');
return true;
},
reset: function () {
this.code = '';
this.showInvalidCodeMsg = false;
}
},
},
equip: {
get showingItems () {
return this._showingItems;
},
set showingItems (items) {
this._showingItems = items;
for (let t of this.lazyRenderTimeouts) {
clearTimeout(t);
}
},
lazyRenderTimeouts: [],
mode: 0,
equipModes: {
inventory: 0,
shop: 1
},
equippedPrimary: null,
equippedSecondary: null,
equippedHat: null,
equippedStamp: null,
equippedGrenade: null,
posingHat: null,
posingStamp: null,
posingWeapon: null,
posingGrenade: null,
showingWeaponType: ItemType.Primary,
selectedItemType: ItemType.Primary,
selectedItem: null,
_showingItems: [],
buyingItem: null,
colorIdx: 0,
extraColorsLocked: true,
categoryLocKey: null,
showSpecialItems: false,
specialItemsTag: null,
redeemCodePopup: {
code: '',
showInvalidCodeMsg: false,
validate: function () {
if (this.code.length == 0) {
console.log('failed validation');
this.showInvalidCodeMsg = true;
BAWK.play('ui_reset');
return false;
}
console.log('passed validation');
return true;
},
reset: function () {
this.code = '';
this.showInvalidCodeMsg = false;
}
},
physicalUnlockPopup: {
item: null
}
},
game: {
shareLinkPopup: {
url: ''
},
gameType: 0,
team: 1,
respawnTime: 0,
tipIdx: 0,
isGameOwner: false,
pauseScreen: {
id: 'pausePopup',
adContainerId: 'pauseAdPlacement',
classChanged: false,
wasGameInventoryOpen: false,
}
},
isPaused: true,
isEvent: false,
doubleEggWeekendSoon: false,
doubleEggWeekend: false,
announcementMessage: null,
playerActionsPopup: {
playerId: 0,
uniqueId: 0,
isGameOwner: false,
playerName: '',
muted: false,
muteFunc: null,
bootFunc: null,
social: false,
vipMember: false
},
giveStuffPopup: {
titleLoc: '',
eggs: 0,
items: [],
type: ''
},
openUrlPopup: {
url: '',
titleLocKey: '',
contentLocKey: '',
confirmLocKey: 'ok',
cancelLocKey: 'no_thanks'
},
genericMessagePopup: {
titleLocKey: 'keybindings_right',
contentLocKey: 'p_popup_chicken_nuggetbutton',
confirmLocKey: 'ok'
},
unsupportedPlatformPopup: {
titleLocKey: 'unsupported_platform',
contentLocKey: ''
},
windowDimensions: {
width: 0,
height: 0,
},
bannerAds: {
bannerElId: '',
},
googleAnalytics: {
isUser: null,
cat: {
purchases: 'Purchases',
purchaseComplete: 'Purchase Complete',
itemShop: 'Item Shop',
inventory: 'Inventory',
playerStats: 'player stats',
play: 'play game',
redeem: 'Redeem'
},
action : {
eggShackClick: 'Egg Shack Click',
eggShackProductClick: 'Egg Shack Product Click',
purchaseComplete: 'Purchase Complete',
goldenChickenProductClick: 'Golden Chicken Product Click',
goldenChickenNuggetClick: 'Golden Chicken Nugget Click',
shopClick: 'Shop Opened ',
shopItemClick: 'Shop Item Selected',
shopItemPopupClick: 'Shop Item Popup Click',
shopItemPopupBuy: 'Item purchased',
shopItemNeedMoreEggsPopup: 'Need More Eggs Popup',
inventorySelected: 'Inventory Item ',
eggCount: 'Egg Count',
inventoryTabClick: 'Inventory Opened',
playGameClick: 'Play Game Click',
redeemed: 'Redeemed',
redeemClick: 'Redeem open',
languageSwitch: 'Language setting change',
langBeforeUpdate: 'Language before auto detect',
privateGame: 'Private Game',
shareGamePopup: 'Share game Popup',
shareGameCopy: 'Shared game code',
createGame: 'Created game',
joinGame: 'Joined game',
playerLimit: 'Player limit',
timesPlayed: 'Times played',
anonymousPopupOpenAuto: 'Anon warning auto opened',
anonymousPopupOpen: 'Anon warning opened',
anonymousPopupSignupClick: 'Anon warning Sign in clicked',
anonymousPopupAgreeClick: 'Anon warning Understood clicked',
denyAnonUserPopup: 'Deny anon user popup',
denyAnonUserPopupSignin: 'sign in click',
faqPopupClick: 'FAQ popup open',
switchTeams: 'Switched Teams',
error: 'error',
signIn: 'Sign in'
},
label : {
signInClick: 'sign in click',
understood: 'Understood click',
getMoreEggs: 'Get More Eggs Click',
waitForGameReadyTimeout: 'waitForGameReady timeout',
signInAuthFailed: 'authorization failed',
signInTiming: 'Sign in delay',
signInCompleted: 'Completed',
signInOut: 'Signed out',
signInFailed: '',
homeToGameLoading: 'Home to game loading',
loading: 'Loading'
}
},
urlParams: null,
urlParamSet: null,
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21743024831/ShellShock_Video&description_url=__page-url__&env=vp&impl=s&correlator=&tfcd=0&npa=0&gdfp_req=1&output=vast&sz=640x480&unviewed_position_start=1',
eggStoreItems: [],
subStoreItems: [],
premiumShopItems: [],
eggStoreReferral: '',
eggStoreHasSale: false,
eggStorePopupSku: 'egg_pack_small',
showNugget: true,
// isMiniGameComplete: false,
miniEggGameAmount: 0,
showGoldenChicken: false,
nugStart: null,
nugCounter: null,
isBuyNugget: false,
adBlockerCountDown: 10,
controllerType: 'generic',
controllerId: '',
controllerButtonIcons: {
xbox: [
'A',
'B',
'X',
'Y',
'LB',
'RB',
'LT',
'RT',
'Select',
'Start',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
ps: [
'<img class="ss_buttonbind_icon" src="img/controller/button_cross.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_circle.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_square.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_triangle.svg">',
'LB',
'RB',
'LT',
'RT',
'Select',
'Start',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
switchpro: [
'B',
'A',
'Y',
'X',
'LB',
'RB',
'LT',
'RT',
'-',
'+',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
generic: [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15'
]
},
pwaDeferEvent: '',
blackFridayBanner: false,
isSale: false,
smallHouseAd: {},
bannerHouseAd: false,
showAdBlockerVideoAd: false,
hasMobileReward: false,
killName: null,
killedName: null,
killedByMessage: null,
killedMessage: null,
chicknWinnerWatched: null,
chicknWinnerCounter: 0,
chicknWinnerReady: false,
chicknWinnerDailyLimitReached: false,
isChicknWinnerError: false,
hasChwPlayClicked: false,
chwActiveTimer: 6000,
chwHomeTimer: null,
chwHomeEl: null,
contentCreator: false,
eggOrg: false
}</script>
<!-- Shared tags must come before the screen tags -->
<script id="events-template" type="text/x-template">
<div v-if="(doubleEggWeekendSoon || doubleEggWeekend) && showUi" id="event-notifications">
<div class="double-eggs">
<img v-if="doubleEggWeekendSoon && !doubleEggWeekend" src="img/events/shellshockers_doubleEgg01.png" alt="Double Egg weekend coming soon">
<img v-if="doubleEggWeekend" src="img/events/shellshockers_doubleEgg02.png" alt="Double Egg weekend now happening">
</div>
</div>
</script>
<script>
const comp_events = {
template: '#events-template',
props: ['show', 'owOn', 'showSoon', 'showUi'],
created() {
this.checkForEvents();
},
data: function () {
return vueData;
},
methods: {
isEventDate(days) {
const day = new Date().getUTCDay();
return days.includes(day);
},
doubbleEggSoon() {
return this.doubleEggWeekendSoon = this.isEventDate([4,5]);
},
doubleEggOn() {
const ISEVENT = this.isEventDate([5,6,0]);
if (!ISEVENT) {
return;
}
const DATE = new Date();
let day = DATE.getUTCDay();
if (day === 5) {
let time = DATE.getUTCHours();
if (time >= 20) {
return (
this.doubleEggWeekend = ISEVENT,
this.isEvent = ISEVENT
)
} else {
return (
this.doubleEggWeekend = false,
this.isEvent = false
)
}
} else {
return (
this.doubleEggWeekend = ISEVENT,
this.isEvent = ISEVENT
)
}
},
checkEvents() {
return (
this.doubbleEggSoon(),
this.doubleEggOn()
)
},
checkForEvents() {
this.checkEvents();
if (!this.doubleEggWeekend && this.isEventDate([4,5,6,0])) {
setTimeout(() => {
return this.checkForEvents();
}, 60000);
}
return;
},
},
};
</script><script>
var comp_light_overlay = {
template: `<transition name="fade">
<div id="lightOverlay" v-show="show" :class="overlayClass" class="overlay overlay_light"></div>
</transition>`,
data: function () {
return {
show: false,
overlayClass: '',
};
},
};
</script><script>
var comp_dark_overlay = {
template: `<transition name="fade">
<div id="darkOverlay" v-show="show" :class="overlayClass" class="overlay overlay_dark"></div>
</transition>`,
data: function () {
return {
show: false,
overlayClass: '',
};
},
};
</script><script id="spinner-overlay-template" type="text/x-template">
<transition name="fadeout">
<div v-show="isShowing" class="load_screen">
<h3 class="load_message">{{ header }}</h3>
<wobbly-egg></wobbly-egg>
<p class="load_message">{{ footer }}</p>
<display-ad :hidden="hideAds" id="div-gpt-ad-shellshockers-loading-houseads-wrap" ref="loadingScreenDisplayAd" :ignoreSize="true" :houseAd="true" adUnit="ShellShockers_LoadingScreen_HouseAds" adSize="728x90" :override="true" :adBlockerData="adblockerbanner"></display-ad>
</div>
</transition>
</script>
<script id="wobble-egg-template" type="text/x-template">
<div id="wobbly-egg">
<svg viewBox="0 0 240 240" :class="[loadEggcontainer, {noanimate: noAnimate}]" width="240" height="240" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient r="0.5" cy="0.4" cx="0.4" id="load_yolkgradient" spreadMethod="pad">
<stop stop-color="#fed" offset="0.3"/>
<stop stop-color="#fb0" offset="0.32"/>
<stop stop-color="#fa0" offset="1"/>
</radialGradient>
<filter id="load_eggshadow" :class="{noanimate: noAnimate}" x="-30%" y="-30%" width="160%" height="160%" >
<feDropShadow dx="0" dy="8" stdDeviation="8" flood-color="#124" flood-opacity="0.3" />
</filter>
</defs>
<g>
<path filter="url(#load_eggshadow)" :class="[loadEggwhite, {noanimate: noAnimate}]" stroke="#000" id="svg_eggwhite" d="m190.13055,40.86621c30.25552,23.71378 -12.26575,57.24017 0,81.77167c12.26575,24.5315 4.9063,80.13624 -33.52639,82.58939c-38.43269,2.45315 -55.60474,-26.16693 -94.03742,-17.98977c-38.43269,8.17717 -11.44803,-30.25552 -17.98977,-44.97442c-6.54173,-14.7189 -24.5315,-46.60985 -4.9063,-71.14135c9.8126,-12.26575 22.07835,-14.92333 34.95739,-15.02554c12.87904,-0.10221 19.01191,-15.63883 31.27766,-17.68312c12.26575,-2.04429 21.46506,17.58091 33.83303,11.2436c12.36797,-6.3373 35.26403,-20.64735 50.39179,-8.79045z" stroke-width="0" fill="#fff" />
</g>
<g>
<ellipse :class="[loadEggyolk, {noanimate: noAnimate}]" ry="38" rx="38" id="svg_eggyolk" cy="120" cx="120" stroke-width="0" fill="url(#load_yolkgradient)"/>
</g>
</svg>
</div>
</script>
<script>
var comp_wobbly_egg = {
template: '#wobble-egg-template',
props: ['noAnimate'],
data: function () {
return {
loadEggyolk: 'load_eggyolk',
loadEggwhite: 'load_eggwhite',
loadEggcontainer: 'load_eggcontainer'
}
}
};
</script>
<script>
var comp_spinner_overlay = {
template: '#spinner-overlay-template',
components: {
'wobbly-egg': comp_wobbly_egg
},
props: ['loc', 'adblockerbanner', 'hideAds'],
data: function () {
return {
isShowing: false,
header: '',
footer: '',
adIsShowing: false,
}
},
methods: {
show: function (headerLocKey, footerLocKey) {
this.header = this.loc[headerLocKey];
this.footer = this.loc[footerLocKey];
this.isShowing = true;
},
showSpinnerLoadProgress: function (percent) {
var msg = this.loc['ui_game_loading'];
this.header = this.loc['building_map'];
this.footer = '{0}... {1}%'.format(msg, percent);
this.isShowing = true;
},
hide: function () {
this.isShowing = false;
this.$emit('close-display-ad');
},
hideDisplayAd() {
this.adIsShowing = false;
console.log('do it');
},
showDisplayAd() {
this.adIsShowing = true;
},
toggleDisplayAd() {
return this.adIsShowing = this.adIsShowing ? false : true;
}
},
};
</script><script id="small-popup-template" type="text/x-template">
<transition name="fade">
<div v-show="isShowing" class="popup_window popup_sm roundme_lg centered">
<div>
<button v-show="!hideClose" @click="onXClick" class="popup_close roundme_sm clickme"></button>
<h3 id="popup_title" v-show="!hideHeader" class="roundme_sm shadow_blue4 nospace">
<slot name="header"></slot>
</h3>
</div>
<div v-show="!hideContent" class="popup_sm_content"><slot name="content"></slot></div>
<div id="btn_horizontal" class="f_center">
<button class="ss_button btn_red bevel_red width_sm" v-show="!hideCancel" @click="cancelClick"><slot name="cancel"></slot></button>
<button class="ss_button btn_green bevel_green width_sm" v-show="!hideConfirm" @click="confirmClick"><slot name="confirm"></slot></button>
</div>
</div>
</transition>
</script><iframe marginwidth="0" marginheight="0" scrolling="no" frameborder="0" id="1021bcc777d444" width="0" height="0" src="about:blank" name="__pb_locator__" style="display: none; height: 0px; width: 0px; border: 0px;"></iframe>
<script type="text/javascript" id="" charset="">!function(b,e,f,g,a,c,d){b.fbq||(a=b.fbq=function(){a.callMethod?a.callMethod.apply(a,arguments):a.queue.push(arguments)},b._fbq||(b._fbq=a),a.push=a,a.loaded=!0,a.version="2.0",a.queue=[],c=e.createElement(f),c.async=!0,c.src=g,d=e.getElementsByTagName(f)[0],d.parentNode.insertBefore(c,d))}(window,document,"script","https://connect.facebook.net/en_US/fbevents.js");fbq("init","446896919250308");fbq("track","PageView");</script>
<noscript>
<img height="1" width="1" src="https://www.facebook.com/tr?id=446896919250308&ev=PageView
&noscript=1">
</noscript>
<script id="large-popup-template" type="text/x-template">
<transition name="fade">
<div id="popupPause" v-show="isShowing" class="popup_window popup_lg centered roundme_lg">
<button @click="onXClick" v-show="!hideClose" class="popup_close clickme roundme_sm"></button>
<slot name="content"></slot>
</div>
</transition>
</script>
<script>
// Register popup components globally
Vue.component('small-popup', createPopupComponent('#small-popup-template'));
Vue.component('large-popup', createPopupComponent('#large-popup-template'));
function createPopupComponent(templateId) {
return {
template: templateId,
props: ['hideHeader', 'hideContent', 'hideClose', 'hideCancel', 'hideConfirm', 'overlayType', 'overlayClass', 'popupModel', 'uiModel', 'stopKeyCapture', 'overlayClose'],
data: function () {
return {
isShowing: false,
overlays: vueData.ui.overlayType,
popupId: '',
removeOverlayClick: ''
}
},
created() {
this.popupId = this.$attrs && this.$attrs.id;
},
destroyed: function() {
document.removeEventListener('keyup', this.escapeKeyClose);
},
methods: {
setVisible: function (visible) {
this.isShowing = visible;
if (this.stopKeyCapture && extern.inGame) {
if (this.isShowing) {
extern.releaseKeys();
} else {
extern.captureKeys();
}
}
if (this.isShowing && this.popupModel && this.popupModel.reset) {
this.popupModel.reset();
}
if (!this.isShowing || this.overlayType === this.overlays.none) {
vueApp.setDarkOverlay(false);
vueApp.setLightOverlay(false);
} else {
vueApp.setDarkOverlay(this.overlayType === undefined || this.overlayType === this.overlays.dark, this.overlayClass);
}
if (!this.isShowing) {
console.log('Closed: ' + this.popupId);
this.$emit('popup-closed');
vueApp.gameUiRemoveClassForNoScroll();
this.cancelEventOverLayClickEscapeClose();
} else {
console.log('Opened: ' + this.popupId);
this.$emit('popup-opened');
vueApp.scrollToTop();
vueApp.gameUiAddClassForNoScroll();
this.outsideClickClose();
}
if (!extern.inGame) {
vueApp.toggleTitleScreenAd();
}
},
toggle: function () {
this.isShowing = !this.isShowing;
this.setVisible(this.isShowing);
},
show: function () {
this.setVisible(true);
},
hide: function () {
this.setVisible(false);
},
close: function () {
this.setVisible(false);
console.log('Closing');
},
onCloseClick: function () {
this.close();
BAWK.play('ui_popupclose');
},
onXClick: function () {
this.$emit('popup-x');
this.close();
BAWK.play('ui_popupclose');
},
cancelClick: function () {
this.close();
this.$emit('popup-cancel');
BAWK.play('ui_popupclose');
},
confirmClick: function () {
if (this.popupModel && this.popupModel.validate && !this.popupModel.validate()) {
return;
}
this.close();
this.$emit('popup-confirm');
BAWK.play('ui_playconfirm');
},
outsideClickClose: function() {
if (this.overlayClose === false) {
return;
}
this.removeOverlayClick = this.handleOutsideClick;
document.addEventListener('click', this.removeOverlayClick);
document.addEventListener('keyup', this.escapeKeyClose);
},
escapeKeyClose: function(e) {
e.stopPropagation();
if (e.keyCode === 27 && this.isShowing && this.overlayClose !== false) {
this.onCloseClick();
}
},
handleOutsideClick: function(e) {
e.stopPropagation();
if ( e.target.id.includes('Overlay') ) {
this.onCloseClick();
}
},
cancelEventOverLayClickEscapeClose: function() {
if (this.overlayClose === false) {
return;
}
document.removeEventListener('click', this.removeOverlayClick);
document.removeEventListener('keyup', this.escapeKeyClose);
}
},
}
}
</script>
<template id="house-display-ad">
<transition name="fade">
<figure v-if="isshowing && data" class="house-wrap">
<img :src="src" :alt="title" @click="adClicked">
</figure>
</transition>
</template>
<script>
function createHouseAd() {
return {
template: '#house-display-ad',
props: ['isshowing', 'data'],
data() {
return {
count: 0
}
},
methods: {
adClicked() {
if ('link' in this.data) {
this.data.link = this.data.link + '/?utm_source=shell_shockers&utm_medium=referral&utm_campaign=house-ads';
}
extern.clickedHouseLink(this.data);
}
},
computed: {
src() {
return dynamicContentPrefix + `data/img/art/${this.data.id}${this.data.imageExt}`;
},
alt() {
return `${this.data.label} banner image!`;
},
link() {
return `${this.data.link}/?utm_source=shell_shockers&utm_medium=referral&utm_campaign=house-ads`;
},
title() {
return `Play ${this.data.label} now!`;
}
}
}
}
Vue.component('house-ad', createHouseAd());
</script><script id="display-ad-template" type="text/x-template">
<div>
<div v-if="!hidden" v-show="isAdShowing" :id="id" class="display-ad-container" :class="theClass"></div>
<house-ad :data="houseAdData" :isshowing="isAdShowing && houseAdData && adBlocker"></house-ad>
</div>
</script>
<script>
// Register popup components globally
Vue.component('display-ad', createDisplayAdComponent('#display-ad-template'));
function createDisplayAdComponent(templateId) {
return {
template: templateId,
props: {
id: String,
hidden: Boolean,
adUnit: String,
isHidden: Boolean,
poki: Boolean,
adSize: String,
override: Boolean,
houseAd: Boolean,
ignoreSize: Boolean,
},
data: function () {
return {
isAdShowing: false,
hideAds: false,
theAd: '',
adRefreshCheck: false,
houseAdData: '',
adBlocker: false,
}
},
mounted() {
this.$nextTick(() => {
this.getTheAd();
});
this.override = this.override || false;
},
methods: {
getTheAd() {
this.theAd = document.getElementById(this.adUnit);
if (pokiActive || extern.productBlockAds) {
return;
}
const wrap = document.getElementById(this.id);
wrap.appendChild(this.theAd);
if (this.houseAd && !crazyGamesActive && !pokiActive) {
googletag.cmd.push(function() { googletag.display('ShellShockers_LoadingScreen_HouseAds') });
}
},
setVisible(visible) {
if (vueData.isUpgraded) {
console.log('Upgrade hides ads');
this.isAdShowing = false;
return;
}
if (extern.productBlockAds) {
console.log('Closure hides ads');
this.isAdShowing = false;
return;
};
this.isAdShowing = visible;
if (!this.isAdShowing) {
window.removeEventListener('resize', this.hideAdBasedOnscreenSize);
// this.adVisibility();
if (pokiActive && this.adSize) PokiSDK.destroyAd(this.$el);
return;
} else {
this.triggerAd();
setTimeout(() => this.hideAdBasedOnscreenSize(), 500);
// this.adVisibility();
window.addEventListener('resize', this.hideAdBasedOnscreenSize);
return;
}
},
show() {
if (extern.productBlockAds) return;
console.log(`display ad ${this.id} showing`);
this.setVisible(true);
},
hide() {
this.setVisible(false);
console.log(`display ad ${this.id} hiding`);
},
crazyGamesAd(id, size) {
// Removing delay per CG's request. Refresh rate is restricted server-side
/*if (this.adRefreshCheck) return;
this.adRefreshCheck = true;
setTimeout(() => this.adRefreshCheck = false, 20000);*/
crazysdk.requestBanner([{
containerId: id,
size: size
}]);
},
triggerAd() {
this.adBlocker = extern.adBlocker;
if (this.adBlocker) {
this.adblockerSetup();
return;
}
if (!pokiActive && !crazyGamesActive && !testCrazy) {
if (this.houseAd) {
gtagInHouseLoadingBanner();
return;
}
aiptag.cmd.display.push(() => aipDisplayTag.display(this.adUnit));
return;
} else if (crazyGamesActive || testCrazy) {
// since crazy games requires an array for multiple ads on screen will cancel the respawn
// ad calls and call them elsewhere
if (this.id === 'shellshockers_respawn_banner_ad' ||
this.id === 'shellshockers_respawn_banner_2_ad' ||
this.id === 'shellshockers_respawn_banner-new_ad') return;
this.crazyGamesAd(this.id, this.adSize);
return;
} else if (pokiActive && this.adSize) {
PokiSDK.displayAd(this.$el, this.adSize);
return;
}
},
toggleAd() {
if (extern.productBlockAds) {
this.isAdShowing = false;
return;
};
this.$nextTick(() => {
if (this.isAdShowing) {
return this.isAdShowing = false;
}
return this.isAdShowing = true;
});
},
adblockerSetup() {
switch(this.id) {
case 'div-gpt-ad-shellshockers-loading-houseads-wrap':
case 'shellshockers_respawn_banner_ad':
case 'shellshockers_respawn_banner-new_ad':
this.houseAdData = extern.getHouseAd('bigBanner');
break;
case 'shellshockers_respawn_banner_2_ad':
case 'shellshockers_titlescreen_wrap':
this.houseAdData = extern.getHouseAd('small');
break;
default:
console.log('House ads say, huh?');
}
},
hideAdBasedOnscreenSize() {
let adWidth = this.$el.offsetWidth;
let intViewportWidth = window.innerWidth;
if (vueApp.displayAdObject && vueApp.displayAdObject > 1 ) {
if (vueApp.displayAdObject < 970) {
return;
}
if (vueApp.displayAdObject > intViewportWidth ) {
this.hide();
}
} else {
if (adWidth < 970) {
return;
}
if (adWidth > intViewportWidth ) {
this.hide();
}
}
},
adVisibility() {
if (this.ignoreSize) return;
googletag.pubads().addEventListener('slotVisibilityChanged', event => {
if (event.inViewPercentage < 51) {
this.hide();
} else {
this.show();
}
}
);
}
},
computed: {
theClass() {
return this.adUnit.toLowerCase().replace(/_/g, "-");
}
},
watch: {
isHidden(value) {
if (!value) {
this.hide();
}
},
}
}
}
</script>
<script><!DOCTYPE html>
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
var gameServerRoot = null;
var dynamicContentRoot = null;
var dynamicContentPrefix = '';
</script>
<script>
class Loader {
static show () {
let container = document.createElement('div');
container.id = 'progress-container';
container.style = `
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
z-index: 2000;
background-image: var(--ss-lightoverlay);
`;
const progressWrapper = document.createElement('div');
progressWrapper.id = 'progress-wrapper';
progressWrapper.className = 'load_screen';
progressWrapper.style = `
position: absolute;
left: 50%;
top: -6em;
transform: translateX(-50%);
background-image: none;
`;
const blueWizLogo = document.createElement('img');
blueWizLogo.src = 'img/BlueWizard-Logo-min.png';
blueWizLogo.style=`
width: 16em;
display: block;
margin: 5em auto 0;
z-index: 2000;
position: absolute;
left: 50%;
bottom: 8em;
transform: translateX(-50%);
`;
let logo = document.createElement('img');
logo.src = 'img/logo.svg';
logo.style = 'height: 16em';
logo.id = 'logo-svg';
// container.appendChild(logo);
const progressOuter = document.createElement('div');
progressOuter.id = 'progress-outer';
progressOuter.style = `
position: relative;
background: #643219;
border-radius: 2em;
height: 3.3em;
width: 24em;
margin-top: 2em;
`;
let progress = document.createElement('div');
progress.style = `
margin-top: 1em;
width: 23em;
height: 2.2em;
background: white;
padding: 0.5em;
border-radius: 2em;
margin: .3em .5em 0;
`;
container.appendChild(progress);
let progressBar = document.createElement('span');
progressBar.id = 'progressBar';
progressBar.style = `
display: block;
width: 20%;
height: 100%;
background: orange;
border-radius: 2em;
margin-left: 80%;
margin: 0 .3em .5em 0;
opacity: 0;
transition: margin-left linear 500ms;
transition-timing-function: ease-in-out;
`;
const progressBarOutside = document.createElement('div');
progress.appendChild(progressBar);
progressWrapper.appendChild(logo);
progressOuter.appendChild(progress);
progressWrapper.appendChild(progressOuter);
container.appendChild(progressWrapper);
container.appendChild(blueWizLogo);
// Minor for the progress bar intial load
setTimeout(() => progressBar.style.opacity = 1, 600);
Loader.barInterval = setInterval(() => {
if (Loader.progressBar.style.marginLeft == '0%') {
Loader.progressBar.style.marginLeft = '80%';
}
else {
Loader.progressBar.style.marginLeft = '0%';
}
}, 500);
Loader.progressBar = progressBar;
Loader.container = container;
let app = document.body;
app.appendChild(container);
}
static hide () {
Loader.container.style = "opacity : 0; transition: opacity 1s;";
setTimeout(() => { Loader.container.remove(); }, 1000);
}
static addTask () {
let id = Loader.loaded.length;
//console.log('Loading tasks: ', ++Loader.actualTasks);
Loader.loaded.push(0);
return id;
}
static finish (id) {
clearInterval(Loader.barInterval);
if (Loader.progressBar) {
Loader.progressBar.style.marginLeft = '0%';
Loader.progressBar.style.transition = '';
Loader.loaded[id] = 1;
Loader.updateBar();
}
}
static progress (id, value, total) {
clearInterval(Loader.barInterval);
if (Loader.progressBar) {
Loader.progressBar.style.marginLeft = '0%';
Loader.progressBar.style.transition = '';
Loader.loaded[id] = value / total;
Loader.updateBar();
}
return id;
}
static updateBar () {
let loadedTotal = 0;
for (let l of Loader.loaded) {
loadedTotal += l;
}
Loader.progressBar.style.width = loadedTotal / Loader.tasks * 95 + 5 + '%';
}
static loadJS (path, callback) {
let p = path;
(function (p, cb) {
let xhr = new XMLHttpRequest();
xhr.open('GET', p, true);
let id = Loader.addTask();
xhr.onprogress = event => {
if (Loader.progressBar) {
id = Loader.progress(id, event.loaded, event.total);
}
};
xhr.onload = () => {
if (xhr.status != 200) {
console.log(`Error ${xhr.status}: ${xhr.statusText}`);
}
else {
Loader.finish(id);
let script = document.createElement('script');
script.innerHTML = xhr.response;
document.body.appendChild(script);
if (cb) cb();
}
};
xhr.send();
})(path, callback);
}
}
Loader.actualTasks = 0;
Loader.tasks = 16;
Loader.loaded = [];
window.Loader = Loader;
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
function openFirebaseDb () {
return new Promise((resolve, reject) => {
let req = window.indexedDB.open('firebaseLocalStorageDb');
req.onsuccess = () => {
let db = req.result;
let transaction = db.transaction(['firebaseLocalStorage'], 'readwrite');
let store = transaction.objectStore('firebaseLocalStorage');
resolve({ db, store });
}
req.onerror = err => reject(err);
req.onupgradeneeded = () => {
let db = req.result;
let store = db.createObjectStore('firebaseLocalStorage', { keyPath: 'fbase_key' });
resolve({ db, store });
}
});
}
var redirectIframe
function postStorageAndRedirect (iframe, storage, firebaseDb) {
iframe.contentWindow.postMessage({ storage, firebaseDb }, '*');
window.location = 'https://shellshock.io' + window.location.search + window.location.hash;
}
window.addEventListener('DOMContentLoaded', () => {
Loader.show();
});
</script><!-- title, seo meta and favicons -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="facebook-domain-verification" content="6lfua33vx0abiv1asnt9p13aac29xy" />
<!-- <link rel="manifest" href="manifest.json"> -->
<title>Shell Shockers | Alt URL: geometry.best.</title>
<meta name="Description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs.">
<meta name="Keywords" content="Play, Free, Online, Multiplayer, Games, IO, ShellShockers, Shooter, Bullets, Top Down">
<meta name="author" content="Blue Wizard Digital">
<meta name="theme-color" content="#0B93BD" />
<meta name="background-color" content="#0B93BD" />
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="favicon192.png" sizes="192x192" />
<link rel="icon" href="https://shellshock.io/favicon256.png" sizes="512x512" />
<meta property="og:url" content="https://www.shellshock.io" />
<meta property="og:type" content="website" />
<meta property="og:image:width" content="1000" />
<meta property="og:image:height" content="500" />
<meta property="og:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg" />
<meta name="image" property="og:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg" />
<meta property="og:title" content="Shell Shockers | by Blue Wizard Digital" />
<meta property="og:description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs." />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@eggcombat">
<meta name="twitter:creator" content="@eggcombat">
<meta name="twitter:title" content="Shell Shockers | by Blue Wizard Digital">
<meta name="twitter:description" content="Alt URL: geometry.best. Shell Shockers, the world's most advanced egg-based multiplayer shooter! It's like your favorite battlefield game but... with eggs.">
<meta name="twitter:image" content="https://www.shellshock.io/img/previewImage_shellShockers.jpg">
<!-- Styles & Fonts -->
<link href="https://fonts.googleapis.com/css?family=Sigmar+One|Nunito:100,200,600,700,900" rel="stylesheet">
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="styles/transitions.css%3F1651709060.css">
<link rel="stylesheet" href="styles/forms.css%3F1651709060.css">
<link rel="stylesheet" href="styles/style.css%3F1654110505.css">
<link rel="stylesheet" href="styles/game.css%3F1653069567.css"><script>
function storageFactory(getStorage) {
const inMemoryStorage = {};
function isSupported() {
try {
var testKey = "__some_random_key_you_are_not_going_to_use__";
getStorage().setItem(testKey, testKey);
getStorage().removeItem(testKey);
return true;
} catch (e) {
return false;
}
}
function clear() {
if (isSupported()) {
getStorage().clear();
} else {
inMemoryStorage = {};
}
}
function getItem(name) {
if (isSupported()) {
return getStorage().getItem(name);
}
if (inMemoryStorage.hasOwnProperty(name)) {
return inMemoryStorage[name];
}
return null;
}
function key(index) {
if (isSupported()) {
return getStorage().key(index);
} else {
return Object.keys(inMemoryStorage)[index] || null;
}
}
function removeItem(name) {
if (isSupported()) {
getStorage().removeItem(name);
} else {
delete inMemoryStorage[name];
}
}
function setItem(name, value) {
if (isSupported()) {
getStorage().setItem(name, value);
} else {
inMemoryStorage[name] = String(value);
}
}
function length() {
if (isSupported()) {
return getStorage().length;
} else {
return Object.keys(inMemoryStorage).length;
}
}
return {
getItem: getItem,
setItem: setItem,
removeItem: removeItem,
clear: clear,
key: key,
get length() {
return length();
}
};
}
const localStore = storageFactory(() => localStorage);
const sessionStore = storageFactory(() => sessionStorage);
</script><style>
.eggIcon {
display: inline-block;
color: #444444;
width: 1em;
height: 1em;
fill: currentColor;
}
</style>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-egg" viewBox="0 0 14.59 18.12">
<path class="eggFill" d="M14.49,10.79c0-3.96-3.02-10.66-6.98-10.66s-7.36,6.7-7.36,10.66s3.21,7.17,7.17,7.17S14.49,14.75,14.49,10.79z"></path>
</symbol>
</defs>
</svg>
<style>
.eggIconLocked {
display: inline-block;
color: #444444;
width: 1em;
height: 1em;
fill: currentColor;
}
</style>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-egg-locked" viewBox="0 0 14.59 18.12">
<g>
<path class="st0" d="M7.3,5.4c-0.6,0-1.1,0.5-1.1,1.1v1.3h2.2V6.5C8.4,5.9,7.9,5.4,7.3,5.4z"/>
<path class="st0" d="M7.5,0.1c-4,0-7.4,6.7-7.4,10.7S3.4,18,7.3,18c3.9,0,7.2-3.2,7.2-7.2S11.5,0.1,7.5,0.1z M11.3,12.5
c0,0.9-0.7,1.6-1.6,1.6H4.8c-0.9,0-1.6-0.7-1.6-1.6V7.8h1.5V6.5C4.8,5.1,5.9,4,7.3,4c1.4,0,2.5,1.1,2.5,2.5v1.3h1.5V12.5z"/>
</g>
</symbol>
</defs>
</svg><!-- ParsedURL -->
<script>
var parsedUrl = (function parseUrl () {
var url = {};
var loc = window.location;
url.root = loc.origin + loc.pathname;
var query = loc.search.substring(1).split('&');
url.query = {};
for (let i = 0; i < query.length; i++) {
var arr = query[i].split('=');
if (arr[0]) {
if (arr[1] === undefined) {
arr[1] = true;
} else if (!isNaN(arr[1])) {
arr[1] = parseFloat(arr[1]);
}
url.query[arr[0]] = arr[1];
}
}
url.hash = loc.hash.substring(1);
var host = loc.host.split('.');
url.dom = host[0];
url.top = host[1];
if (url.hash.length == 0) url.hash = undefined;
return url;
})();
</script>
<!-- third party globals -->
<script>
// Third party globals
var crazysdk = {inviteLink: function () {}},
pokiActive = false,
crazyGamesActive = false,
thirdPartyAdblocker = false,
testCrazy = false;
</script><!-- Crazy Games -->
<script src="https://sdk.crazygames.com/crazygames-sdk-v1.js"></script>
<script type="text/javascript">
const crazyAdDetect = (e) => {
if (e.hasAdblock) {
thirdPartyAdblocker = true;
}
};
// const crazyInitialized = (e) => {
// console.log('INITIALIZED: ', e);
// };
if (window.CrazyGames && CrazyGames.CrazySDK) {
const { CrazySDK } = window.CrazyGames;
crazysdk = CrazySDK.getInstance(); //Getting the SDK
crazysdk.addEventListener('bannerRendered', (e) => {
console.log(`Banner for container ${e.containerId} has been rendered!`);
});
crazysdk.addEventListener('bannerError', (e) => {
console.log(`Banner render error: ${e.error}`);
if (e.containerId === 'shellshockers_respawn_banner_2_ad' || e.containerId === 'shellshockers_respawn_banner-new_ad') {
// We only reset the timeout if both banners fail during the same request
if (++vueData.cGrespawnBannerErrors >= 2) {
vueData.cGrespawnBannerErrors = 0;
if (vueData.cGrespawnBannerTimeout) {
clearTimeout(vueData.cGrespawnBannerTimeout);
vueData.cGrespawnBannerTimeout = null;
}
}
}
});
// crazysdk.addEventListener('initialized', crazyInitialized);
crazysdk.addEventListener('adblockDetectionExecuted', crazyAdDetect);
crazysdk.init(); //Initializing the SDK, call as early as possible
}
if (parsedUrl.query.testCrazy) {
testCrazy = true;
}
</script><!-- European Union detection -->
<script>isFromEU = 0 ? true : false</script>
<!-- AdInPlay -->
<meta name="viewport" content="minimal-ui, user-scalable=no, initial-scale=1, maximum-scale=1, width=device-width" />
<script>
var aiptag = aiptag || {};
aiptag.cmd = aiptag.cmd || [];
aiptag.cmd.display = aiptag.cmd.display || [];
aiptag.cmd.player = aiptag.cmd.player || [];
</script>
<script async src="https://api.adinplay.com/libs/aiptag/pub/SSK/shellshock.io/tag.min.js"></script>
<!-- GTM -->
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-K5MSJHJ');</script>
<!-- End Google Tag Manager --><!-- In house ads -->
<script>
window.googletag = window.googletag || {cmd: []};
let inHouseSlot;
const slots = [];
const dpfNetwork = /21743024831/,
inHouseAdSlot = 'ShellShockers_LoadingScreen_HouseAds'
inHouseAdSize = [[468, 60], [970, 90], [970, 250], [728, 90]],
inHouseAdDiv = 'ShellShockers_LoadingScreen_HouseAds',
adSlots = [];
// Helper to setup slots and add to slot array
const adDefineSlot = (slot, sizes, id) => {
return adSlots.push([{slot, sizes, id}]);
};
// Defining the slots for the the array
const loadingScreeningAd = adDefineSlot(inHouseAdSlot, inHouseAdSize, inHouseAdDiv);
// Helper to add slots to google service
function addServiceToSlot() {
slots.forEach(slot => {
slot.addService(googletag.pubads());
});
}
// Get all the slots, add to google ad defineSlot method
function getAllDefinedSlots(allSlots) {
let definedSlots = [];
allSlots.forEach(adSlot => {
for (var i = 0, len = adSlot.length; i < len; i++) {
slots.push(googletag.defineSlot(dpfNetwork + adSlot[i].slot, adSlot[i].sizes, adSlot[i].id));
}
})
return addServiceToSlot(slots);
}
const gtagInHouseLoadingBannerIntialLoad = () => {
if (typeof hasPoki !== 'undefined') {
console.log('haspoki', typeof(hasPoki));
return;
}
googletag.cmd.push(function() {
getAllDefinedSlots(adSlots);
googletag.pubads().disableInitialLoad();
googletag.enableServices();
});
};
gtagInHouseLoadingBannerIntialLoad();
const adRenderedEvent = () => {
return googletag.pubads().addEventListener('slotRenderEnded', (event) => {
vueApp.disaplyAdEventObject(event);
});
};
const gtagInHouseLoadingBanner = () => {
googletag.cmd.push(function() {
googletag.pubads().refresh([slots[0]]);
adRenderedEvent();
});
};
const destroyInhouseAdForPaid = () => {
googletag.destroySlots([slots[0]]);
};
</script><!-- Firebase -->
<script src="https://www.gstatic.com/firebasejs/7.21.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.21.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/ui/4.6.1/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.6.1/firebase-ui-auth.css" />
<!-- Facebook -->
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '771186996377132');
fbq('track', 'PageView');
</script>
<noscript>
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=771186996377132&ev=PageView&noscript=1"/>
</noscript>
<!-- DO NOT MODIFY -->
<!-- End Facebook Pixel Code -->
<!-- OneSignal -->
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
var osAppId = 'dae68bc6-167c-4012-8644-90fe9db39950';
if (!location.hostname.startsWith('shellshock')) {
if (location.hostname.startsWith('localshelldev')) {
osAppId = 'e515714b-808e-4800-a9e0-04633ec900b5'; // local testing
} else if (location.hostname.startsWith('dev')) {
osAppId = '20bd47ca-cce1-428e-b34f-1a240f643112'; // dev testing
} else if (location.hostname.startsWith('localhost')) {
osAppId = '884bfbf7-5bcb-4170-9bf4-bba6b6e0046e';// localhost testing
} else {
osAppId = '166e17cb-5c02-4c7d-8bff-8ec69729f725'; // internal testing
}
}
var OneSignal = window.OneSignal || [];
OneSignal.push(function() {
OneSignal.init({
appId: osAppId,
// autoResubscribe:true,
// allowLocalhostAsSecureOrigin: true
});
});
</script><!-- progressive web app -->
<!-- <button id="addToHomescreen" style="z-index:333;display: none; position:absolute; top:0px; right: 75%; cursor:pointer;" class="ss_button btn_yolk bevel_yolk">Add to your desktop!</button> -->
<script>
let pwaBlockAds = false;
// if ('serviceWorker' in navigator) {
// console.log("Will the service worker register?");
// navigator.serviceWorker.register('service-worker.js')
// .then(function(reg){
// console.log("Yes, it did.");
// }).catch(function(err) {
// console.log("No it didn't. This happened:", err)
// });
// }
if (window.matchMedia('(display-mode: standalone)').matches) {
pwaBlockAds = 'utm_source' in parsedUrl.query && parsedUrl.query.utm_source === 'homescreen';
ga('send', 'event', 'pwa', 'desktop opened');
}
</script>
<!-- Music audio tag -->
<audio id="theAudio" preload="metadata"></audio><!-- VueJS -->
<script src="js/vue/vue.min.2.6.10.js"></script><!-- tools and varibles -->
<script>
let changeLogData;
var version;
fetch('./changelog/changelog.json?1653515333', {cache: "no-cache"})
.then(response => response.json())
.then(data => {
changeLogData = data;
version = changeLogData[0].version;
});
localStore.removeItem('brbTime');
String.prototype.format = String.prototype.f = function() {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
function getKeyByValue (obj, value) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (obj[prop] === value) {
return prop;
}
}
}
}
function objToStr (obj) {
var str = JSON.stringify(obj, null, 4).replace(/\\|"/g, '');
//str = str.replace(/\\|"/g, '');
return str;
}
function detectChromebook() {
return /\bCrOS\b/.test(navigator.userAgent);
}
function removeChildNodes (name) {
var myNode = document.getElementById(name);
while (myNode.firstChild) {
myNode.removeChild(myNode.firstChild);
}
}
function logCallStack() {
var stack = new Error().stack;
console.log(stack);
}
function getRequest (url, callback) {
if (url.startsWith('./')) url = url.slice(2);
url = dynamicContentPrefix + url;
var req = new XMLHttpRequest();
if (!req) {
return false;
}
if (typeof callback != 'function') callback = function () {};
req.onreadystatechange = function(){
if(req.readyState == 4) {
return req.status === 200 ?
callback(null, req.responseText) : callback(req.status, null);
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
function hasValue (a) {
return (a !== undefined && a !== null && a !== 0);
}
Array.prototype.shallowClone = function() {
return this.slice(0);
}
function deepClone (o) {
return JSON.parse(JSON.stringify(o));
}
function isString (value) {
return typeof value === 'string' || value instanceof String;
}
const theTimeTracker = (startTime, gaVar, gaLabel) => {
const endTime = new Date();
const timerResult = endTime - startTime;
if (!Number.isInteger(timerResult) && !timerResult ) {
return;
}
return ga('send', 'timing', vueData.googleAnalytics.cat.playerStats, gaVar, timerResult, gaLabel);
};
const isShellIframe = () => window.self === window.top;
const iframeParent = () => {
const parent = (window.location != window.parent.location)
? document.referrer
: document.location.href,
domain = new URL(parent).hostname.replace(/(www.)/, '').split('.');
if (!Array.isArray(domain) && !domain.length) {
return false;
}
const index = domain.length - 2;
return {
domain: domain,
index: index,
};
};
const iframeWhitelist = (domains) => {
if (isShellIframe()) {
return;
}
const parent = iframeParent(),
domain = parent.domain,
index = parent.index;
// if in iframe and url hostname is in approved whitelist return true or false if not in list
return domains.includes(domain[index]) || domains.includes(domain[index - 1]);
};
const playShellshockers = () => {
//if not in a iframe return true
if (isShellIframe()) {
console.log('Not playing in iframe');
return true;
}
console.log('Playing in iframe');
const gamePortals = [
'poki',
'poki-gdn',
'poki.compoki',
'games.poki',
'crazygames',
'1001juegos',
'ioground',
'gogy',
'playgamesio',
'iogames',
'iogames',
'wingsiofree',
'vseigru',
'miniclip',
'red-ball4',
'speelspelletjes',
'onlinegame',
'addictinggames'
];
const parent = iframeParent(),
domain = parent.domain,
index = parent.index;
// if in iframe and url hostname is in approved whitelist return true or false if not in list
//return gamePortals.includes(domain[index]) || gamePortals.includes(domain[index - 1]);
return true; // Disabling this for now because server outages caused everyone to be blacklisted for some insane, currently unknown reason.
};
const capitalize = (s) => {
if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1)
};
var servers = [
{ name: 'US East', subdom: 'useast2.', locKey: 'server_useast', id: 'us-e1' },
{ name: 'US West', subdom: 'uswest2.', locKey: 'server_uswest', id: 'us-w1' },
{ name: 'US Central', subdom: 'uscentral2.', locKey: 'server_uscentral', id: 'us-c1' },
{ name: 'Brazil', subdom: 'brazil2.', locKey: 'server_brazil', id: 'br-1' },
{ name: 'Germany', subdom: 'frankfurt.', locKey: 'server_germany', id: 'de-1' },
{ name: 'Singapore', subdom: 'singapore2.', locKey: 'server_singapore', id: 'si-1' },
{ name: 'Sydney', subdom: 'sydney.', locKey: 'server_sydney', id: 'au-1' },
];
var debug = false;
var servicesServer = 'wss://' + window.location.hostname + '/services/';
const isLocalShellDev = location.hostname.startsWith('localshelldev'),
isLocalHost = location.hostname.startsWith('localhost');
if (dynamicContentRoot) {
servicesServer = 'wss://' + dynamicContentRoot + '/services/';
}
else if (isLocalHost || isLocalShellDev) {
servicesServer = isLocalHost ? 'ws://localhost:4242' : 'ws://localshelldev.bluewizard.com:4242/';
debug = true;
if (isLocalShellDev)
servers.push({ name: 'Local VM', subdom: 'localshelldev.', root: 'bluewizard.com', locKey: 'server_localshelldev', id: 'lucyskydiamonds' });
servers.push({ name: 'local', subdom: '', locKey: '_server_local', id: 'local' });
servers.push({ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_gamedev', id: 'gamedev' });
}
else if (location.hostname.startsWith('staging.shellshock.io')) {
debug = true;
servers = [{ name: 'Staging', subdom: 'staging.', locKey: 'server_staging', id: 'staging' }];
var servicesServer = 'wss://staging.shellshock.io:8443/services/';
}
if (location.search.includes('portalTest')) {
gameServerRoot = 'shellshock.io';
dynamicContentRoot = 'dev.shellshock.io';
dynamicContentPrefix = 'https://dev.shellshock.io/';
servers = [{ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_dev', id: 'dev' }];
}
if (!dynamicContentRoot && location.hostname.startsWith('dev.shellshock.io') || dynamicContentRoot == 'dev.shellshock.io') {
servers = [{ name: 'Dev (US West)', subdom: 'gamedev.', locKey: 'server_dev', id: 'dev' }];
servicesServer = 'wss://dev.shellshock.io/services/';
}
function getGameServerUrl (server) {
// Dump the www from the hostname if it exists
var hostname = window.location.hostname;
var fields = hostname.split('.');
if (fields.length > 2) {
hostname = fields[1] + '.' + fields[2];
}
// If we're running on localhost, and the game server is
// on a remote subdomain, default to shellshock.io domain
var rootName = server.root || hostname;
if (server.subdom && rootName == 'localhost') {
rootName = 'shellshock.io';
}
var subdom = server.subdom || '';
if (gameServerRoot) rootName = gameServerRoot;
if (server.subdom == '' && rootName === 'localhost' || rootName === 'bluewizard.com') {
return 'ws://' + subdom + rootName + ':4430';
} else {
return 'wss://' + subdom + rootName;
}
}
function getServerIndex (server) {
return servers.map(s => s.id).indexOf(server.id);
}
function getStoredNumber (name, def) {
var num = localStore.getItem(name);
if (!num) {
return def;
}
return Number(num);
}
function getStoredBool (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return str == 'true' ? true : false;
}
function getStoredString (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return str;
}
function getStoredObject (name, def) {
var str = localStore.getItem(name);
if (!str) {
return def;
}
return JSON.parse(str);
}
var shellColors = [
'#ffffff',
'#c4e3e8',
'#e2bc8b',
'#d48e52',
'#cb6d4b',
'#8d3213',
'#5e260f',
'#e70a0a',
'#aa24ce',
'#f17ff9',
'#FFD700',
'#33a4ea',
'#3e7753',
'#59db27',
//'#99953a'
];
var freeColors = shellColors.slice(0, 7);
var paidColors = shellColors.slice(7, shellColors.length);
var Slot = {
Primary: 0,
Secondary: 1
};
var EGGCOLOR = {
white: 0,
skyblue: 1,
beige: 2,
tan: 3,
brown: 4,
caramel: 5,
chocolate: 6,
red: 7,
purple: 8,
violet: 9,
yellow: 10,
babyblue: 11,
darkgreen: 12,
green: 13
}
// Type matches contents of the item_type table (could be generated from a db query but ... meh)
var ItemType = {
Hat: 1,
Stamp: 2,
Primary: 3,
Secondary: 4,
Grenade: 6
}
var CharClass = {
Soldier: 0,
Scrambler: 1,
Ranger: 2,
Eggsploder: 3,
Whipper: 4,
Crackshot: 5,
TriHard: 6
};
const SOCIALMEDIA = [
'fa-facebook-square',
'fa-instagram-square',
'fa-tiktok',
'fa-discord',
'fa-youtube',
'fa-twitter-square',
'fa-twitch'
];
</script><!-- shellshockers js -->
<script>
function ssJSComplete () {
window.onloadingcomplete();
}
Loader.loadJS('src/shellshock.js?1654121223', ssJSComplete);
</script>
</head>
<body>
<!-- google tag manager noscript -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K5MSJHJ"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) --> <!-- Ads -->
<div id="gameAdContainer" class="hideme">
<!-- <div id="multisizeBannerAdPlaceholder"></div>
<div id="shellshock-io_multisize"></div> -->
<!-- AdInPlay tag ID -->
<!-- ShellShock_Respawn_Banner -->
<!-- <div id='div-gpt-ad-ShellShock_Respawn_Banner'>
<script type='text/javascript'>
googletag.cmd.push(function() { googletag.display('div-gpt-ad-ShellShock_Respawn_Banner'); });
</script>
</div> -->
</div>
<div id="shellshockers_titlescreen">
</div>
<div id="shellshockers_chicken_nugget_banner">
</div>
<div id="shellshockers_respawn_banner_2">
</div>
<!-- <div id="shellshockers_respawn_banner">
</div> -->
<div id="shellshockers_respawn_banner-new">
</div>
<div id="ShellShockers_LoadingScreen_HouseAds">
</div>
<div id="videoAdContainer">
<div id="preroll"></div>
</div>
<!-- <div class="video_ad_wrapper">
<video id="asc_video_ad" class="video-js vjs-default-skin" controls preload="auto" width="640" height="360" muted="true" style="display: none;">
<source src="video/tiny.mp4" type="video/mp4" />
</video>
</div> -->
<div id="ss_background"></div>
<!-- Instantiate the Vue instance -->
<div id="app" :class="[currentLanguageCode, portalClass]"> <!-- vue instance div: all vue-controlled elements MUST be inside this tag -->
<!-- <asc-video-player id="mainVideoPlayer" ref="mainVideoPlayer" adTagUrl="adTagUrl"></asc-video-player> -->
<div class="firebaseID">firebase ID: {{ firebaseId }}, maskedEmail: {{ maskedEmail }} isAnonymous: {{ isAnonymous }}, isEmailVerified: {{ isEmailVerified }}</div>
<!-- Canvas -->
<canvas id="canvas" ref="canvas" class="gameCanvas"></canvas>
<!-- Overlays -->
<light-overlay id="lightOverlay" ref="lightOverlay"></light-overlay>
<dark-overlay id="darkOverlay" ref="darkOverlay"></dark-overlay>
<spinner-overlay id="spinnerOverlay" ref="spinnerOverlay" :loc="loc" :hide-ads="hideAds"></spinner-overlay>
<!-- GDPR -->
<gdpr id="gdpr" ref="gdpr" :loc="loc"></gdpr>
<!-- Screens -->
<home-screen id="home_screen" ref="homeScreen" v-show="(ui.showScreen === ui.screens.home)"></home-screen>
<equip-screen id="equip_screen" ref="equipScreen" v-show="(ui.showScreen === ui.screens.equip)"></equip-screen>
<game-screen id="game_screen" ref="gameScreen" v-show="(ui.showScreen === ui.screens.game)" :kname="killName" :kdname="killedName"></game-screen>
<!-- Popup: Settings -->
<large-popup id="settingsPopup" ref="settingsPopup" @popup-closed="onSharedPopupClosed" @popup-opened="onSettingsPopupOpened" @popup-x="onSettingsX">
<template slot="content">
<settings id="settings" ref="settings" :loc="loc" :settings-ui="settingsUi" :languages="languages" :current-language-code="currentLanguageCode" :show-privacy-options="showPrivacyOptions" @privacy-options-opened="onPrivacyOptionsOpened" :is-from-eu="showPrivacyOptions" :controller-id="controllerId" :controller-type="controllerType" :lang-option="locLanguage" :is-vip="(hideAds || contentCreator)"></settings>
</template>
</large-popup>
<!-- Popup: Privacy Options -->
<small-popup id="privacyPopup" ref="privacyPopup" hide-cancel="true" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc.p_settings_privacy }}</template>
<template slot="content">
<label class="ss_checkbox label"> {{ loc.p_settings_of_age }}
<input id="ofAgeCheck" type="checkbox" v-model="isOfAge" @change="ofAgeChanged($event)">
<span class="checkmark"></span>
</label>
<label class="ss_checkbox label"> {{ loc.p_settings_target_ads }}
<input id="targetedAdsCheck" type="checkbox" v-model="showTargetedAds" @change="targetedAdsChanged($event)">
<span class="checkmark"></span>
</label>
<!--
<input id="ofAgeCheck" type="checkbox" v-model="isOfAge" @change="ofAgeChanged($event)"> {{ loc.p_settings_of_age }}<br>
<input id="targetedAdsCheck" type="checkbox" v-model="showTargetedAds" @change="targetedAdsChanged($event)"> <span id="targetedAdsText">{{ loc.p_settings_target_ads }}</span>
-->
</template>
<template slot="confirm">{{ loc.ok }}</template>
</small-popup>
<!-- Popup: Help & Feedback -->
<large-popup id="helpPopup" ref="helpPopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed">
<template slot="content">
<help id="help" ref="help" :loc="loc"></help>
</template>
</large-popup>
<!-- Popup: VIP Help & Feedback -->
<large-popup id="vipPopup" ref="vipPopup" stop-key-capture="true" @popup-closed="onVipHelpClosed">
<template slot="content">
<vip-help id="vip-help" ref="help" :loc="loc" :is-vip="isSubscriber"></help>
</template>
</large-popup>
<!-- Popup: Egg Store -->
<large-popup id="eggStorePopup" ref="eggStorePopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="false">
<template slot="content">
<egg-store id="help" ref="help" :loc="loc" :products="eggStoreItems" :sale-event="isSale"></egg-store>
</template>
</large-popup>
<img v-show="blackFridayBanner" class="black-friday-banner" style="display: none" src="img/black-friday-banner.jpg" alt="Black Friday Sale"/>
<!-- Popup: VIP store -->
<large-popup id="subStorePopup" ref="subStorePopup" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="true">
<template slot="content">
<subscription-store id="shell-subscriptions" ref="shell-subscriptions" :loc="loc" :subs="subStoreItems"></egg-store>
</template>
</large-popup>
<!-- Popup: VIP ended -->
<small-popup id="vipEnded" ref="vipEnded" stop-key-capture="true" @popup-confirm="showSubStorePopup" @popup-closed="onSharedPopupClosed" :overlay-close="true" class="vip">
<template slot="content">
<figure>
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Shell Shockers VIP">
</figure>
<div class="vip-ended-popup">
Yo! Your VIP subscription has expired! If you'd like to keep your awesome benefits (and your Golden Wings!) then click below to join again!
</div>
</template>
<template slot="confirm">Join again!</template>
<template slot="cancel">No, i don't like stuff</template>
</small-popup>
<!-- Popup: Egg Store single -->
<large-popup id="popupEggStoreSingle" ref="popupEggStoreSingle" stop-key-capture="true" @popup-closed="onSharedPopupClosed" :overlay-close="false" class="popup-store-single">
<template slot="content">
<egg-store-item v-for="item in premiumShopItems" :key="item.sku" :item="item" :loc="loc" :account-set="accountSettled" v-if="eggStorePopupSku && item.sku === eggStorePopupSku"></egg-store-item>
</template>
</large-popup>
<!-- Popup: Unsupported Platform -->
<large-popup id="unsupportedPlatformPopup" ref="unsupportedPlatformPopup" hide-close="true">
<template slot="content">
<h2>{{ loc['unsupported_platform'] }}</h2>
<div>{{ loc[unsupportedPlatformPopup.contentLocKey] }}</div>
</template>
</large-popup>
<!-- Popup: Missing Features -->
<large-popup id="missingFeaturesPopup" ref="missingFeaturesPopup" hide-close="true">
<template slot="content">
<h2>{{ loc['oh_no'] }}</h2>
<span>{{ loc['missing_features'] }}</span>
<ul>
<li v-for="f in missingFeatures" v-html="f"></li>
</ul>
<span>{{ loc['missing_help'] }}</span>
</template>
</large-popup>
<!-- Popup: No Anon -->
<small-popup id="noAnonPopup" ref="noAnonPopup" @popup-confirm="onNoAnonPopupConfirm" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc.no_anon_title }}</template>
<template slot="content">
<div>{{ loc.no_anon_msg1 }}</div>
<div>{{ loc.no_anon_msg2 }}</div>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.no_anon_signup }}</template>
</small-popup>
<!-- Popup: Give Stuff -->
<give-stuff-popup ref="giveStuffPopup" id="giveStuffPopup" :loc="loc" :give-stuff-popup="giveStuffPopup"></give-stuff-popup>
<!-- Popup: Open URL -->
<small-popup id="openUrlPopup" ref="openUrlPopup" @popup-confirm="onOpenUrlPopupConfirm" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc[openUrlPopup.titleLocKey] }}</template>
<template slot="content">
<!-- content not loc'd (yet) -->
{{ openUrlPopup.content }}
</template>
<template slot="cancel">{{ loc[openUrlPopup.cancelLocKey] }}</template>
<template slot="confirm">{{ loc[openUrlPopup.confirmLocKey] }}</template>
</small-popup>
<!-- Popup: Changelog -->
<large-popup id="changelogPopup" ref="changelogPopup" @popup-closed="onSharedPopupClosed">
<template slot="content">
<h1 id="popup_title nospace" class="roundme_sm">
{{ loc.changelog_title }}
</h1>
<div class="changelog_content">
<section v-for="(log, idx) in changelog.current">
<h3>{{ log.version }} - <i><time>{{ log.date }}</time></i></h3>
<ul>
<li v-for="data in log.content" v-html="data"></li>
</ul>
<hr class="blue">
</section>
</div>
<div id="btn_horizontal">
<button v-if="changelog.showHistoryBtn" @click="showHistoryChangelogPopup" class="ss_button btn_green bevel_green">More</button>
<button @click="hideChangelogPopup" class="ss_button btn_red bevel_red">{{ loc.close }}</button>
</div>
</template>
</large-popup>
<!-- Popup: Golden Chicken -->
<!-- <large-popup id="goldChickenPopup" ref="goldChickenPopup" :overlay-close="false">
<template slot="content">
<gold-chicken-popup id="gold_chicken" ref="gold_chicken" :loc="loc"></gold-chicken-popup>
</template>
</large-popup> -->
<!-- Popup: Chicken Nugget -->
<large-popup id="chicknWinner" ref="chicknWinner" :hide-close="true" :overlay-close="false">
<template slot="content">
<chicken-nugget-popup id="chickenNugget" ref="chickenNugget" :loc="loc" :amount-given="miniEggGameAmount" :ad-units="adUnits"></chicken-nugget-popup>
</template>
</large-popup>
<!-- Popup: Generic Message -->
<small-popup id="genericPopup" ref="genericPopup" :popup-model="genericMessagePopup" :hide-cancel="true" @popup-closed="onSharedPopupClosed">
<template slot="header">{{ loc[genericMessagePopup.titleLocKey] }}</template>
<template slot="content">{{ loc[genericMessagePopup.contentLocKey] }}</template>
<template slot="confirm">{{ loc[genericMessagePopup.confirmLocKey] }}</template>
</small-popup>
<!-- Popup: Anon warning message -->
<small-popup v-if="isAnonymous" id="anonWarningPopup" ref="anonWarningPopup" :hide-close="true" :overlay-close="false" @popup-cancel="anonWarningPopupCancel" @popup-confirm="anonWarningPopupConfrim">
<template slot="header">{{ loc.account_anon_warn_popup_title }}!</template>
<template slot="content">
<p v-html="loc.account_anon_warn_paragraph_block"></p>
<p v-html="loc.account_anon_warn_paragraph_block_two"></p>
</template>
<template slot="cancel">{{ loc.account_anon_warn_confirm }}</template>
<template slot="confirm">{{ loc.sign_in }}</template>
</small-popup>
<!-- Popup: Need More eggs popup -->
<small-popup id="needMoreEggsPopup" ref="needMoreEggsPopup" @popup-confirm="showEggStorePopup">
<template slot="header">{{ loc.p_buy_isf_title }}!</template>
<template slot="content">
<p>{{ loc.p_buy_isf_content }}.</p>
</template>
<template slot="cancel">{{ loc.p_buy_item_cancel }}</template>
<template slot="confirm">{{ loc.account_title_eggshop }}</template>
</small-popup>
<!-- Popup: Firebase Sign In -->
<large-popup id="firebaseSignInPopup" ref="firebaseSignInPopup" :overlay-close="false">
<template slot="content">
<h1 class="nospace">{{ loc.p_signin_head }}</h1>
<div id="firebaseui-auth-container"></div>
<div id="btn_horizontal" class="f_center">
<button @click="onSignInCancelClicked()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
</div>
</template>
</large-popup>
<small-popup ref="adBlockerPopup" id="adBlockerPopup" :overlay-close="false" hide-confirm="true" hide-cancel="true" hide-close="true">
<template slot="header">
We've detected ad blocker!
</template>
<template slot="content">
<p>To <i>avoid</i> this message please turn <i>off</i> ad blocker.</p>
<h4>Please wait</h4>
<h3>{{adBlockerCountDown}}</h3>
</template>
</small-popup>
<!-- Popup: PWA -->
<small-popup id="pwaPopup" class="pwa-popup" ref="pwaPopup" hide-confirm="true" @popup-closed="onSharedPopupClosed">
<!-- <template slot="header">{{ loc.p_settings_privacy }}</template> -->
<template slot="content">
<p>{{loc.pwa_desc_one}}</p>
<p>{{loc.pwa_desc_two}}</p>
<button @click="pwaBtnClick" class="ss_button btn_big btn_green bevel_green btn_height_auto btn-pwa-download">
<div class="pwa-btn-img-box roundme_lg bg-darkgreen">
<img src="favicon192.png" alt="Egg yolk">
<i class="fas fa-share" aria-hidden="true"></i>
</div>
{{loc.pwa_btn_line_one}}<br/>{{loc.pwa_btn_line_two}}
</button>
</template>
<template slot="cancel">{{loc.pwa_no_thanks}}</template>
</small-popup>
<large-popup id="adBlockerVideo" ref="adBlockerVideo" @popup-closed="onSharedPopupClosed" :overlay-close="false" hide-confirm="true" hide-cancel="true" hide-close="true">
<template slot="content">
<p class="text-center">{{ loc.ad_blocker_big_popup_title }}<br /> <span v-html="loc.ad_blocker_big_popup_desc"></span></p>
<img src="img/shellshockers-unite-lg.png" alt="">
<!-- <house-ad id="house-ad-video-replacement" ref="house-ad-video-replacement" :data="bannerHouseAd" :isshowing="showAdBlockerVideoAd"></house-ad> -->
</template>
</large-popup>
<large-popup ref="mobileAdPopup" id="mobileAdPopup" :overlay-close="true" hide-confirm="true" hide-cancel="true">
<template slot="content">
<img src="img/mobile/shell-mobile-popup-bg-qr.png" alt="Get Shell Shockers Mobile app!">
</template>
</large-popup>
<large-popup ref="kotcInstrucPopup" id="kotcInstrucPopup" :overlay-close="true" hide-confirm="true" hide-cancel="true">
<template slot="content">
<img class="kotc-wordmark" src="img/kotc/kotc-wordmark.svg" alt="">
<div class="kotc-how-to-play-wrapper box_aboslute">
<h2 class="kotc-how-to-play-title text-center"><span class="roundme_md">{{ loc.home_kotc_popup_how_to }}</span><br />{{ loc.home_play }}!</h2>
<img src="img/kotc/kotc-arrow.svg" aria-hidden="true">
</div>
<div class="display-grid grid-column-2-eq grid-gap-space-lg fullwidth ss_margintop_xxxxl">
<div class="img-container roundme_lg fullwidth step-one">
<div class="fullwidth">
<p class="text-center"><span class="sr-only">Step </span>1</p>
<h6 class="text-center">{{loc.home_kotc_popup_step_one}}</h6>
</div>
</div>
<div class="img-container roundme_md fullwidth step-two">
<div class="fullwidth">
<p class="text-center"><span class="sr-only">Step </span>2</p>
<h6 class="text-center">{{loc.home_kotc_popup_step_two}}</h6>
</div>
</div>
</div>
<div class="display-grid grid-column-2-eq grid-gap-space-lg roundme_md fullwidth ss_margintop_lg kotc-play-now step-three-wrapper">
<div class="fullwidth box_relative step-three">
<img class="kotc-logo box_aboslute" src="img/kotc/kotc-rooster.svg" alt="The King of the Coop Rooster">
<div>
<p class="text-center"><span class="sr-only">Step </span>3</p>
<h6 class="text-center" v-html="loc.home_kotc_popup_step_three"></h6>
</div>
</div>
<div class="fullwidth f_col f_space_between">
<div class="display-grid grid-column-5-eq kotc-crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
<img aria-hidden="true" src="img/kotc/kotc-crown.svg" alt="Crowns">
</div>
<button class="ss_button btn_big btn_green bevel_green fullwidth" @click="onClickPlayKotcNow"><i class="fa fa-play fa-sm"></i> {{ loc.home_play }}</button>
</div>
</div>
</template>
</large-popup>
<!-- <div id="kotc-play-kotc" class="kotc-play-kotc display-grid">
<img class="kotc-play-kotc-watermark" src="img/kotc/kotc-crown-indicator.svg" alt="">
<img class="kotc-play-kotc-arrow" src="img/kotc/kotc-arrow.svg" aria-hidden="true">
</div> -->
<!-- #kotc-play-kotc -->
</div> <!-- End of vue instance div -->
<script>
var vueApp;
var vueData = {
ready: false,
accountSettled: false,
missingFeatures: [],
changelogVersion: version,
changeLogData: [],
showChangelogHistoryBtn: true,
changelog: {
current: [],
history: [],
showHistoryBtn: true
},
firebaseId: null,
photoUrl: null,
maskedEmail: null,
isEmailVerified: false,
isAnonymous: true,
showPrivacyOptions: isFromEU,
isOfAge: false,
showTargetedAds: false,
delayTheCracking: false,
displayAdFunction: Function,
titleScreenDisplayAd: Function,
displayAdObject: false,
hideAds: false,
isPoki: false,
isPokiGameLoad: false,
pokiRewardReady: false,
isPokiNewRewardTimer: false,
videoRewardTimers: {
initial: 300000,
primary: 420000
},
pokiRewNum: 1,
adUnits: {
display: {
respawn: 'shellshockers_respawn_banner',
respawnTwo: 'shellshockers_respawn_banner_2',
respawnThree: "shellshockers_respawn_banner-new",
home: 'shellshockers_titlescreen',
nugget: 'shellshockers_chicken_nugget_banner',
house: 'ShellShockers_LoadingScreen_HouseAds'
}
},
cGrespawnBannerTimeout: null,
cGrespawnBannerErrors: 0,
classIdx: 0,
playerName: '',
eggs: 0,
kills: 0,
deaths: 0,
kdr: 0,
streak: 0,
isUpgraded: false,
upgradeName: '',
isSubscriber: false,
serverList: [], // Populated by pingServers()
currentServerId: null,
currentServerLocKey: null,
currentGameType: 0,
volume: 0,
getMusicVolume: 0.5,
currentLanguageCode: 'en',
ui: {
showScreen: 0,
screens: {
home: 0,
equip: 1,
game: 2
},
overlayType: {
none: 0,
dark: 1,
light: 2,
},
overlayClass: {
inGame: 'overlay_game'
},
team: {
blue: 1,
red: 2
},
houseAds: {
small: null,
big: null
},
showCornerButtons: true,
},
isTwitchEvent: false,
twitchLinked: 0,
twitchName: '',
languages: [
{ name: 'English', code: 'en' },
{ name: 'French', code: 'fr' },
{ name: 'German', code: 'de' },
{ name: 'Russian', code: 'ru' },
{ name: 'Spanish', code: 'es' },
{ name: 'Portuguese', code: 'pt' },
{ name: 'Korean', code: 'ko' },
{ name: 'Chinese', code: 'zh' },
{ name: 'Dutch', code: 'nl' }
],
locLanguage: {},
playTypes: {
joinPublic: 0,
createPrivate: 1,
joinPrivate: 2
},
gameTypes: [
{ locKey: 'gametype_ffa', value: 0 },
{ locKey: 'gametype_teams', value: 1 },
{ locKey: 'gametype_ctf', value: 2 },
{ locKey: 'gametype_king', value: 3 }
],
// This makes me mad, but until Vue is put in the clojure with GameType,
// where it should have been to begin with, HERE IT IS >:(
gameTypeKeys: [
'FFA',
'Teams',
'Spatula',
'King'
],
twitchStreams: [],
youtubeStreams: [],
newsfeedItems: [
{ message: "Test 1 Lorem ipsum dolor sit amet, consectetur adipiscing elit.", image: "img/ico_news.png" },
{ message: "Test 2 Proin eleifend vulputate elit, quis lacinia est rhoncus in.", image: "img/ico_news.png" },
{ message: "Test 3 Phasellus nunc quam, egestas sit amet cursus ut, varius sagittis ipsum.", image: "img/ico_news.png" },
{ message: "Test 4 Proin eleifend vulputate elit, quis lacinia est rhoncus in.", image: "img/ico_news.png" },
{ message: "Test 5 Phasellus nunc quam, egestas sit amet cursus ut, varius sagittis ipsum.", image: "img/ico_news.png" }
],
maps: [],
settingsUi: {
adjusters: {
misc: [
{ id: 'volume', locKey: 'p_settings_mastervol', min: 0, max: 1, step: 0.01, value: 1, multiplier: 100 }
],
mouse: [
{ id: 'mouseSpeed', locKey: 'p_settings_mousespeed', min: 1, max: 100, step: 1, value: 30 }
],
gamepad: [
{ id: 'sensitivity', locKey: 'p_settings_sensitivity', min: 1, max: 100, step: 1, value: 30 },
{ id: 'deadzone', locKey: 'p_settings_deadzone', min: 0, max: 1, step: 0.01, value: 0.3, precision: 2 }
],
// music: [
// { id: 'musicVolume', locKey: 'p_settings_music_volume', min: 0, max: 1, step: 0.01, value: 0.5, multiplier: 100 }
// ],
},
togglers: {
misc: [
{ id: 'holdToAim', locKey: 'p_settings_holdtoaim', value: true },
{ id: 'enableChat', locKey: 'p_settings_enablechat', value: true },
{ id: 'safeNames', locKey: 'p_settings_safenames', value: false },
{ id: 'autoDetail', locKey: 'p_settings_autodetail', value: true },
{ id: 'shadowsEnabled', locKey: 'p_settings_shadows', value: true },
{ id: 'highRes', locKey: 'p_settings_highres', value: false },
{ id: 'hideBadge', locKey: 'p_settings_badge_hide', value: false },
// { id: 'musicStatus', locKey: 'p_settings_music', value: true }
],
mouse: [
{ id: 'mouseInvert', locKey: 'p_settings_invertmouse', value: false },
{ id: 'fastPollMouse', locKey: 'p_settings_fastpollmouse', value: false },
],
gamepad: [
{ id: 'controllerInvert', locKey: 'p_settings_invertcontroller', value: false },
]
},
controls: {
keyboard: {
// The ids map to the field names in settings.controls[category]
game: [
{ id: 'up', side: 'left', locKey: 'keybindings_forward', value: 'W' },
{ id: 'down', side: 'left', locKey: 'keybindings_backward', value: 'S' },
{ id: 'left', side: 'left', locKey: 'keybindings_left', value: 'A' },
{ id: 'right', side: 'left', locKey: 'keybindings_right', value: 'D' },
{ id: 'jump', side: 'left', locKey: 'keybindings_jump', value: 'SPACE' },
{ id: 'fire', side: 'right', locKey: 'keybindings_fire', value: 'MOUSE 0' },
{ id: 'scope', side: 'right', locKey: 'keybindings_aim', value: 'SHIFT' },
{ id: 'reload', side: 'right', locKey: 'keybindings_reload', value: 'R' },
{ id: 'swap_weapon', side: 'right', locKey: 'keybindings_swapweapon', value: 'E' },
{ id: 'grenade', side: 'right', locKey: 'keybindings_grenade', value: 'Q' }
],
spectate: [
{ id: 'ascend', locKey: 'keybindings_spectate_ascend', value: 'SPACE' },
{ id: 'descend', locKey: 'keybindings_spectate_descend', value: 'SHIFT' }
]
},
gamepad: {
// The ids map to the field names in settings.gamepad[category]
game: [
{ id: 'jump', locKey: 'keybindings_jump', value: '0' },
{ id: 'fire', locKey: 'keybindings_fire', value: '1' },
{ id: 'scope', locKey: 'keybindings_aim', value: '2' },
{ id: 'reload', locKey: 'keybindings_reload', value: '3' },
{ id: 'swap_weapon', locKey: 'keybindings_swapweapon', value: '4' },
{ id: 'grenade', locKey: 'keybindings_grenade', value: '5' }
],
spectate: [
{ id: 'ascend', locKey: 'keybindings_spectate_ascend', value: '1' },
{ id: 'descend', locKey: 'keybindings_spectate_descend', value: '2' }
]
}
}
},
songChanged: false,
music: {
isMusic: false,
musicJson: 'data/sponsors.json',
musicSrc: '',
theAudio: '',
playing: false,
sponsors: {},
sponsor: '',
currIndex: 0,
currentTime: 0,
duration: 0,
timer: null,
progress: 0,
volume: 10,
hideClass: 'music-widget--fade-out',
serverTracks: {
id: '',
title: '',
artist: '',
album: '',
albumArt: '',
url: '',
trackUrltest: 'https://shellshock.io',
sponsor: '',
sponsorUrl: '',
}
},
home: {
joinPrivateGamePopup: {
code: '',
showInvalidCodeMsg: false,
validate: function () {
if (this.code.length == 0) {
console.log('failed validation');
this.showInvalidCodeMsg = true;
BAWK.play('ui_reset');
return false;
}
console.log('passed validation');
return true;
},
reset: function () {
this.code = '';
this.showInvalidCodeMsg = false;
}
},
},
equip: {
get showingItems () {
return this._showingItems;
},
set showingItems (items) {
this._showingItems = items;
for (let t of this.lazyRenderTimeouts) {
clearTimeout(t);
}
},
lazyRenderTimeouts: [],
mode: 0,
equipModes: {
inventory: 0,
shop: 1
},
equippedPrimary: null,
equippedSecondary: null,
equippedHat: null,
equippedStamp: null,
equippedGrenade: null,
posingHat: null,
posingStamp: null,
posingWeapon: null,
posingGrenade: null,
showingWeaponType: ItemType.Primary,
selectedItemType: ItemType.Primary,
selectedItem: null,
_showingItems: [],
buyingItem: null,
colorIdx: 0,
extraColorsLocked: true,
categoryLocKey: null,
showSpecialItems: false,
specialItemsTag: null,
redeemCodePopup: {
code: '',
showInvalidCodeMsg: false,
validate: function () {
if (this.code.length == 0) {
console.log('failed validation');
this.showInvalidCodeMsg = true;
BAWK.play('ui_reset');
return false;
}
console.log('passed validation');
return true;
},
reset: function () {
this.code = '';
this.showInvalidCodeMsg = false;
}
},
physicalUnlockPopup: {
item: null
}
},
game: {
shareLinkPopup: {
url: ''
},
gameType: 0,
team: 1,
respawnTime: 0,
tipIdx: 0,
isGameOwner: false,
pauseScreen: {
id: 'pausePopup',
adContainerId: 'pauseAdPlacement',
classChanged: false,
wasGameInventoryOpen: false,
}
},
isPaused: true,
isEvent: false,
doubleEggWeekendSoon: false,
doubleEggWeekend: false,
announcementMessage: null,
playerActionsPopup: {
playerId: 0,
uniqueId: 0,
isGameOwner: false,
playerName: '',
muted: false,
muteFunc: null,
bootFunc: null,
social: false,
vipMember: false
},
giveStuffPopup: {
titleLoc: '',
eggs: 0,
items: [],
type: ''
},
openUrlPopup: {
url: '',
titleLocKey: '',
contentLocKey: '',
confirmLocKey: 'ok',
cancelLocKey: 'no_thanks'
},
genericMessagePopup: {
titleLocKey: 'keybindings_right',
contentLocKey: 'p_popup_chicken_nuggetbutton',
confirmLocKey: 'ok'
},
unsupportedPlatformPopup: {
titleLocKey: 'unsupported_platform',
contentLocKey: ''
},
windowDimensions: {
width: 0,
height: 0,
},
bannerAds: {
bannerElId: '',
},
googleAnalytics: {
isUser: null,
cat: {
purchases: 'Purchases',
purchaseComplete: 'Purchase Complete',
itemShop: 'Item Shop',
inventory: 'Inventory',
playerStats: 'player stats',
play: 'play game',
redeem: 'Redeem'
},
action : {
eggShackClick: 'Egg Shack Click',
eggShackProductClick: 'Egg Shack Product Click',
purchaseComplete: 'Purchase Complete',
goldenChickenProductClick: 'Golden Chicken Product Click',
goldenChickenNuggetClick: 'Golden Chicken Nugget Click',
shopClick: 'Shop Opened ',
shopItemClick: 'Shop Item Selected',
shopItemPopupClick: 'Shop Item Popup Click',
shopItemPopupBuy: 'Item purchased',
shopItemNeedMoreEggsPopup: 'Need More Eggs Popup',
inventorySelected: 'Inventory Item ',
eggCount: 'Egg Count',
inventoryTabClick: 'Inventory Opened',
playGameClick: 'Play Game Click',
redeemed: 'Redeemed',
redeemClick: 'Redeem open',
languageSwitch: 'Language setting change',
langBeforeUpdate: 'Language before auto detect',
privateGame: 'Private Game',
shareGamePopup: 'Share game Popup',
shareGameCopy: 'Shared game code',
createGame: 'Created game',
joinGame: 'Joined game',
playerLimit: 'Player limit',
timesPlayed: 'Times played',
anonymousPopupOpenAuto: 'Anon warning auto opened',
anonymousPopupOpen: 'Anon warning opened',
anonymousPopupSignupClick: 'Anon warning Sign in clicked',
anonymousPopupAgreeClick: 'Anon warning Understood clicked',
denyAnonUserPopup: 'Deny anon user popup',
denyAnonUserPopupSignin: 'sign in click',
faqPopupClick: 'FAQ popup open',
switchTeams: 'Switched Teams',
error: 'error',
signIn: 'Sign in'
},
label : {
signInClick: 'sign in click',
understood: 'Understood click',
getMoreEggs: 'Get More Eggs Click',
waitForGameReadyTimeout: 'waitForGameReady timeout',
signInAuthFailed: 'authorization failed',
signInTiming: 'Sign in delay',
signInCompleted: 'Completed',
signInOut: 'Signed out',
signInFailed: '',
homeToGameLoading: 'Home to game loading',
loading: 'Loading'
}
},
urlParams: null,
urlParamSet: null,
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?iu=/21743024831/ShellShock_Video&description_url=__page-url__&env=vp&impl=s&correlator=&tfcd=0&npa=0&gdfp_req=1&output=vast&sz=640x480&unviewed_position_start=1',
eggStoreItems: [],
subStoreItems: [],
premiumShopItems: [],
eggStoreReferral: '',
eggStoreHasSale: false,
eggStorePopupSku: 'egg_pack_small',
showNugget: true,
// isMiniGameComplete: false,
miniEggGameAmount: 0,
showGoldenChicken: false,
nugStart: null,
nugCounter: null,
isBuyNugget: false,
adBlockerCountDown: 10,
controllerType: 'generic',
controllerId: '',
controllerButtonIcons: {
xbox: [
'A',
'B',
'X',
'Y',
'LB',
'RB',
'LT',
'RT',
'Select',
'Start',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
ps: [
'<img class="ss_buttonbind_icon" src="img/controller/button_cross.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_circle.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_square.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_triangle.svg">',
'LB',
'RB',
'LT',
'RT',
'Select',
'Start',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
switchpro: [
'B',
'A',
'Y',
'X',
'LB',
'RB',
'LT',
'RT',
'-',
'+',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_stickright.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadup.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpaddown.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadleft.svg">',
'<img class="ss_buttonbind_icon" src="img/controller/button_dpadright.svg">'
],
generic: [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15'
]
},
pwaDeferEvent: '',
blackFridayBanner: false,
isSale: false,
smallHouseAd: {},
bannerHouseAd: false,
showAdBlockerVideoAd: false,
hasMobileReward: false,
killName: null,
killedName: null,
killedByMessage: null,
killedMessage: null,
chicknWinnerWatched: null,
chicknWinnerCounter: 0,
chicknWinnerReady: false,
chicknWinnerDailyLimitReached: false,
isChicknWinnerError: false,
hasChwPlayClicked: false,
chwActiveTimer: 6000,
chwHomeTimer: null,
chwHomeEl: null,
contentCreator: false,
eggOrg: false
}</script>
<!-- Shared tags must come before the screen tags -->
<script id="events-template" type="text/x-template">
<div v-if="(doubleEggWeekendSoon || doubleEggWeekend) && showUi" id="event-notifications">
<div class="double-eggs">
<img v-if="doubleEggWeekendSoon && !doubleEggWeekend" src="img/events/shellshockers_doubleEgg01.png" alt="Double Egg weekend coming soon">
<img v-if="doubleEggWeekend" src="img/events/shellshockers_doubleEgg02.png" alt="Double Egg weekend now happening">
</div>
</div>
</script>
<script>
const comp_events = {
template: '#events-template',
props: ['show', 'owOn', 'showSoon', 'showUi'],
created() {
this.checkForEvents();
},
data: function () {
return vueData;
},
methods: {
isEventDate(days) {
const day = new Date().getUTCDay();
return days.includes(day);
},
doubbleEggSoon() {
return this.doubleEggWeekendSoon = this.isEventDate([4,5]);
},
doubleEggOn() {
const ISEVENT = this.isEventDate([5,6,0]);
if (!ISEVENT) {
return;
}
const DATE = new Date();
let day = DATE.getUTCDay();
if (day === 5) {
let time = DATE.getUTCHours();
if (time >= 20) {
return (
this.doubleEggWeekend = ISEVENT,
this.isEvent = ISEVENT
)
} else {
return (
this.doubleEggWeekend = false,
this.isEvent = false
)
}
} else {
return (
this.doubleEggWeekend = ISEVENT,
this.isEvent = ISEVENT
)
}
},
checkEvents() {
return (
this.doubbleEggSoon(),
this.doubleEggOn()
)
},
checkForEvents() {
this.checkEvents();
if (!this.doubleEggWeekend && this.isEventDate([4,5,6,0])) {
setTimeout(() => {
return this.checkForEvents();
}, 60000);
}
return;
},
},
};
</script><script>
var comp_light_overlay = {
template: `<transition name="fade">
<div id="lightOverlay" v-show="show" :class="overlayClass" class="overlay overlay_light"></div>
</transition>`,
data: function () {
return {
show: false,
overlayClass: '',
};
},
};
</script><script>
var comp_dark_overlay = {
template: `<transition name="fade">
<div id="darkOverlay" v-show="show" :class="overlayClass" class="overlay overlay_dark"></div>
</transition>`,
data: function () {
return {
show: false,
overlayClass: '',
};
},
};
</script><script id="spinner-overlay-template" type="text/x-template">
<transition name="fadeout">
<div v-show="isShowing" class="load_screen">
<h3 class="load_message">{{ header }}</h3>
<wobbly-egg></wobbly-egg>
<p class="load_message">{{ footer }}</p>
<display-ad :hidden="hideAds" id="div-gpt-ad-shellshockers-loading-houseads-wrap" ref="loadingScreenDisplayAd" :ignoreSize="true" :houseAd="true" adUnit="ShellShockers_LoadingScreen_HouseAds" adSize="728x90" :override="true" :adBlockerData="adblockerbanner"></display-ad>
</div>
</transition>
</script>
<script id="wobble-egg-template" type="text/x-template">
<div id="wobbly-egg">
<svg viewBox="0 0 240 240" :class="[loadEggcontainer, {noanimate: noAnimate}]" width="240" height="240" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient r="0.5" cy="0.4" cx="0.4" id="load_yolkgradient" spreadMethod="pad">
<stop stop-color="#fed" offset="0.3"/>
<stop stop-color="#fb0" offset="0.32"/>
<stop stop-color="#fa0" offset="1"/>
</radialGradient>
<filter id="load_eggshadow" :class="{noanimate: noAnimate}" x="-30%" y="-30%" width="160%" height="160%" >
<feDropShadow dx="0" dy="8" stdDeviation="8" flood-color="#124" flood-opacity="0.3" />
</filter>
</defs>
<g>
<path filter="url(#load_eggshadow)" :class="[loadEggwhite, {noanimate: noAnimate}]" stroke="#000" id="svg_eggwhite" d="m190.13055,40.86621c30.25552,23.71378 -12.26575,57.24017 0,81.77167c12.26575,24.5315 4.9063,80.13624 -33.52639,82.58939c-38.43269,2.45315 -55.60474,-26.16693 -94.03742,-17.98977c-38.43269,8.17717 -11.44803,-30.25552 -17.98977,-44.97442c-6.54173,-14.7189 -24.5315,-46.60985 -4.9063,-71.14135c9.8126,-12.26575 22.07835,-14.92333 34.95739,-15.02554c12.87904,-0.10221 19.01191,-15.63883 31.27766,-17.68312c12.26575,-2.04429 21.46506,17.58091 33.83303,11.2436c12.36797,-6.3373 35.26403,-20.64735 50.39179,-8.79045z" stroke-width="0" fill="#fff" />
</g>
<g>
<ellipse :class="[loadEggyolk, {noanimate: noAnimate}]" ry="38" rx="38" id="svg_eggyolk" cy="120" cx="120" stroke-width="0" fill="url(#load_yolkgradient)"/>
</g>
</svg>
</div>
</script>
<script>
var comp_wobbly_egg = {
template: '#wobble-egg-template',
props: ['noAnimate'],
data: function () {
return {
loadEggyolk: 'load_eggyolk',
loadEggwhite: 'load_eggwhite',
loadEggcontainer: 'load_eggcontainer'
}
}
};
</script>
<script>
var comp_spinner_overlay = {
template: '#spinner-overlay-template',
components: {
'wobbly-egg': comp_wobbly_egg
},
props: ['loc', 'adblockerbanner', 'hideAds'],
data: function () {
return {
isShowing: false,
header: '',
footer: '',
adIsShowing: false,
}
},
methods: {
show: function (headerLocKey, footerLocKey) {
this.header = this.loc[headerLocKey];
this.footer = this.loc[footerLocKey];
this.isShowing = true;
},
showSpinnerLoadProgress: function (percent) {
var msg = this.loc['ui_game_loading'];
this.header = this.loc['building_map'];
this.footer = '{0}... {1}%'.format(msg, percent);
this.isShowing = true;
},
hide: function () {
this.isShowing = false;
this.$emit('close-display-ad');
},
hideDisplayAd() {
this.adIsShowing = false;
console.log('do it');
},
showDisplayAd() {
this.adIsShowing = true;
},
toggleDisplayAd() {
return this.adIsShowing = this.adIsShowing ? false : true;
}
},
};
</script><script id="small-popup-template" type="text/x-template">
<transition name="fade">
<div v-show="isShowing" class="popup_window popup_sm roundme_lg centered">
<div>
<button v-show="!hideClose" @click="onXClick" class="popup_close roundme_sm clickme"></button>
<h3 id="popup_title" v-show="!hideHeader" class="roundme_sm shadow_blue4 nospace">
<slot name="header"></slot>
</h3>
</div>
<div v-show="!hideContent" class="popup_sm_content"><slot name="content"></slot></div>
<div id="btn_horizontal" class="f_center">
<button class="ss_button btn_red bevel_red width_sm" v-show="!hideCancel" @click="cancelClick"><slot name="cancel"></slot></button>
<button class="ss_button btn_green bevel_green width_sm" v-show="!hideConfirm" @click="confirmClick"><slot name="confirm"></slot></button>
</div>
</div>
</transition>
</script>
<script id="large-popup-template" type="text/x-template">
<transition name="fade">
<div id="popupPause" v-show="isShowing" class="popup_window popup_lg centered roundme_lg">
<button @click="onXClick" v-show="!hideClose" class="popup_close clickme roundme_sm"></button>
<slot name="content"></slot>
</div>
</transition>
</script>
<script>
// Register popup components globally
Vue.component('small-popup', createPopupComponent('#small-popup-template'));
Vue.component('large-popup', createPopupComponent('#large-popup-template'));
function createPopupComponent(templateId) {
return {
template: templateId,
props: ['hideHeader', 'hideContent', 'hideClose', 'hideCancel', 'hideConfirm', 'overlayType', 'overlayClass', 'popupModel', 'uiModel', 'stopKeyCapture', 'overlayClose'],
data: function () {
return {
isShowing: false,
overlays: vueData.ui.overlayType,
popupId: '',
removeOverlayClick: ''
}
},
created() {
this.popupId = this.$attrs && this.$attrs.id;
},
destroyed: function() {
document.removeEventListener('keyup', this.escapeKeyClose);
},
methods: {
setVisible: function (visible) {
this.isShowing = visible;
if (this.stopKeyCapture && extern.inGame) {
if (this.isShowing) {
extern.releaseKeys();
} else {
extern.captureKeys();
}
}
if (this.isShowing && this.popupModel && this.popupModel.reset) {
this.popupModel.reset();
}
if (!this.isShowing || this.overlayType === this.overlays.none) {
vueApp.setDarkOverlay(false);
vueApp.setLightOverlay(false);
} else {
vueApp.setDarkOverlay(this.overlayType === undefined || this.overlayType === this.overlays.dark, this.overlayClass);
}
if (!this.isShowing) {
console.log('Closed: ' + this.popupId);
this.$emit('popup-closed');
vueApp.gameUiRemoveClassForNoScroll();
this.cancelEventOverLayClickEscapeClose();
} else {
console.log('Opened: ' + this.popupId);
this.$emit('popup-opened');
vueApp.scrollToTop();
vueApp.gameUiAddClassForNoScroll();
this.outsideClickClose();
}
if (!extern.inGame) {
vueApp.toggleTitleScreenAd();
}
},
toggle: function () {
this.isShowing = !this.isShowing;
this.setVisible(this.isShowing);
},
show: function () {
this.setVisible(true);
},
hide: function () {
this.setVisible(false);
},
close: function () {
this.setVisible(false);
console.log('Closing');
},
onCloseClick: function () {
this.close();
BAWK.play('ui_popupclose');
},
onXClick: function () {
this.$emit('popup-x');
this.close();
BAWK.play('ui_popupclose');
},
cancelClick: function () {
this.close();
this.$emit('popup-cancel');
BAWK.play('ui_popupclose');
},
confirmClick: function () {
if (this.popupModel && this.popupModel.validate && !this.popupModel.validate()) {
return;
}
this.close();
this.$emit('popup-confirm');
BAWK.play('ui_playconfirm');
},
outsideClickClose: function() {
if (this.overlayClose === false) {
return;
}
this.removeOverlayClick = this.handleOutsideClick;
document.addEventListener('click', this.removeOverlayClick);
document.addEventListener('keyup', this.escapeKeyClose);
},
escapeKeyClose: function(e) {
e.stopPropagation();
if (e.keyCode === 27 && this.isShowing && this.overlayClose !== false) {
this.onCloseClick();
}
},
handleOutsideClick: function(e) {
e.stopPropagation();
if ( e.target.id.includes('Overlay') ) {
this.onCloseClick();
}
},
cancelEventOverLayClickEscapeClose: function() {
if (this.overlayClose === false) {
return;
}
document.removeEventListener('click', this.removeOverlayClick);
document.removeEventListener('keyup', this.escapeKeyClose);
}
},
}
}
</script>
<template id="house-display-ad">
<transition name="fade">
<figure v-if="isshowing && data" class="house-wrap">
<img :src="src" :alt="title" @click="adClicked" />
</figure>
</transition>
</template>
<script>
function createHouseAd() {
return {
template: '#house-display-ad',
props: ['isshowing', 'data'],
data() {
return {
count: 0
}
},
methods: {
adClicked() {
if ('link' in this.data) {
this.data.link = this.data.link + '/?utm_source=shell_shockers&utm_medium=referral&utm_campaign=house-ads';
}
extern.clickedHouseLink(this.data);
}
},
computed: {
src() {
return dynamicContentPrefix + `data/img/art/${this.data.id}${this.data.imageExt}`;
},
alt() {
return `${this.data.label} banner image!`;
},
link() {
return `${this.data.link}/?utm_source=shell_shockers&utm_medium=referral&utm_campaign=house-ads`;
},
title() {
return `Play ${this.data.label} now!`;
}
}
}
}
Vue.component('house-ad', createHouseAd());
</script><script id="display-ad-template" type="text/x-template">
<div>
<div v-if="!hidden" v-show="isAdShowing" :id="id" class="display-ad-container" :class="theClass"></div>
<house-ad :data="houseAdData" :isshowing="isAdShowing && houseAdData && adBlocker"></house-ad>
</div>
</script>
<script>
// Register popup components globally
Vue.component('display-ad', createDisplayAdComponent('#display-ad-template'));
function createDisplayAdComponent(templateId) {
return {
template: templateId,
props: {
id: String,
hidden: Boolean,
adUnit: String,
isHidden: Boolean,
poki: Boolean,
adSize: String,
override: Boolean,
houseAd: Boolean,
ignoreSize: Boolean,
},
data: function () {
return {
isAdShowing: false,
hideAds: false,
theAd: '',
adRefreshCheck: false,
houseAdData: '',
adBlocker: false,
}
},
mounted() {
this.$nextTick(() => {
this.getTheAd();
});
this.override = this.override || false;
},
methods: {
getTheAd() {
this.theAd = document.getElementById(this.adUnit);
if (pokiActive || extern.productBlockAds) {
return;
}
const wrap = document.getElementById(this.id);
wrap.appendChild(this.theAd);
if (this.houseAd && !crazyGamesActive && !pokiActive) {
googletag.cmd.push(function() { googletag.display('ShellShockers_LoadingScreen_HouseAds') });
}
},
setVisible(visible) {
if (vueData.isUpgraded) {
console.log('Upgrade hides ads');
this.isAdShowing = false;
return;
}
if (extern.productBlockAds) {
console.log('Closure hides ads');
this.isAdShowing = false;
return;
};
this.isAdShowing = visible;
if (!this.isAdShowing) {
window.removeEventListener('resize', this.hideAdBasedOnscreenSize);
// this.adVisibility();
if (pokiActive && this.adSize) PokiSDK.destroyAd(this.$el);
return;
} else {
this.triggerAd();
setTimeout(() => this.hideAdBasedOnscreenSize(), 500);
// this.adVisibility();
window.addEventListener('resize', this.hideAdBasedOnscreenSize);
return;
}
},
show() {
if (extern.productBlockAds) return;
console.log(`display ad ${this.id} showing`);
this.setVisible(true);
},
hide() {
this.setVisible(false);
console.log(`display ad ${this.id} hiding`);
},
crazyGamesAd(id, size) {
// Removing delay per CG's request. Refresh rate is restricted server-side
/*if (this.adRefreshCheck) return;
this.adRefreshCheck = true;
setTimeout(() => this.adRefreshCheck = false, 20000);*/
crazysdk.requestBanner([{
containerId: id,
size: size
}]);
},
triggerAd() {
this.adBlocker = extern.adBlocker;
if (this.adBlocker) {
this.adblockerSetup();
return;
}
if (!pokiActive && !crazyGamesActive && !testCrazy) {
if (this.houseAd) {
gtagInHouseLoadingBanner();
return;
}
aiptag.cmd.display.push(() => aipDisplayTag.display(this.adUnit));
return;
} else if (crazyGamesActive || testCrazy) {
// since crazy games requires an array for multiple ads on screen will cancel the respawn
// ad calls and call them elsewhere
if (this.id === 'shellshockers_respawn_banner_ad' ||
this.id === 'shellshockers_respawn_banner_2_ad' ||
this.id === 'shellshockers_respawn_banner-new_ad') return;
this.crazyGamesAd(this.id, this.adSize);
return;
} else if (pokiActive && this.adSize) {
PokiSDK.displayAd(this.$el, this.adSize);
return;
}
},
toggleAd() {
if (extern.productBlockAds) {
this.isAdShowing = false;
return;
};
this.$nextTick(() => {
if (this.isAdShowing) {
return this.isAdShowing = false;
}
return this.isAdShowing = true;
});
},
adblockerSetup() {
switch(this.id) {
case 'div-gpt-ad-shellshockers-loading-houseads-wrap':
case 'shellshockers_respawn_banner_ad':
case 'shellshockers_respawn_banner-new_ad':
this.houseAdData = extern.getHouseAd('bigBanner');
break;
case 'shellshockers_respawn_banner_2_ad':
case 'shellshockers_titlescreen_wrap':
this.houseAdData = extern.getHouseAd('small');
break;
default:
console.log('House ads say, huh?');
}
},
hideAdBasedOnscreenSize() {
let adWidth = this.$el.offsetWidth;
let intViewportWidth = window.innerWidth;
if (vueApp.displayAdObject && vueApp.displayAdObject > 1 ) {
if (vueApp.displayAdObject < 970) {
return;
}
if (vueApp.displayAdObject > intViewportWidth ) {
this.hide();
}
} else {
if (adWidth < 970) {
return;
}
if (adWidth > intViewportWidth ) {
this.hide();
}
}
},
adVisibility() {
if (this.ignoreSize) return;
googletag.pubads().addEventListener('slotVisibilityChanged', event => {
if (event.inViewPercentage < 51) {
this.hide();
} else {
this.show();
}
}
);
}
},
computed: {
theClass() {
return this.adUnit.toLowerCase().replace(/_/g, "-");
}
},
watch: {
isHidden(value) {
if (!value) {
this.hide();
}
},
}
}
}
</script>
<!-- include_once('./includes/shared_tags/inc_tag_asc_video_player.php'); -->
<script id="language-selector-template" type="text/x-template">
<select id="pickLanguage" v-model="languageCode" @change="onChangeLanguage" class="ss_select ss_marginright_sm">
<option v-for="(language, code) in langOptions" v-bind:value="code">
{{ language }}
</option>
</select>
</script>
<script>
var comp_language_selector = {
template: '#language-selector-template',
props: ['languages', 'selectedLanguageCode', 'loc', 'langOptions'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onChangeLanguage: function () {
vueApp.changeLanguage(this.languageCode);
// Update localStore for selected language.
localStore.setItem('languageSelected', this.languageCode);
BAWK.play('ui_onchange');
ga('send', 'event', {
eventCategory: vueData.googleAnalytics.cat.playerStats,
eventAction: vueApp.googleAnalytics.action.languageSwitch,
eventLabel: this.languageCode,
});
}
},
watch: {
selectedLanguageCode: function (code) {
this.languageCode = code;
}
}
};
</script><script id="gdpr-template" type="text/x-template">
<transition name="fade">
<div v-show="isShowing">
<div id="consent" v-show="showingNotification" class="gdpr_banner f_row">
<div>{{ loc.gdpr_notification }} <a href="http://www.bluewizard.com/privacypolicy" target="_window">{{ loc.gdpr_link }}</a>
</div>
<div class="f_row">
<button @click="onDisagreeClicked()" class="ss_button btn_red bevel_red ss_marginright ss_marginleft">{{ loc.gdpr_disagree }}</button>
<button @click="onAgreeClicked()" class="ss_button btn_green bevel_green">{{ loc.gdpr_agree }}</button>
</div>
</div>
<div id="doConsent" v-show="showingConsent" class="gdpr_banner f_row">
<div>{{ loc.gdpr_consent }}</div>
<div>
<button @click="close()" class="ss_button btn_green bevel_green btn_md">{{ loc.ok }}</button>
</div>
</div>
<div id="noConsent"v-show="showingNoConsent" class="gdpr_banner f_row">
<div>{{ loc.gdpr_noConsent }}</div>
<div>
<button @click="close()" class="ss_button btn_green bevel_green btn_md">{{ loc.ok }}</button>
</div>
</div>
</div>
</transition>
</script>
<script>
var comp_gdpr = {
template: '#gdpr-template',
props: ['loc'],
data: function () {
return {
isShowing: false,
showingNotification: false,
showingConsent: false,
showingNoConsent: false
}
},
methods: {
show: function () {
this.isShowing = true;
this.showingNotification = true;
this.showingConsent = false;
this.showingNoConsent = false;
},
close: function () {
this.isShowing = false;
BAWK.play('ui_playconfirm');
},
onAgreeClicked: function () {
this.showingConsent = true;
this.showingNotification = false;
extern.doConsent();
BAWK.play('ui_onchange');
},
onDisagreeClicked: function () {
this.showingNoConsent = true;
this.showingNotification = false;
extern.doNotConsent();
BAWK.play('ui_onchange');
}
}
};
</script>
<script id="settings-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_settings_title }}</h1>
<div id="horizontalTabs">
<button id="keyboard_button" @click="selectTab" class="ss_bigtab bevel_blue ss_marginright" :class="(showKeyboardTab ? 'selected' : '')"><img src="img/ico_keyboard.svg" class="ss_bigtab_icon"> <img src="img/ico_mouse.svg" class="ss_bigtab_icon"></button>
<button id="controller_button" @click="selectTab" class="ss_bigtab bevel_blue ss_marginright" :class="(showControllerTab ? 'selected' : '')"><img src="img/ico_gamepad.svg" class="ss_bigtab_icon"></button>
<button id="misc_button" @click="selectTab" class="ss_bigtab bevel_blue" :class="(showMiscTab ? 'selected' : '')"><img src="img/ico_monitor.svg" class="ss_bigtab_icon"> <img src="img/ico_speaker.svg" class="ss_bigtab_icon"> <img src="img/ico_privacy.svg" class="ss_bigtab_icon"></button>
</div>
<div id="popupInnards" class="roundme_sm fullwidth f_col ss_margintop_sm ss_marginbottom_xl">
<div id="settings_keyboard" v-show="showKeyboardTab">
<h3 class="nospace">{{ loc.p_settings_keybindings }}</h3>
<div class="f_row ss_margintop">
<div class="f_col">
<div v-for="c in settingsUi.controls.keyboard.game" v-if="c.side == 'left'" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGameControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
<div class="ss_margintop_xl">
<div v-for="c in settingsUi.controls.keyboard.spectate" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onSpectateControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
</div>
<div class="f_col ss_marginleft_xl">
<div v-for="c in settingsUi.controls.keyboard.game" v-if="c.side == 'right'" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGameControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
<div class="ss_margintop">
<div v-for="t in settingsUi.adjusters.mouse" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.togglers.mouse" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
</div>
</div>
<div id="settings_controller" v-show="showControllerTab">
<h3 class="nospace">{{ loc.p_settings_gamepadbindings }}</h3>
<div class="f_row ss_margintop">
<div class="f_col">
<div v-for="c in settingsUi.controls.gamepad.game" class="nowrap">
<settings-gamepad-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGamepadGameControlCaptured" :controller-type="controllerType"></settings-gamepad-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
<div class="f_col ss_marginleft_xl">
<div class="ss_marginbottom_xl">
<div v-for="c in settingsUi.controls.gamepad.spectate" class="nowrap">
<settings-gamepad-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGamepadSpectateControlCaptured" :controller-type="controllerType"></settings-gamepad-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
<div v-for="t in settingsUi.adjusters.gamepad" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" :precision="t.precision" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.togglers.gamepad" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
<p>{{ controllerId }}</p>
<p>{{ loc.p_settings_controllerhelp }} <a target="_blank" href="https://html5gamepad.com">html5gamepad.com</a></p>
</div>
<div id="settings_misc" v-show="showMiscTab">
<div class="f_row">
<div class="f_col">
<header>
<h2>{{loc.p_settings_volume_controls}}</h2>
</header>
<div v-for="t in settingsUi.adjusters.misc" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.adjusters.music" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<h3 class="nospace ss_margintop">{{ loc.p_settings_language }}</h3>
<language-selector :languages="languages" :loc="loc" :selectedLanguageCode="currentLanguageCode" class="ss_select" :langOptions="langOption"></language-selector>
<button v-if="showPrivacyOptions" @click="onPrivacyOptionsClicked" class="ss_button btn_blue bevel_blue btn_md ss_margintop_xl">{{ loc.p_settings_privacy }}</button>
</div>
<div class="f_col ss_marginleft_xl">
<div v-for="t in settingsUi.togglers.misc" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :hide="hideSetting(t.id)" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
</div>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onCloseClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
<button @click="onResetClick" class="ss_button btn_yolk bevel_yolk btn_sm">{{ loc.p_settings_reset }}</button>
<button @click="onSaveClick()" class="ss_button btn_green bevel_green btn_sm">{{ loc.confirm }}</button>
</div>
</div>
</script>
<script id="settings-control-binder-template" type="text/x-template">
<input ref="controlInput" @change="BAWK.play('ui_onchange')" type="text" v-model="currentValue" :placeholder="loc.press_key" class="ss_keybind clickme" :class="(currentValue === 'undefined' ? 'ss_keybind_undefined' : '')"
v-on:mousedown="onMouseDown($event)"
v-on:keydown="onKeyDown($event)"
v-on:keyup="onKeyUp($event)"
v-on:wheel="onWheel($event)"
v-on:focusout="onFocusOut($event)">
</script>
<script>
var comp_settings_control_binder = {
template: '#settings-control-binder-template',
props: ['loc', 'controlId', 'controlValue'],
data: function () {
return {
currentValue: this.controlValue,
isCapturing: false
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
reset: function () {
this.currentValue = (this.controlValue === null) ? 'undefined' : this.controlValue;
this.isCapturing = false;
this.$refs.controlInput.blur();
},
capture: function (value) {
this.isCapturing = false;
this.$refs.controlInput.blur();
this.$emit('control-captured', this.controlId, value);
},
onMouseDown: function (event) {
if (!this.isCapturing) {
this.currentValue = '';
this.isCapturing = true;
} else {
BAWK.play('ui_onchange')
this.capture('MOUSE ' + event.button);
}
},
onKeyDown: function (event) {
this.currentValue = '';
event.stopPropagation();
},
onKeyUp: function (event) {
event.stopPropagation();
var key = event.key;
if (key == 'Escape' || key == 'Tab' || key == 'Enter') {
return;
}
if (key == ' ') {
key = 'space';
event.preventDefault();
}
this.capture(key);
},
onWheel: function (event) {
if (this.isCapturing) {
BAWK.play('ui_onchange')
if (event.deltaY > 0) {
this.capture('WHEEL DOWN');
} else if (event.deltaY < 0) {
this.capture('WHEEL UP');
}
}
},
onFocusOut: function (event) {
this.reset();
}
},
watch: {
// The value prop gets updated by the parent control; watch for changes and update the backing field of the textbox
controlValue: function (newValue) {
this.currentValue = (newValue === null) ? 'undefined' : newValue;
}
}
};
</script><script id="settings-gamepad-binder-template" type="text/x-template">
<button ref="gamepadInput" class="ss_keybind clickme" :class="(currentValue === 'undefined' ? 'ss_keybind_undefined' : '')"
v-on:mousedown="onMouseDown($event)"
v-on:keydown="onKeyDown($event)"
v-on:keyup="onKeyUp($event)"
v-on:focusout="onFocusOut($event)"
:key="controllerType">
<span v-html="currentValue"></span></button>
</script>
<script>
var comp_settings_gamepad_binder = {
template: '#settings-gamepad-binder-template',
props: ['loc', 'controlId', 'controlValue', 'controllerType'],
data: function () {
return {
currentValue: (this.controlValue === null) ? 'undefined' : vueData.controllerButtonIcons[this.controllerType][this.controlValue],
isCapturing: false
}
},
beforeUpdate: function () {
if (!this.isCapturing) {
this.setIcon(this.controlValue);
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
reset: function () {
this.setIcon(this.controlValue);
this.isCapturing = false;
removeEventListener('gamepadbuttondown', this.onButtonDown);
removeEventListener('gamepadbuttonup', this.onButtonUp);
},
capture: function (value) {
this.isCapturing = false;
this.$refs.gamepadInput.blur();
this.$emit('control-captured', this.controlId, value);
this.reset();
},
onMouseDown: function (event) {
if (!this.isCapturing) {
this.currentValue = this.loc.press_button;
this.isCapturing = true;
addEventListener('gamepadbuttondown', this.onButtonDown);
addEventListener('gamepadbuttonup', this.onButtonUp);
}
},
onKeyDown: function (event) {
event.stopPropagation();
},
onKeyUp: function (event) {
event.stopPropagation();
},
onButtonDown: function (event) {
if (event.detail == 8 || event.detail == 9) return;
BAWK.play('ui_onchange')
this.capture(event.detail);
},
onFocusOut: function (event) {
this.reset();
},
setIcon: function (value) {
this.currentValue = (value === null) ? 'undefined' : vueData.controllerButtonIcons[this.controllerType][value];
}
},
watch: {
// The value prop gets updated by the parent control; watch for changes and update the backing field of the textbox
controlValue: function (newValue) {
this.setIcon(newValue);
}
}
};
</script><script id="settings-adjuster-template" type="text/x-template">
<div>
<h3 class="nospace">{{ loc[locKey] }}</h3>
<div class="f_row">
<input class="ss_slider" type="range" :min="min" :max="max" :step="step" v-model="currentValue" @change="onChange">
<label class="ss_slider label">{{ getCurrentValue() }}</label>
</div>
</div>
</script>
<script>
var comp_settings_adjuster = {
template: '#settings-adjuster-template',
props: ['loc', 'locKey', 'controlId', 'controlValue', 'min', 'max', 'step', 'multiplier', 'precision'],
data: function () {
return {
currentValue: this.controlValue
}
},
methods: {
onChange: function (event) {
this.$emit('setting-adjusted', this.controlId, this.currentValue);
BAWK.play('ui_onchange');
},
getCurrentValue: function () {
if (this.precision) {
return Number.parseFloat(this.currentValue).toFixed(this.precision);
}
else {
return Math.floor(this.currentValue * (this.multiplier || 1));
}
}
},
watch: {
// controlValue prop could change when player X's out or clicks Cancel
controlValue: function (newValue) {
if (this.currentValue !== newValue) {
this.currentValue = newValue;
}
}
}
};
</script><script id="settings-toggler-template" type="text/x-template">
<label v-if="!hide" class="ss_checkbox label"> {{ loc[locKey] }}
<input type="checkbox" v-model="currentValue" @change="onChange($event)">
<span class="checkmark"></span>
</label>
</script>
<script>
var comp_settings_toggler = {
template: '#settings-toggler-template',
props: ['loc', 'locKey', 'controlId', 'controlValue', 'hide'],
data: function () {
return {
currentValue: this.controlValue
}
},
methods: {
onChange: function (event) {
this.$emit('setting-toggled', this.controlId, this.currentValue);
BAWK.play('ui_onchange');
}
},
watch: {
// controlValue prop could change when player X's out or clicks Cancel
controlValue: function (newValue) {
if (this.currentValue !== newValue) {
this.currentValue = newValue;
}
}
}
};
</script>
<script>
var comp_settings = {
template: '#settings-template',
components: {
'settings-control-binder': comp_settings_control_binder,
'settings-gamepad-binder': comp_settings_gamepad_binder,
'language-selector': comp_language_selector,
'settings-adjuster': comp_settings_adjuster,
'settings-toggler': comp_settings_toggler
},
props: ['loc', 'settingsUi', 'languages', 'currentLanguageCode', 'showPrivacyOptions', 'controllerId', 'isFromEU', 'controllerType', 'langOption', 'isVip'],
data: function () {
return {
showKeyboardTab: true,
showControllerTab: false,
showMiscTab: false,
originalSettings: {},
showDetailSettings: false,
originalLanguage: '',
originalMusicVolume: '',
musicStatChg: ''
}
},
methods: {
selectTab: function (e) {
return this.switchTab(e.target.id)
},
switchTab(tab) {
this.showKeyboardTab = false;
this.showControllerTab = false;
this.showMiscTab = false;
switch (tab) {
case 'keyboard_button':
this.showKeyboardTab = true;
break;
case 'controller_button':
this.showControllerTab = true;
break;
case 'misc_button':
this.showMiscTab = true;
break;
}
BAWK.play('ui_toggletab');
},
captureOriginalSettings: function () {
this.originalSettings = deepClone(vueData.settingsUi);
this.originalLanguage = this.currentLanguageCode;
// this.originalMusicVolume = this.originalSettings.adjusters.music[0].value;
},
applyOriginalSettings: function () {
vueData.settingsUi = this.originalSettings;
this.showDetailSettings = !vueData.settingsUi.togglers.misc.find( a => { return a.id === 'autoDetail'; }).value;
console.log('applying original settings: ' + JSON.stringify(vueData.settingsUi));
},
onGameControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.keyboard.game, id, value)
},
onSpectateControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.keyboard.spectate, id, value)
},
onGamepadGameControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.gamepad.game, id, value)
},
onGamepadSpectateControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.gamepad.spectate, id, value)
},
onControlCaptured: function (controls, id, value) {
value = value.toLocaleUpperCase();
controls
.forEach( (c) => {
if (c.id === id) {
c.value = value;
} else {
if (c.value === value) {
c.value = null;
}
}
});
},
onSettingToggled: function (id, value) {
console.log('value: ' + value);
Object.values(this.settingsUi.togglers).forEach(v => {
var toggler = v.find(t => { return t.id === id; });
if (toggler) toggler.value = value;
})
if (id === 'autoDetail') {
this.showDetailSettings = !value;
}
if (id === 'safeNames') {
extern.setSafeNames(value);
}
// if (id === 'musicStatus') {
// extern.setMusicStatus(value);
// this.musicStatChg = true;
// if (extern.inGame) {
// vueApp.toggleMusic();
// }
// }
},
onSettingAdjusted: function (id, value) {
Object.values(this.settingsUi.adjusters).forEach(v => {
var adjuster = v.find( (a) => { return a.id === id; });
if (adjuster) adjuster.value = value;
})
if (id === 'volume') {
extern.setVolume(value);
}
if (id === 'mouseSpeed') {
extern.setMouseSpeed(value);
}
if (id === 'sensitivity') {
extern.setControllerSpeed(value);
}
if (id === 'deadzone') {
extern.setDeadzone(value);
}
if (id === 'musicVolume') {
extern.setMusicVolume(value);
}
},
onVolumeChange: function () {
extern.setVolume(this.settingsUi.volume);
},
onPrivacyOptionsClicked: function () {
this.$emit('privacy-options-opened');
BAWK.play('ui_popupopen');
},
onCancelClick: function () {
this.applyOriginalSettings();
//extern.setMusicVolume(this.originalMusicVolume);
this.cancelLanguageSelect();
if (this.musicStatChg) {
if (extern.inGame) {
vueApp.toggleMusic();
}
};
this.$parent.close();
},
onCloseClick: function () {
this.applyOriginalSettings();
//extern.setMusicVolume(this.originalMusicVolume);
this.cancelLanguageSelect();
if (this.musicStatChg) {
if (extern.inGame) {
vueApp.toggleMusic();
}
};
this.$parent.close();
BAWK.play('ui_popupclose');
},
quickSave() {
extern.applyUiSettings(this.settingsUi, this.originalSettings);
this.resetOriginalLanguage();
},
onSaveClick: function () {
// if (vueApp.music.serverTracks.title) {
// this.gaMusicVol();
// }
// this.gaMusicVol();
extern.applyUiSettings(this.settingsUi, this.originalSettings);
this.resetOriginalLanguage();
this.$parent.toggle();
BAWK.play('ui_playconfirm');
},
gaMusicVol() {
let newVol = Number(this.settingsUi.adjusters.music[0].value);
if (newVol === Number(this.originalMusicVolume)) return;
if ((Math.round(newVol*100)) <= 1) {
ga('send', 'event', 'music', 'mute', vueApp.music.serverTracks.title);
}
},
onResetClick: function () {
extern.resetSettings();
BAWK.play('ui_reset');
},
cancelLanguageSelect: function() {
this.originalLanguage === vueApp.$data.currentLanguageCode ?
vueApp.changeLanguage(vueApp.$data.currentLanguageCode) : vueApp.changeLanguage(this.originalLanguage);
// Revert localStore for language
localStore.setItem('languageSelected', this.originalLanguage);
this.resetOriginalLanguage();
},
resetOriginalLanguage: function() {
this.originalLanguage = '';
},
setSettings: function (settings) {
var getSettingById = (list, id) => {
return list.filter( o => {
return o.id == id;
})[0];
};
// Keyboard
getSettingById(this.settingsUi.controls.keyboard.game, 'up').value = settings.controls.keyboard.game.up;
getSettingById(this.settingsUi.controls.keyboard.game, 'down').value = settings.controls.keyboard.game.down;
getSettingById(this.settingsUi.controls.keyboard.game, 'left').value = settings.controls.keyboard.game.left;
getSettingById(this.settingsUi.controls.keyboard.game, 'right').value = settings.controls.keyboard.game.right;
getSettingById(this.settingsUi.controls.keyboard.game, 'jump').value = settings.controls.keyboard.game.jump;
getSettingById(this.settingsUi.controls.keyboard.game, 'fire').value = settings.controls.keyboard.game.fire;
getSettingById(this.settingsUi.controls.keyboard.game, 'scope').value = settings.controls.keyboard.game.scope;
getSettingById(this.settingsUi.controls.keyboard.game, 'reload').value = settings.controls.keyboard.game.reload;
getSettingById(this.settingsUi.controls.keyboard.game, 'swap_weapon').value = settings.controls.keyboard.game.swap_weapon;
getSettingById(this.settingsUi.controls.keyboard.game, 'grenade').value = settings.controls.keyboard.game.grenade;
getSettingById(this.settingsUi.controls.keyboard.spectate, 'ascend').value = settings.controls.keyboard.spectate.ascend;
getSettingById(this.settingsUi.controls.keyboard.spectate, 'descend').value = settings.controls.keyboard.spectate.descend;
// Gamepad
getSettingById(this.settingsUi.controls.gamepad.game, 'jump').value = settings.controls.gamepad.game.jump;
getSettingById(this.settingsUi.controls.gamepad.game, 'fire').value = settings.controls.gamepad.game.fire;
getSettingById(this.settingsUi.controls.gamepad.game, 'scope').value = settings.controls.gamepad.game.scope;
getSettingById(this.settingsUi.controls.gamepad.game, 'reload').value = settings.controls.gamepad.game.reload;
getSettingById(this.settingsUi.controls.gamepad.game, 'swap_weapon').value = settings.controls.gamepad.game.swap_weapon;
getSettingById(this.settingsUi.controls.gamepad.game, 'grenade').value = settings.controls.gamepad.game.grenade;
getSettingById(this.settingsUi.controls.gamepad.spectate, 'ascend').value = settings.controls.gamepad.spectate.ascend;
getSettingById(this.settingsUi.controls.gamepad.spectate, 'descend').value = settings.controls.gamepad.spectate.descend;
// Misc
getSettingById(this.settingsUi.adjusters.misc, 'volume').value = settings.volume;
// getSettingById(this.settingsUi.adjusters.music, 'musicVolume').value = settings.musicVolume;
getSettingById(this.settingsUi.adjusters.mouse, 'mouseSpeed').value = settings.mouseSpeed;
getSettingById(this.settingsUi.adjusters.gamepad, 'sensitivity').value = settings.controllerSpeed;
getSettingById(this.settingsUi.adjusters.gamepad, 'deadzone').value = settings.deadzone;
getSettingById(this.settingsUi.togglers.mouse, 'mouseInvert').value = (settings.mouseInvert !== 1);
getSettingById(this.settingsUi.togglers.mouse, 'fastPollMouse').value = settings.fastPollMouse;
getSettingById(this.settingsUi.togglers.gamepad, 'controllerInvert').value = (settings.controllerInvert !== 1);
getSettingById(this.settingsUi.togglers.misc, 'holdToAim').value = settings.holdToAim;
getSettingById(this.settingsUi.togglers.misc, 'enableChat').value = settings.enableChat;
getSettingById(this.settingsUi.togglers.misc, 'safeNames').value = settings.safeNames;
getSettingById(this.settingsUi.togglers.misc, 'autoDetail').value = settings.autoDetail;
getSettingById(this.settingsUi.togglers.misc, 'shadowsEnabled').value = settings.shadowsEnabled;
getSettingById(this.settingsUi.togglers.misc, 'highRes').value = settings.highRes;
getSettingById(this.settingsUi.togglers.misc, 'hideBadge').value = settings.hideBadge;
// getSettingById(this.settingsUi.togglers.misc, 'musicStatus').value = settings.musicStatus;
console.log('auto detail: ' + settings.autoDetail);
this.showDetailSettings = !settings.autoDetail;
},
hideSetting(id) {
if (id === 'hideBadge' && !this.isVip) {
return true;
}
return false;
}
}
};
</script><script id="help-template" type="text/x-template">
<div>
<div id="horizontalTabs">
<button id="faq_button" @click="toggleTabs" class="ss_bigtab bevel_blue ss_marginright" :class="(showTab1 ? 'selected' : '')">{{ loc.faq }}</button>
<button id="fb_button" @click="toggleTabs" class="ss_bigtab bevel_blue" :class="(!showTab1 ? 'selected' : '')">{{ loc.feedback }}</button>
</div>
<div v-show="showTab1">
<div id="feedback_panel">
<h1>{{ loc.faq_title }}</h1>
<help-questions :content="localizeThis"></help-questions>
<hr>
<div id="btn_horizontal" class="f_center">
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
</div>
</div>
</div>
<div v-show="!showTab1">
<div id="feedback_panel">
<h1>{{ loc.fb_feedback_title }}</h1>
<p>{{ loc.fb_feedback_intro }}</p>
<div id="btn_horizontal" class="f_center">
<select v-model="selectedType" class="ss_field ss_marginright" @click="BAWK.play('ui_click')" @change="BAWK.play('ui_onchange')">
<option v-for="type in feedbackType" :value="type.id">{{ loc[type.locKey] }}</option>
</select>
<input id="feedbackEmail" v-model="email" :placeholder="loc.fb_email_ph" class="ss_field" v-on:keyup="validateEmail">
</div>
<div>
<textarea id="feedbackText" class="ss_field" v-model="feedback" :placeholder="loc.fb_feedback_ph" v-on:keyup="validateMessage"></textarea>
</div>
<div class="f_center f_col">
<span v-show="emailInvalid" class="ss_marginright error_text">{{ loc.fb_bad_email }}</span>
<span v-show="messageInvalid" class="ss_marginright error_text">{{ loc.fb_no_comment }}</span>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
<button @click="onSendClick" class="ss_button btn_md btn_green bevel_green">{{ loc.fb_send }}</button>
</div>
</div>
</div>
</div>
</script>
<script id="help-question-template" type="text/x-template">
<div>
<div v-for="qa in content">
<a :name="qa[0]"></a>
<h3>{{ qa[1] }}</h3>
<span v-html="qa[2]"></span>
</div>
</div>
</script>
<script>
var comp_help_question = {
template: '#help-question-template',
props: ['content'],
};
</script>
<script>
var comp_help = {
template: '#help-template',
components: {
'help-questions': comp_help_question,
},
props: ['loc'],
mounted() {
this.helpLocSetup();
},
data: function () {
return {
showTab1: true,
feedbackType: [
{ id: 0, locKey: 'fb_type_commquest' },
{ id: 1, locKey: 'fb_type_request' },
{ id: 2, locKey: 'fb_type_bug' },
{ id: 3, locKey: 'fb_type_purchase' },
{ id: 4, locKey: 'fb_type_account' },
{ id: 5, locKey: 'fb_type_abuse' },
{ id: 6, locKey: 'fb_type_other' }
],
selectedType: 0,
email: '',
feedback: '',
doValidation: false,
emailInvalid: false,
messageInvalid: false,
qaNum: [1,2,3,4,5,6,7,8,9,10,11],
newLoc: [],
localizeThis: [],
}
},
feedbackValidateTimeout: 0,
methods: {
playSound (sound) {
BAWK.play(sound);
},
validateEmail: function () {
if (!this.doValidation) {
return;
}
// Insane e-mail-validating regex
var re = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
this.emailInvalid = (this.email === '' || !re.test(this.email));
return !this.emailInvalid;
},
validateMessage: function () {
if (!this.doValidation) {
return;
}
this.messageInvalid = this.feedback === '';
return !this.messageInvalid;
},
toggleTabs: function () {
this.showTab1 = !this.showTab1;
BAWK.play('ui_toggletab');
! this.showTab1 && ga('send', 'event', 'feedback opened');
},
onBackClick: function () {
vueApp.$refs.helpPopup.toggle();
BAWK.play('ui_popupclose');
},
onSendClick: function () {
this.doValidation = true;
if (!this.validateEmail() || !this.validateMessage()) {
return;
}
BAWK.play('ui_playconfirm');
// Send that shit out
extern.api_feedback(this.selectedType, this.email, this.feedback);
setTimeout(() => {
this.$parent.toggle();
this.selectedType = 0;
this.feedback = null;
this.email = null;
}, 900);
},
helpLocSetup(locContent) {
let content = this.loc;
// if (locContent) {
// content = locContent
// }
const locArray = Object.entries(content);
this.newLoc = locArray.filter( (item, i) => {
if (item[0].includes('faqItems_q')) {
return item;
}
});
const tranlateThat = [];
for (let n = 0; n < this.qaNum.length; n++) {
tranlateThat.push([]);
for (let i = 0; i < this.newLoc.length; i++) {
if (this.newLoc[i][0].includes('faqItems_q' + this.qaNum[n] + '_')) {
tranlateThat[n].push(this.newLoc[i][1]);
}
}
}
// Cause once again... vue
setTimeout(() => {this.localizeThis = tranlateThat}, 500);
}
},
watch: {
loc(val) {
this.helpLocSetup(val);
}
}
};
</script><script id="vip-help-template" type="text/x-template">
<div>
<div id="feedback_panel">
<h1>{{ loc.vipHelptitle }}</h1>
<small class="text_red"><i class="fas fa-exclamation-triangle"></i> {{loc.vipHelpDesc2}}</small>
<p>{{loc.vipHelpDesc}}</p>
<div>
<a :name="loc.vipFaqItems_q1_anchor"></a>
<h3>{{ loc.vipFaqItems_q1_q }}</h3>
<p>{{ loc.vipFaqItems_q1_a_1 }}</p>
<ul>
<li>{{ loc.vipFaqItems_q1_li_1 }}</li>
<li>{{ loc.vipFaqItems_q1_li_2 }}</li>
<li>{{ loc.vipFaqItems_q1_li_3 }}</li>
<li>{{ loc.vipFaqItems_q1_li_4 }}</li>
<li>{{ loc.vipFaqItems_q1_li_5 }}</li>
<li>{{ loc.vipFaqItems_q1_li_6 }}</li>
</ul>
</div>
<div>
<a :name="loc.vipFaqItems_q2_anchor"></a>
<h3>{{ loc.vipFaqItems_q2_q }}</h3>
<p>{{ loc.vipFaqItems_q2_a_1 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q3_anchor"></a>
<h3>{{ loc.vipFaqItems_q3_q }}</h3>
<p>{{ loc.vipFaqItems_q3_a_1 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q4_anchor"></a>
<h3>{{ loc.vipFaqItems_q4_q }}</h3>
<p>{{ loc.vipFaqItems_q4_a_mobile_3 }}</p>
<p>{{ loc.vipFaqItems_q4_a_1 }}</p>
<p>{{ loc.vipFaqItems_q4_a_2 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q5_anchor"></a>
<h3>{{ loc.vipFaqItems_q5_q }}</h3>
<p>{{ loc.vipFaqItems_q5_a_1 }}</p>
<p>{{ loc.vipFaqItems_q5_a_2 }}</p>
<p>{{ loc.vipFaqItems_q5_a_3 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q6_anchor"></a>
<h3>{{ loc.vipFaqItems_q6_q }}</h3>
<p>{{ loc.vipFaqItems_q6_a_1 }}</p>
<p>{{ loc.vipFaqItems_q6_a_2 }}</p>
<p>{{ loc.vipFaqItems_q6_a_3 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q7_anchor"></a>
<h3>{{ loc.vipFaqItems_q7_q }}</h3>
<p>{{ loc.vipFaqItems_q7_a_1 }}</p>
</div>
<!--
<div v-for="qa in loc.vipFaqItems">
<a :name="qa.anchor"></a>
<h3>{{ qa.q }}</h3>
<p v-for="p in qa.a">
{{p}}
</p>
<ul v-if="qa.li">
<li v-for="li in qa.li">{{li}}</li>
</ul>
</div> -->
<hr>
<div id="btn_horizontal" class="f_center">
<button @click="openVipStore" class="ss_button btn_md btn_green bevel_green ss_marginright">{{ subButtonTxt }}</button>
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
</div>
</div>
</div>
</script>
<script>
var vip_help = {
template: '#vip-help-template',
props: ['loc', 'isVip'],
data: function () {
return {
}
},
methods: {
onBackClick() {
BAWK.play('ui_popupclose');
this.$parent.hide();
},
openVipStore() {
this.$parent.hide();
vueApp.showSubStorePopup();
}
},
computed: {
subButtonTxt() {
return this.isVip ? this.loc.sManageBtn : this.loc.account_vip;
}
}
};
</script><script id="egg-store-template" type="text/x-template">
<div class="fullwidth">
<h1 class="roundme_sm">{{ loc.p_egg_shop_title }}</h1>
<div class="display-grid grid-column-4-eq grid-gap-space-lg">
<egg-store-item v-for="item in products" :key="item.sku" :item="item" :loc="loc" inStore="true" :account-set="accountSettled" :isUpgraded="isUpgraded" :isSaleEvent="saleEvent"></egg-store-item>
</div>
</div>
</script>
<template id="comp-store-item">
<figure id="popupInnards" v-if="showItem" class="single-egg-store-item box_blue4 roundme_md f_col text-center box_relative" :class="[itemType, {purchased: purchased}]">
<div v-if="purchased" class="single-egg-store-item-purchased">{{loc.p_egg_shop_purchased}}</div>
<div v-if="item.flagText" id="eggshop_banner" :class="{sale: item.salePrice}">
<img v-if="!item.salePrice && !item.itemId" src="img/egg-shop-banner-left.png">
<div class="eggshop_banner_mid">
<i v-if="item.salePrice || item.itemId" class="fas" :class="flagTxt"></i>
{{ item.discount }} {{ loc[item.flagText] }}
</div>
</div>
<figcaption>
<p align="center" class="nospace roundme_md"><img :src="img" class="eggshop_image roundme_md"></p>
<h6 class="nospace shadow_bluebig4 eggshop_bigtitle">{{ loc[title] }}</h6>
<span v-if="showSubtitle" class="eggshop_subtitle text_white">{{ loc[description] }}</span>
<div class="f_row">
<div class="eggshop_pricebox roundme_sm" :class="{ slashed: item.salePrice }">${{ item.price }} USD</div>
<div v-if="item.salePrice" class="eggshop_pricebox roundme_sm sale-price">${{ item.salePrice }} USD</div>
</div>
<button class="store_btn ss_button btn_green bevel_green btn_sm center_h" @click="onItemClicked(item.sku)">{{ buyBtnText }}</button>
<div v-if="item.type === 'item' && !hasPurchased && inStore">
<button class="ss_button btn_yolk bevel_yolk btn_sm center_h vip-get-btn box_absolute" @click="onVipClick"><span>{{ loc.p_egg_shop_free_with_vip }}</span> <img src="img/vip-club/vip-club-emblem-sm.png" alt=""></button>
</div>
</figcaption>
</figure>
</template>
<script>
const comp_store_item = {
template: '#comp-store-item',
props: ['loc', 'item', 'inStore', 'accountSet', 'isUpgraded', 'isSaleEvent'],
data() {
return {
purchased: false,
attempt: 0,
};
},
methods: {
onItemClicked() {
if (!this.accountSet || !vueApp.accountSettled) {
vueApp.hideEggStorePopup();
setTimeout(() => {
if (this.attempt < 5) {
this.onItemClicked(this.item.sku);
this.attempt++;
} else {
vueApp.showGenericPopup('uh_oh', 'error', 'ok');
}
}, 300);
vueApp.pleaseWaitPopup();
return;
}
if (this.$parent.$el.id === 'help') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
if (this.item.type === 'item' && !hasValue(this.item.itemId.id) && !Number.isInteger(this.item.itemId)) {
vueApp.showGenericPopup('uh_oh', 'p_egg_shop_no_item_id', 'ok');
return;
}
if (this.purchased) {
console.log('Item is owned so lets go see it.');
vueApp.showItemOnEquipScreen(extern.catalog.findItemById(this.item.itemId.id));
return;
}
extern.buyProductForMoney(this.item.sku);
ga('send', 'event', vueApp.googleAnalytics.cat.purchases, vueApp.googleAnalytics.action.eggShackProductClick, this.item.sku);
},
isPurchased() {
if (this.item.itemId) {
return this.purchased = extern.isItemOwned(this.item.itemId);
}
},
onVipClick() {
this.$parent.$parent.hide();
vueApp.showSubStorePopup();
}
},
computed: {
title() {
return `${this.item.sku}_title`;
},
description() {
return `${this.item.sku}_desc`;
},
img() {
if (this.item.type === 'item') {
return `img/store/items/${this.item.sku}.gif`;
}
const path = !this.isSaleEvent ? '' : 'store-black-friday/';
return `img/${path}${this.item.sku}.png`;
},
itemType() {
return 'single-egg-store-item-is-' + this.item.type;
},
buyBtnText() {
if (this.purchased) {
return this.loc.p_egg_shop_see_item;
}
return this.loc.p_buy_item_confirm;
},
showItem() {
if (this.inStore) return this.item.inStore;
this.isPurchased();
return true;
},
flagTxt() {
if (this.item.salePrice) {
return 'fa-tag';
}
return 'fa-gem'
},
showSubtitle() {
if (this.item.type === 'item') return true;
if (this.isSaleEvent) {
return false;
}
return true;
},
hasPurchased() {
return this.isPurchased();
}
},
watch: {
accountSet(val) {
if (val) {
this.isPurchased();
}
},
isUpgraded(val) {
if (val) {
this.isPurchased();
}
}
}
};
</script>
<script>
var comp_egg_store = {
template: '#egg-store-template',
components: {
'egg-store-item': comp_store_item,
},
data() {
return vueData;
},
props: ['loc', 'products', 'saleEvent'],
methods: {
onItemClicked: function (sku) {
if (!this.accountSettled) {
console.log(this.$parent.hide());
setTimeout(() => {
this.onItemClicked(sku)
}, 300);
vueApp.pleaseWaitPopup();
return;
}
if (vueApp.$refs.genericPopup.isShowing === true) vueApp.$refs.genericPopup.close();
this.$parent.hide();
extern.buyProductForMoney(sku);
ga('send', 'event', this.googleAnalytics.cat.purchases, this.googleAnalytics.action.eggShackProductClick, sku);
}
},
};
</script><script id="house-ad-big-template" type="text/x-template">
<div v-show="(useAd !== null)">
<button @click="onCloseClicked" class="popup_close splash_ad_close ad_close"></button>
<img :src="adImageUrl" @click="onClicked" class="splash_ad_image centered roundme_md">
</div>
</script>
<script>
var comp_house_ad_big = {
template: '#house-ad-big-template',
data: function() {
return {
removeOverlayClick: '',
}
},
props: ['useAd'],
bigAdTimeout: null,
methods: {
onCloseClicked: function () {
console.log('big ad closed');
this.close();
},
onClicked: function () {
this.close();
BAWK.play('ui_click');
extern.clickedHouseAdBig(this.useAd);
},
close: function () {
if (this.useAd === null) {
return;
}
BAWK.play('ui_popupclose');
this.$emit('big-house-ad-closed');
},
outsideClickClose: function() {
const showingId = document.getElementById('house-ad-big-template', true);
this.removeOverlayClick = this.handleOutsideClick;
document.addEventListener('click', this.removeOverlayClick);
},
handleOutsideClick: function(e) {
// Stop bubbling
e.stopPropagation();
// If the target does NOT include the class splash_ad_image use the onCloseClicked method and remove the eventListener
if ( ! e.target.id.includes('splash_ad_image') ) {
this.onCloseClicked();
document.removeEventListener('click', this.removeOverlayClick);
}
},
},
computed: {
adImageUrl: function () {
if (!hasValue(this.useAd)) {
return;
}
return dynamicContentPrefix + 'data/img/art/{0}{1}'.format(this.useAd.id, this.useAd.imageExt);
}
},
watch: {
useAd: function (bigAd) {
if (hasValue(bigAd)) {
setTimeout(() => {
vueApp.hideTitleScreenAd();
}, 100);
this.$options.bigAdTimeout = setTimeout(function () {
vueApp.ui.houseAds.big = null;
}, 15000);
// Close with outside click
this.outsideClickClose();
} else {
vueApp.showTitleScreenAd();
}
}
}
};
</script><script id="house-ad-small-template" type="text/x-template">
<img v-show="(useAd !== null)" :src="adImageUrl" @click="onClicked" class="news_banner roundme_md">
</script>
<script>
var comp_house_ad_small = {
template: '#house-ad-small-template',
props: ['useAd'],
methods: {
onClicked: function () {
BAWK.play('ui_click');
extern.clickedHouseAdSmall(this.useAd);
}
},
computed: {
adImageUrl: function () {
if (!hasValue(this.useAd)) {
return;
}
ga('send', 'event', {
eventCategory: 'House banner ad',
eventAction: 'show',
eventLabel: this.useAd.label
});
return dynamicContentPrefix + 'data/img/art/{0}{1}'.format(this.useAd.id, this.useAd.imageExt);
}
}
};
</script>
<script id="item-template" type="text/x-template">
<div v-if="active" class="store_item roundme_lg clickme" ref="eggItemInvetory" :class="highlightSelected()" @click="onClick">
<div v-if="isPremium" class="store_item-premium" :class="{'is-vip-item': isVipItem}">
{{itemBannerText}}
</div>
<div v-if="showPrice" class="equip_smallprice">
<svg v-if="!isPremium" class="equip_egg eggIcon"><use xlink:href="#icon-egg"></use></svg>
<i v-if="isPremium" class="fas fa-dollar-sign equip_egg eggIcon"></i>
<div class="equip_cost"> {{ item.price }}</div>
</div>
<canvas ref="itemCanvas" class="equip_icon" width="250" height="250"></canvas>
</div>
</script>
<script>
var comp_item = {
template: '#item-template',
props: ['loc', 'item', 'showItemOnly', 'isSelected', 'equippedSlot'],
data: function () {
return {
itemOnly: hasValue(this.showItemOnly) ? this.showItemOnly : false,
active: true,
}
},
mounted() {
this.prepareItem();
this.itemHightlightedOrder();
},
methods: {
isItemSellable: function () {
return !this.itemOnly && vueData.equip.mode == vueData.equip.equipModes.shop;
},
isPremItem() {
if (this.isPremium && this.isItemSellable()) {
const ITEM = vueData.premiumShopItems.find(i => {
return i.itemId.id && i.itemId.id === this.item.id && i.type === 'item';
});
if (ITEM !== undefined && ITEM.isActive) {
this.item.sku = ITEM.sku;
this.item.price = ITEM.salePrice ? ITEM.salePrice : ITEM.price;
} else {
this.active = false;
}
}
this.isMerch();
},
isMerch() {
if (this.showPhysicalMerch && vueData.equip.mode === vueData.equip.equipModes.shop) {
this.item.active = false;
}
this.isEquippedSlot();
},
isEquippedSlot() {
if (this.equippedSlot) {
this.active = true;
}
vueApp.equip.lazyRenderTimeouts.push(setTimeout(() => this.renderItem(), 0));
},
prepareItem: function () {
this.isPremItem();
},
renderItem() {
extern.renderItemToCanvas(this.item, this.$refs.itemCanvas);
},
highlightSelected: function () {
return this.isSelected ? 'highlight' : '';
},
onClick: function () {
this.$emit('item-selected', this.item);
},
itemHightlightedOrder: function() {
if (this.showPhysicalMerch && vueData.equip.mode == vueData.equip.equipModes.shop) return;
return this.$refs.eggItemInvetory.classList.contains('highlight') ? this.$refs.eggItemInvetory.style.order='-1' : null;
},
},
computed: {
showPrice () {
return this.isItemSellable() && this.item.price > 0;
},
showPhysicalMerch () {
return this.isItemSellable() && this.item.unlock === 'physical';
},
isPremium() {
return this.item.unlock === 'premium';
},
isVipItem() {
if ('tags' in this.item.item_data ) {
if (this.item.item_data.tags.includes('vipItem')) {
return true;
}
}
},
itemBannerText() {
return this.isVipItem ? 'VIP' : 'Premium';
}
},
watch: {
item: function (val) {
this.prepareItem();
}
}
};
</script><script id="chickn-winner-template" type="text/x-template">
<div id="popupInnards" class="box_dark roundme_sm fullwidth f_col">
<header class="display-grid grid-column-1-eq grid-align-items-center roundme_lg">
<h1 class="chickn-winner-title nospace text-center">{{ loc.chw_ready_msg }}</h1>
</header>
<section id="chickn-winner-wrapper" class="egg-chick-wrapper f_row roundme_lg">
<div class="egg-chick-box box_relative" v-for="egg in eggs" :key="egg.id">
<div v-if="showAmountRewarded && busted && egg.value > 5" class="text-center chw-reward-amount box_absolute">
<h2 class="box_relative shadow_grey">{{ showAmountRewarded }} <img class="chw-winner-egg" src="img/ico_goldenEgg.svg" /></h2>
</div>
<img class="incentivized-egg-chick box_relative" :class="eggClass(egg.value)" @click="eggClickCounter" :src="eggSrc(egg.value)" :id="egg.id">
</div>
</section>
<!-- #chickn-winner-wrapper -->
<footer class="text-center">
<h2 v-if="!busted">{{ loc.p_nugget_instruction }}</h2>
<button v-if="busted" id="gotWinnerOk" v-show="isMiniGameComplete" @click="onGotWinner" class="ss_button btn_medium btn_yolk bevel_yolk btn_shiny">{{ loc.p_nugget_button }}</button>
<display-ad id="shellshockers_chicken_nugget_banner_ad" ref="nuggetDisplayAd" class="pauseFiller center_h" :ignoreSize="true" :adUnit="adUnits.display.nugget" adSize="728x90"></display-ad>
</footer>
</div>
<!-- #popupInnards -->
</script>
<script>
var comp_chickn_winner_popup = {
template: '#chickn-winner-template',
props: ['loc', 'amountGiven', 'adUnits'],
data: function () {
return {
clickedIdx: 0,
eggs: [{id:'eggOne', value: 0, active: true}, {id:'eggTwo', value: 0, active: true}, {id:'eggThree', value: 0, active: true}],
isMiniGameComplete: false,
bustedSrc: `img/incentivized-mini-game/svg/Egg07.svg`,
busted: false,
bustedTimer: 1414
}
},
methods: {
placeBannerAdTag: function (tagEl) {
this.$refs.chickenNuggetAdContainer.appendChild(tagEl);
},
showAd() {
return this.$refs.nuggetDisplayAd.show();
},
hideAd() {
return this.$refs.nuggetDisplayAd.hide();
},
eggSrc(count) {
if (count > 6) {
return `img/incentivized-mini-game/svg/Egg06.svg`;
}
return `img/incentivized-mini-game/svg/Egg0${count}.svg`;
},
eggSrcBusted() {
setTimeout(() => {
return `img/incentivized-mini-game/svg/Egg07.svg`;
}, 2424);
},
eggBg(count) {
if (count > 5) {
return 'incentivized-show'
}
},
eggClass(count) {
if (count > 5) {
return 'chick-alive';
}
},
eggClickCounter(e) {
if (!this.busted) {
BAWK.play('mini-egg-game_shellhit');
} else {
BAWK.play('mini-egg-game_chick');
}
this.clickedIdx = this.eggs.findIndex(i => i.id === e.target.id);
let elem = document.getElementById(this.eggs[this.clickedIdx].id);
if (this.eggs[this.clickedIdx].value < 6) {
elem.classList.add('chickn-winner-clicked');
setTimeout(() => elem.classList.remove('chickn-winner-clicked'), 650);
}
if (this.eggs[this.clickedIdx].value === 5) {
this.isMiniGameComplete = true;
ga('send', 'event', 'Chickn Winner', 'Egg Game', `egg-cracked-${this.eggs[this.clickedIdx].id}`);
setTimeout(() => {
this.eggs[this.clickedIdx].active = false;
elem.src = this.bustedSrc;
}, this.bustedTimer);
this.busted = true;
extern.api_checkBalance();
this.eggs.forEach(i => {
if (i.id === e.target.id) {
return;
}
let btn = document.getElementById(i.id).style.pointerEvents = 'none';
btn.disabled = true;
});
}
if (this.eggs[this.clickedIdx].value === 100) {
BAWK.play('mini-egg-game_shial');
}
this.eggs[this.clickedIdx].value++;
},
resetGame() {
setTimeout(() => {
this.isMiniGameComplete = false;
this.busted = false;
this.eggs.forEach(i => {
let btn = document.getElementById(i.id).style.pointerEvents = 'all';
btn.disabled = false;
});
this.eggs = [{id:'eggOne', value: 0, active: true}, {id:'eggTwo', value: 0, active: true}, {id:'eggThree', value: 0, active: true}];
}, 1000);
},
onGotWinner: function () {
this.$parent.hide();
this.hideAd();
this.resetGame();
extern.checkStartChicknWinner(false, true);
if (extern.inGame) {
vueApp.showGameMenu();
}
},
// loadMiniGame: function () {
// this.isMiniGameComplete = false;
// this.$refs.miniGameFrame.src = "app_nugget/index.html";
// this.$refs.nuggetDisplayAd.show();
// },
// unloadMiniGame: function () {
// this.$refs.miniGameFrame.src = "about:blank";
// },
// onMiniGameCompleted: function () {
// this.isMiniGameComplete = true;
// }
},
computed: {
showAmountRewarded() {
if (this.amountGiven === 0) {
return;
}
return `+${this.amountGiven}`;
},
},
watch: {
busted(val) {
if (val) {
BAWK.play('mini-egg-game_shellburst');
setTimeout(() => {
BAWK.play('mini-egg-game_victory');
}, 500);
}
}
}
};
</script>
<script id="home-screen-template" type="text/x-template">
<div>
<house-ad-big id="big-house-ad" ref="bigHouseAd" :useAd="ui.houseAds.big" @big-house-ad-closed="onBigHouseAdClosed"></house-ad-big>
<div ref="chw-home-timer" v-show="!isPoki && firebaseId" class="chw-home-timer display-grid grid-column-1-2 grid-align-items-center box_absolute grid-gap-1" :class="chwHomeTimerCls">
<div>
<img class="chw-home-timer-chick" :src="chwChickSrc">
</div>
<div class="display-grid grid-align-items-center bg_white chw-circular-timer-container box_relative" :class="chwClass">
<div v-show="chwShowTimer" class="chw-home-screen-timer"></div>
<!-- #chw-circular-timer-outer -->
<div>
<p class="chw-circular-timer-countdown nospace">
<span class="chw-pie-remaining text_center chw-msg chw-r-msg">{{ remainingMsg }}</span>
<span v-show="chwShowTimer" class="chw-pie-num chw-pie-mins"></span><span v-show="chwShowTimer" class="chw-pie-num chw-pie-secs"></span>
</p>
<button v-if="chicknWinnerReady && !hasChwPlayClicked && !isChicknWinnerError" class="ss_button btn_sm btn_yolk bevel_yolk" @click="playIncentivizedAd">{{ playAdText }}</button>
</div>
</div>
<!-- <img src="img/chicken-nugget/speechBubble_static2_tail1.svg" class="chw-bubble-tail box_absolute" alt=""> -->
</div>
<div id="mainHead">
<account-panel id="account_panel" ref="accountPanelHome" :loc="loc" :selected-language-code="currentLanguageCode" :eggs="eggs" :languages="languages" :currentLangOptions="locLanguage" :show-corner-buttons="ui.showCornerButtons" :show-bottom="true" :photo-url="photoUrl" :is-anonymous="isAnonymous" :is-of-age="isOfAge" :show-targeted-ads="showTargetedAds" :ui="ui" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" @sign-in-clicked="onSignInClicked" @sign-out-clicked="onSignOutClicked" :is-twitch="twitchLinked"></account-panel>
<!-- <pwa-button :show="ui.showCornerButtons"></pwa-button> -->
<!-- <streamer-panel id="youtube_panel" :streams="youtubeStreams" :title="loc.youtube_title" :viewers="loc.youtube_viewers" icon="ico_youtube"></streamer-panel> -->
</div>
<div id="mainLayout">
<div id="logo">
<a href="https://www.shellshock.io" @click="BAWK.play('ui_click')"><img class="home-screen-logo" src="img/logo.svg"></a>
<img v-if="eggOrg" class="egg-org-logo" src="img/egg-org/logo_EggOrg.svg">
</div>
<div class="main-content">
<div id="panel_front_play">
<div class="front_panel-events center_h">
<!-- <event-panel :show-soon="true" :show-ui="true"></event-panel> -->
<!-- <img @click="onTwitchDropsClick" title="Click here to manage your Twitch account on Shell Shockers" :src="twitchDropsBtnImgSrs" alt="Twitch drops parachute" class="events-twitch-drop"> -->
<button v-if="isTwitchEvent" class="ss_button twitch-btn btn_sm box_relative" @click="onTwitchDropsClick">Twitch Drops! <span v-html="isTwitchLinked"></span> <img class="box_absolute" src="img/twitch-drops/twitch-drops-parachute.svg" alt=""></button>
</div>
<play-panel id="play_game" ref="playPanel" :loc="loc" :player-name="playerName" :game-types="gameTypes" :current-game-type="currentGameType" :is-game-ready='accountSettled' :server-list="serverList" :current-server-id="currentServerId" :home="home" @playerNameChanged="onPlayerNameChanged"></play-panel>
<vip-club-cta :loc="loc" :upgrade-name="upgradeName" :is-upgraded="isUpgraded" :is-subscriber="isSubscriber" :has-mobile-reward="hasMobileReward" :is-black-fryday="isSale" :is-egg-org="eggOrg" :is-twitch-event="isTwitchEvent"></vip-club-cta>
</div>
<div id="panel_front_egg">
<div id="paper_doll_container"
class="paper-doll--click-container" @click="onEggPlayClick"></div>
<stats-panel id="stats_panel" :loc="loc" :kills="kills" :deaths="deaths" :kdr="kdr" :streak="streak"></stats-panel>
<weapon-select-panel id="weapon_select" :loc="loc" :current-class="classIdx"></weapon-select-panel>
<button class="ss_button btn_md btn_yolk bevel_yolk" @click="onEquipClicked">{{ loc.eq_equipment }}</button>
</div>
<div id="panel_front_news">
<media-tabs ref="mediaTabs" :loc="loc" :newsfeedItems="newsfeedItems" :twitchStreams="twitchStreams" :youtubeStreams="youtubeStreams"></media-tabs>
<!-- <house-ad-small id="banner-ad" :useAd="ui.houseAds.small"></house-ad-small> -->
<display-ad id="shellshockers_titlescreen_wrap" :hidden="hideAds" ref="titleScreenDisplayAd" class="house-small" :ignoreSize="true" :adUnit="adUnits.display.home" adSize="300x250"></display-ad>
</div>
<!-- <house-ad-small id="banner-ad" :useAd="ui.houseAds.small"></house-ad-small> -->
</div>
<!-- .main-content -->
</div>
<div id="mainFooter">
<!-- <chicken-panel ref="chickenPanel" id="chicken_panel" :local="loc" :do-upgraded="isUpgraded"></chicken-panel> -->
<footer-links-panel id="footer_links_panel" :loc="loc"></footer-links-panel>
</div>
<div id="gameDescription">
<h1 class="text-center">{{ loc.home_desc_about }}</h1>
<p class="text-center">{{ loc.home_desc_pick }}
<svg class="eggIcon"><use xlink:href="#icon-egg"></use></svg>
{{ loc.home_desc_loadout }}
<svg class="eggIcon"><use xlink:href="#icon-egg"></use></svg>
{{ loc.home_desc_madeof }}</p>
<section class="text-center">
<p>{{ loc.home_blocked_start }} Alt URL: geometry.best. {{ loc.home_blocked_end }}</p>
</section>
<div class="display-grid grid-column-2-eq grid-gap-1">
<section>
<p>{{ loc.home_desc_p1 }}</p>
<p>
<img src="img/eggPose05.png" style="width: 350px; float: left; margin-right: 1em; shape-outside: polygon(0% 0%, 100% 0%, 100% 41%, 84% 48%, 80% 63%, 59% 74%, 46% 100%, 0% 99%);">{{ loc.home_desc_p2 }}
</p>
</section>
<section>
<p>
<img src="img/eggPose01.png" style="float: right; margin-left: 1em; margin-top: 1em; shape-outside: polygon(1% 0%, 100% 1%, 100% 99%, 50% 100%, 28% 86%, 16% 68%, 14% 51%, 0 35%);">
{{ loc.home_desc_p3 }} <br /><br />
{{ loc.home_desc_p4 }}
</p>
</section>
</div>
<section>
<header>
<h2 class="text-center">{{ loc.home_game_mode_title }}</h2>
</header>
<ul class="display-grid grid-column-2-eq grid-gap-1">
<li v-html="loc.home_game_mode_content_li_1"></li>
<li v-html="loc.home_game_mode_content_li_2"></li>
<li v-html="loc.home_game_mode_content_li_3"></li>
<li v-html="loc.home_game_mode_content_li_4"></li>
</ul>
</section>
<h2 class="text-center">{{ loc.home_desc_controls }}</h2>
<p class="text-center">{{ loc.home_desc_standard }}</p>
<ul class="display-grid grid-column-2-eq" style="min-width: 25em;max-width: 35em;margin:0 auto">
<li> {{ loc.home_desc_control1 }}</li>
<li> {{ loc.home_desc_control2 }}</li>
<li> {{ loc.home_desc_control3 }}</li>
<li> {{ loc.home_desc_control4 }}</li>
<li> {{ loc.home_desc_control5 }}</li>
<li> {{ loc.home_desc_control6 }}</li>
<li> {{ loc.home_desc_control7 }}</li>
</ul>
<p class="text-center">
<button class="ss_button btn_lg btn_blue bevel_blue" @click="openUnblocked">{{ loc.home_unblocked_text }}</button>
</p>
<p>
{{ loc.home_desc_p7 }}
</p>
<p align="center"><button class="ss_button btn_yolk bevel_yolk" @click="vueApp.scrollToTop()">{{ loc.home_backtotop }}</button></p>
</div>
<!-- Popup: Check Email -->
<small-popup id="checkEmailPopup" ref="checkEmailPopup" :hide-cancel="true">
<template slot="header">{{ loc.p_check_email_title }}</template>
<template slot="content">
<p>{{ loc.p_check_email_text1 }}:</p>
<h5 class="nospace text-center">{{ maskedEmail }}</h5>
<p class="ss_marginbottom">{{ loc.p_check_email_text2 }}</p>
</template>
<template slot="confirm">{{ loc.ok }}</template>
</small-popup>
<!-- Popup: Resend Email -->
<small-popup id="resendEmailPopup" ref="resendEmailPopup" @popup-confirm="onResendEmailClicked">
<template slot="header">{{ loc.p_resend_email_title }}</template>
<template slot="content">
<p>{{ loc.p_resend_email_text1 }}:</p>
<h5 class="nospace text-center">{{ maskedEmail }}</h5>
<p class="ss_marginbottom">{{ loc.p_resend_email_text2 }}</p>
</template>
<template slot="cancel">{{ loc.ok }}</template>
<template slot="confirm">{{ loc.p_resend_email_resend }}</template>
</small-popup>
</div>
</script>
<script id="create-private-game-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_privatematch_title }}</h1>
<div class="box_blue2 roundme_sm fullwidth">
<div id="popupInnards" class="fullwidth f_row f_spaced">
<div id="private_left" class="f_col f_start">
<h3 class="text-center fullwidth">{{ loc.p_privatematch_gametype }}</h3>
<select name="gameType" v-model="pickedGameType" class="ss_select fullwidth" @click="BAWK.play('ui_click')" @change="onGameTypeChanged">
<option v-for="g in gameTypes" v-bind:value="g.value" :class="'create-game-' + g.locKey" v-html="loc[g.locKey]"></option>
</select>
<button class="ss_button button_blue bevel_blue fullwidth" @click="onServerClick">{{ loc.server }}: {{ loc[serverLocKey] }}</button>
<button name="play" @click="onPlayClick" class="ss_button btn_big fullwidth btn_green bevel_green btn_sm"><i class="fa fa-play fa-sm"></i> {{ loc.p_privatematch_create }}</button>
<!-- Player limit is not in place yet
<h3 class="nospace">{{ loc.p_privatematch_players }}</h3>
<div id="player_selector">
<img src="./img/ico_arrowLeft.png" class="numberArrow">
<input type="text" v-model class="ss_field fld_number">
<img src="./img/ico_arrowRight.png" class="numberArrow">
</div> -->
</div>
<div class="f_col j_start">
<h3 class="ss_marginleft_lg text-center">{{ loc.p_privatematch_selectmap }}</h3>
<div id="private_maps" class="ss_marginleft_lg roundme_md">
<img :src="mapImgPath" id="mapThumb" class="roundme_sm">
<div id="mapNav">
<button id="mapLeft" @click="onMapChange(-1)" class="clickme"> </button>
<h5 id="mapText" class="shadow_grey">
{{ vueData.maps[mapIdx].name }}
<span class="map_playercount shadow_grey roundme_sm">
<img src="img/ico_eggColour_normal.png">
<span class="ss_marginbottom_xs ss_marginright_xs">x</span>
<span>{{vueData.maps[mapIdx].numPlayers}}</span>
</span>
</h5>
<button id="mapRight" @click="onMapChange(1)" class="clickme"> </button>
</div>
</div>
</div>
</div>
<div id="btn_horizontal" class="f_center nospace">
<button @click="onCloseClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
</div>
</div>
</div>
</script>
<script>
var comp_create_private_game_popup = {
template: '#create-private-game-template',
props: ['loc', 'serverLocKey', 'mapImgBasePath', 'isGameReady'],
data: function () {
let mapIdx = Math.randomInt(0, vueData.maps.length);
let map = vueData.maps[mapIdx];
return {
showingServerList: false,
pickedGameType: 0,
gameTypes: vueData.gameTypes,
mapIdx: mapIdx,
mapImgPath: this.mapImgBasePath + map.filename + '.png?' + map.hash,
mapLocKey: map.locKey,
playClickedBeforeReady: false,
vueData,
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onCloseClick: function () {
this.$parent.close();
BAWK.play('ui_popupclose');
},
onServerClick: function () {
this.showingServerList = true;
this.$parent.toggle();
vueApp.$refs.homeScreen.$refs.playPanel.$refs.pickServerPopup.toggle();
BAWK.play('ui_click');
},
onMapChange: function (dir) {
this.selectMapForPickedGameType(dir);
BAWK.play('ui_onchange');
},
selectMapForPickedGameType (dir) {
let idx = this.mapIdx;
for (var i = 0; i < vueData.maps.length; i++) { // Prevent race condition
if (dir) idx = (idx + dir + vueData.maps.length) % vueData.maps.length;
let map = vueData.maps[idx];
let gameTypeShortName = vueData.gameTypeKeys[this.pickedGameType];
if (map.modes[gameTypeShortName]) {
break;
}
if (dir == 0) dir = 1
//idx = (idx + dir + vueData.maps.length) % vueData.maps.length;
}
this.mapImgPath = this.mapImgBasePath + vueData.maps[idx].filename + '.png?' + vueData.maps[idx].hash;
this.mapLocKey = vueData.maps[idx].locKey;
this.mapIdx = idx;
},
onGameTypeChanged () {
BAWK.play('ui_onchange');
this.selectMapForPickedGameType(0);
},
onPlayTypeWhenSignInComplete() {
return this.playClickFunction();
},
onPlaySentBeforeSignIn() {
this.gameClickedBeforeReady = true;
vueApp.showSpinner('signin_auth_title', 'signin_auth_msg');
},
onPlayClick: function () {
this.$parent.close();
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn();
return;
}
vueApp.externPlayObject(vueData.playTypes.createPrivate, this.pickedGameType, this.vueData.playerName, this.mapIdx, '');
BAWK.play('ui_playconfirm');
}
},
watch: {
isGameReady(val) {
if (this.gameClickedBeforeReady && val) {
setTimeout(() => this.onPlayClick(), 700);
}
}
}
};
</script><script id="account-panel-template" type="text/x-template">
<div>
<div id="account_top">
<!-- <eggstore-notify ref="shirtStore" :show="showCornerButtons" :loc="loc" :sku="sku" icon="fa-tshirt" :text-hide="true" text="p_egg_shop_sale_notify" title="account_threadless" color="blue" url="https://bluewizard.threadless.com/" analytics="threadless"></eggstore-notify> -->
<eggstore-notify ref="eggStoreSaleNotify" :text-hide="!hideNewItemNotify" :show="showCornerButtons" :loc="loc" :sku="sku" title="account_premium_item" icon="fa-gem" text="p_egg_shop_sale_notify" analytics="diamond"></eggstore-notify>
<button v-if="showVipButton" @click="onVipClick" class="ss_button btn_yolk bevel_yolk btn_vip" :title="loc['account_vip']" :class="{'has-sub' : isVipLive}"><img src="img/vip-club/vip-club-emblem-sm.png" alt="VIP Emblem"> {{vipButtonText}}</button>
<div class="account_eggs roundme_sm clickme" @click="onEggStoreClick" v-bind:title="loc['account_title_eggshop']">
<button v-if="isAnonymous" type="image" src="img/attention_indicator.png" v-show="showCornerButtons" @click="onAnonWarningClick" class="ss_button btn_yolk bevel_yolk attention_btn" v-bind:title="loc['account_title_shop']"><i class="fas fa-exclamation"></i></button>
<img src="img/ico_goldenEgg.png" class="egg_icon">
<span class="egg_count shadow_blue2_micro">{{ eggBalance }}</span>
</div>
<!-- <input type="image" src="img/ico_nav_leaderboards.png" class="account_icon roundme_sm"> -->
<div id="corner-buttons" v-show="showCornerButtons">
<input type="image" src="img/ico_nav_shop.png" @click="itemStoreClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_shop']">
<!-- <input type="image" src="img/ico_nav_help.png" @click="onHelpClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_faq']"> -->
<input type="image" src="img/ico_nav_share.png" v-show="showShareLinkButton" @click="onShareLinkClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_invite']">
<input type="image" src="img/ico_nav_settings.png" @click="onSettingsClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_settings']">
<input type="image" src="img/ico_nav_fullscreen.png" v-if="!vueData.isPoki && !crazyGamesActive" @click="onFullscreenClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_fullscreen']">
</div>
</div>
<div id="account_bottom" v-show="showBottom">
<language-selector :languages="languages" :loc="loc" :selectedLanguageCode="selectedLanguageCode" :langOptions="currentLangOptions"></language-selector>
<button id="signInButton" v-show="(isAnonymous && showSignIn)" @click="onSignInClicked" class="ss_button btn_yolk bevel_yolk">{{ loc.sign_in }}</button>
<button id="signOutButton" v-show="!isAnonymous" @click="onSignOutClicked" class="ss_button btn_yolk bevel_yolk">{{ loc.sign_out }}</button>
<div id="player_photo" class="box_relative" v-show="photoUrl !== null && photoUrl !== undefined && photoUrl !== '' && ! isAnonymous">
<img :src="photoUrl" class="roundme_sm bevel_blue"/>
<div v-if="isTwitch" class="box_aboslute account-panel-twitch roundme_sm" @click="onTwitchIconClick"><i class="fab fa-twitch"></i></div>
</div>
</div>
</div>
</script>
<template id="egg-store-notify">
<div v-if="show" class="egg-store-sale-notify" :class="{'white-blue' : color}" @click="notifyClick">
<button class="account_icon roundme_sm account_icon-item" :title="getTitle"><i aria-hidden="true" class="fas" :class="icon"><span class="hideme">Egg</span></i>
<span class="text" :class="{hideme : textHide}"> {{loc[text]}}</span>
</button>
</div>
</template>
<script>
const compEggStoreSaleNotify = {
template: '#egg-store-notify',
props: ['loc', 'show', 'sku', 'textHide', 'text', 'icon', 'color', 'url', 'title', 'analytics'],
methods: {
notifyClick() {
if (this.analytics) ga('send', 'event', 'header-buttons', 'click', this.analytics);
if (this.url) {
window.open(this.url, '_window');
return;
}
// if (!vueData.firebaseId) {
// vueApp.showGenericPopup('p_redeem_error_no_player_title', 'p_redeem_error_no_player_content', 'ok');
// return;
// }
vueApp.eggStoreReferral = 'Sale notify ref';
if (this.sku) {
return vueApp.showPopupEggStoreSingle(this.sku)
}
return vueApp.onPremiumItemsClicked();
}
},
computed: {
getTitle() {
if (!this.title) return null;
return this.loc[this.title];
}
}
};
</script><script>
var comp_account_panel = {
template: '#account-panel-template',
components: {
'language-selector': comp_language_selector,
'eggstore-notify': compEggStoreSaleNotify,
},
props: ['loc', 'eggs', 'languages', 'selectedLanguageCode', 'showBottom', 'photoUrl', 'isAnonymous', 'isOfAge', 'showTargetedAds', 'showCornerButtons', 'ui', 'isEggStoreSale', 'sku', 'isSubscriber', 'isTwitch', 'currentLangOptions'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
eggBalance: 0,
vueData,
}
},
created() {
this.getEggsLocalStorage();
},
methods: {
getEggsLocalStorage() {
const raw = localStore.getItem('localLoadOut');
if (!raw) {
return;
}
const storage = JSON.parse(raw);
if (!'balance' in storage) {
return;
}
return this.eggBalance = storage.balance;
},
onEggStoreClick: function () {
if (!vueData.firebaseId) {
vueApp.showGenericPopup('p_redeem_error_no_player_title', 'p_redeem_error_no_player_content', 'ok');
return;
}
vueApp.showEggStorePopup();
BAWK.play('ui_popupopen');
this.gaSend('shoppingCart');
},
itemStoreClick: function() {
this.gaSend('openItemShop');
vueApp.switchToEquipUi();
vueApp.$refs.equipScreen.switchToShop();
BAWK.play('ui_popupopen');
},
onHelpClick: function () {
vueApp.showHelpPopup();
this.gaSend('openHelp');
BAWK.play('ui_popupopen');
},
onSettingsClick: function () {
this.gaSend('openSettings');
vueApp.showSettingsPopup();
BAWK.play('ui_popupopen');
},
onFullscreenClick: function () {
extern.toggleFullscreen();
BAWK.play('ui_click');
},
onSignInClicked: function () {
vueApp.setDarkOverlay(true);
this.$emit('sign-in-clicked');
BAWK.play('ui_playconfirm');
},
onSignOutClicked: function () {
vueApp.setDarkOverlay(true);
this.$emit('sign-out-clicked');
BAWK.play('ui_reset');
},
onShareLinkClick: function () {
this.gaSend('openShareLink');
extern.inviteFriends();
},
onAnonWarningClick: function() {
ga('send', 'event', vueApp.googleAnalytics.cat.playerStats, vueApp.googleAnalytics.action.anonymousPopupOpen);
vueApp.showAttentionPopup();
},
onVipClick() {
this.gaSend('openVipPopup');
vueApp.showSubStorePopup();
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'header-buttons', 'click', label);
},
onTwitchIconClick() {
window.open(dynamicContentPrefix + 'twitch');
}
},
computed: {
showSignIn: function () {
if (!isFromEU) {
return true;
}
return isFromEU && this.isOfAge && this.showTargetedAds;
},
showShareLinkButton: function () {
return this.showCornerButtons && (this.ui.showScreen === this.ui.screens.game);
},
hideNewItemNotify() {
// if (!ssChangelogDate) return false;
// if (!this.showCornerButtons) return false;
// const lapsed = Date.now() - ssChangelogDate.valueOf(),
// days = Math.floor((lapsed / (60*60*24*1000)));
// if (days <= 5 ) return true;
// return false;
return;
},
vipButtonText() {
return this.isSubscriber && !extern.account.upgradeIsExpired ? '' : this.loc['s-btn-txt-subscribe'];
},
showVipButton() {
return this.ui.showScreen === this.ui.screens.home || this.ui.showScreen === this.ui.screens.equip;
},
isVipLive() {
return this.isSubscriber && !extern.account.upgradeIsExpired;
}
},
watch: {
eggs() {
this.eggBalance = this.eggs;
}
}
};
</script>
<template id="stats_panel_template" type="text/x-template">
<div>
<!-- <h3 class="nospace">{{ loc.home_stats }}</h3> -->
<div class="stats-wrapper">
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.kills.toUpperCase() }}</h4>
<div class="stat_stat">{{ lKills }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.deaths.toUpperCase() }}</h4>
<div class="stat_stat">{{ lDeaths }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.kdr.toUpperCase() }}</h4>
<div class="stat_stat">{{ lKdr }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.streak.toUpperCase() }}</h4>
<div class="stat_stat">{{ lStreak }}</div>
</div>
</div>
</div>
</template>
<script>
var comp_stats_panel = {
template: '#stats_panel_template',
props: ['loc', 'kills', 'deaths', 'kdr', 'streak'],
data: () => {
return {
localLoadOut : Object,
lKills: 0,
lDeaths: 0,
lKdr: 0,
lStreak: 0,
}
},
created() {
this.getStatsLocalStorage();
},
methods: {
getStatsLocalStorage() {
const raw = localStore.getItem('localLoadOut');
if (!raw) {
return;
}
const storage = JSON.parse(raw);
const {kills, deaths, kdr, streak} = storage;
this.lKills = kills;
this.lDeaths = deaths;
this.lKdr = kdr;
this.lStreak = streak;
},
},
watch: {
kills() {
this.lKills = this.kills;
this.lDeaths = this.deaths;
this.lKdr = this.kdr;
this.lStreak = this.streak;
}
}
};
</script>
<script id="play-panel-template" type="text/x-template">
<div>
<div class="front_panel roundme_md">
<input name="name" :value="playerName" v-bind:placeholder="loc.play_enter_name" @change="onNameChange($event)" v-on:keyup="onPlayerNameKeyUp($event)" class="ss_field fullwidth"><br>
<div class="select-box-wrap">
<label for="create-select-type" class="ss_button btn_yolk bevel_yolk"><i class="fas fa-chevron-down"></i></label>
<select id="create-select-type" name="gameType" v-model="pickedGameType" class="ss_select select" @change="onGameTypeChange($event)">
<option v-for="g in gameTypes" v-bind:value="g.value" :class="'game-select-' + g.locKey" v-html="loc[g.locKey]"></option>
</select>
</div>
<br>
<button name="server" @click="onPickServerButtonClick" :disabled="isButtonDisabled" class="ss_button btn_blue bevel_blue fullwidth">{{ loc.server }}: {{ loc[serverLocKey] }}</button><br>
<button name="play" @click="onPlayButtonClick" class="ss_button btn_big btn_yolk bevel_yolk fullwidth nospace play-button"><i class="fa fa-play fa-sm"></i> {{ loc.home_play }}</button>
<h3>{{ loc.home_privategames }}</h3>
<div id="btn_horizontal" class="nospace">
<button name="create" @click="onCreatePrivateGameClick" class="ss_button btn_sm btn_blue bevel_blue">{{ loc.home_create }}</button>
<button name="join" @click="onJoinPrivateGameClick" class="ss_button btn_sm btn_blue bevel_blue">{{ loc.home_join }}</button>
</div>
</div>
<!-- Popup: Pick Server -->
<large-popup id="pickServerPopup" ref="pickServerPopup" @popup-closed="onPickServerPopupClosed">
<template slot="header">{{ loc.server }}</template>
<template slot="content">
<server-list-popup id="server_list_popup" ref="serverListPopup" v-if="(serverList.length > 0)" :loc="loc" :servers="serverList" :picked-server-id="currentServerId" @server-picked="onServerPicked"></server-list-popup>
</template>
</large-popup>
<!-- Popup: Create Private Game -->
<large-popup id="createPrivateGamePopup" ref="createPrivateGamePopup">
<template slot="content">
<create-private-game-popup id="createPrivateGame" ref="createPrivateGame" :loc="loc" :server-loc-key="serverLocKey" :is-game-ready="isGameReady" map-img-base-path="maps/"></create-private-game-popup>
</template>
</large-popup>
<!-- Popup: Join Private Game -->
<small-popup id="joinPrivateGamePopup" ref="joinPrivateGamePopup" :popup-model="home.joinPrivateGamePopup" @popup-confirm="onJoinConfirmed">
<template slot="header">{{ loc.p_game_code_title }}</template>
<template slot="content">
<div class="error_text shadow_red" v-show="home.joinPrivateGamePopup.showInvalidCodeMsg">{{ loc.p_game_code_blank }}</div>
<p><input type="text" class="ss_field ss_margintop ss_marginbottom fullwidth text-center" v-model="home.joinPrivateGamePopup.code" v-bind:placeholder="loc.p_game_code_enter" v-on:keyup.enter="onJoinConfirmed"></p>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
</div>
</script>
<script id="server-list-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_servers_title }}</h1>
<div v-for="s in servers" :key="s.id">
<div id="server_list_item">
<input type="radio" :id="('rb_' + s.id)" name="pickServer" v-bind:value="s.id" v-model="serverId" @click="BAWK.play('ui_onchange')">
<label :for="('rb_' + s.id)" class="serverName">{{ loc[s.locKey] }} </label>
<label :for="('rb_' + s.id)" class="serverPingWrap roundme_sm">
<span class="pingBar" :class="barColorClass(s)" :style="barStyle(s)"></span>
</label>
<label :for="('rb_' + s.id)" class="serverPingNumber ss_marginleft_lg"> {{ s.ping }}ms</label>
</div>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onCancelClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
<button @click="onConfirmClick()" class="ss_button btn_green bevel_green btn_sm">{{ loc.ok }}</button>
</div>
</div>
</script>
<script>
var comp_server_list_popup = {
template: '#server-list-template',
props: ['loc', 'servers', 'pickedServerId'],
data: function () {
return {
colorClasses: ['greenPing', 'yellowPing','orangePing', 'redPing'],
serverId: this.pickedServerId
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
barColorClass: function (server) {
var colorIdx = Math.min(3, Math.floor(server.ping / 100));
return this.colorClasses[colorIdx];
},
barStyle: function (server) {
return {
width: Math.min(10, Math.max(0, server.ping / 100)) + 0.1 + 'em'
}
},
onCancelClick: function () {
this.serverId = this.pickedServerId;
this.$parent.close();
BAWK.play('ui_popupclose');
},
onConfirmClick: function () {
this.$emit('server-picked', this.serverId);
this.$parent.close();
BAWK.play('ui_playconfirm');
}
}
};
</script>
<script>
var comp_play_panel = {
template: '#play-panel-template',
components: {
'create-private-game-popup': comp_create_private_game_popup,
'server-list-popup': comp_server_list_popup
},
props: ['loc', 'playerName', 'gameTypes', 'currentGameType', 'serverList', 'currentServerId', 'home', 'isGameReady'],
// mounted() {
// this.kotcPrompt = document.getElementById('kotc-play-kotc');
// this.typeSelect = document.getElementById('create-select-type');
// this.anchorKotcPrompt();
// window.addEventListener('resize', this.anchorKotcPrompt);
// },
data: function() {
return {
pickedServerId: null,
pickedGameType: this.currentGameType,
isButtonDisabled: true,
playClickedBeforeReady: false,
playClickFunction: Function,
kotcPrompt: '',
typeSelect: ''
}
},
methods: {
onPickServerButtonClick: function () {
this.$refs.pickServerPopup.toggle();
BAWK.play('ui_popupopen');
},
onServerPicked: function (serverId) {
if (vueData.currentServerId === serverId) { return; }
vueData.currentServerId = serverId;
extern.selectServer(vueData.currentServerId);
BAWK.play('ui_onchange');
},
onPickServerPopupClosed: function () {
if (this.$refs.createPrivateGame.showingServerList) {
this.$refs.createPrivateGame.showingServerList = false;
this.$refs.createPrivateGamePopup.toggle();
}
},
onNameChange: function (event) {
console.log('name changed to: ' + event.target.value);
this.$emit('playerNameChanged', event.target.value);
},
onPlayerNameKeyUp: function (event) {
event.target.value = extern.filterUnicode(event.target.value);
event.target.value = extern.fixStringWidth(event.target.value);
event.target.value = event.target.value.substring(0, 128);
// Send username to server to start the game!
if (event.code == "Enter" || event.keyCode == 13) {
if (vueData.playerName.length > 0) {
extern.play({
playType: vueData.playTypes.joinPublic,
playerName: vueData.playerName
});
}
}
},
onGameTypeChange: function (event) {
extern.selectGameType(event.target.value);
BAWK.play('ui_onchange');
},
onPlayTypeWhenSignInComplete() {
return this.playClickFunction();
},
onPlaySentBeforeSignIn(callback) {
this.gameClickedBeforeReady = true;
vueApp.showSpinner('signin_auth_title', 'signin_auth_msg');
this.playClickFunction = callback;
},
hasValidPlayerNameCheck() {
console.log('invalid player name');
vueApp.showGenericPopup('play_pu_name_title', 'play_pu_name_content', 'ok');
vueApp.hideSpinner();
return;
},
onPlayButtonClick: function () {
if (!hasValue(this.playerName)) {
this.hasValidPlayerNameCheck();
return;
}
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn(this.onPlayButtonClick);
return;
}
vueApp.disablePlayButton(true);
vueApp.game.respawnTime = 0;
vueApp.externPlayObject(vueData.playTypes.joinPublic, this.pickedGameType, this.playerName, -1, '');
BAWK.play('ui_playconfirm');
},
onCreatePrivateGameClick: function () {
this.$refs.createPrivateGamePopup.toggle();
BAWK.play('ui_popupopen');
},
onJoinPrivateGameClick: function () {
this.showJoinPrivateGamePopup(vueData.home.joinPrivateGamePopup.code);
BAWK.play('ui_popupopen');
},
showJoinPrivateGamePopup: function (showCode) {
// The popup must be active before it will update; set code after showing
this.$refs.joinPrivateGamePopup.show();
vueData.home.joinPrivateGamePopup.code = showCode;
},
onJoinConfirmed: function () {
if (!hasValue(this.playerName)) {
this.hasValidPlayerNameCheck();
return;
}
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn(this.onJoinConfirmed)
return;
}
let match = null;
if (vueData.home.joinPrivateGamePopup.code.match(/\#\w+/)) {
match = vueData.home.joinPrivateGamePopup.code.match(/\#\w+/)[0];
} else if (vueData.home.joinPrivateGamePopup.code.includes('crazyShare')) {
match = vueData.home.joinPrivateGamePopup.code.match(/=\w*$/)[0].substring(1);
}
else { // In case someone copy/pastes the thing without including the #
match = vueData.home.joinPrivateGamePopup.code;
}
if (!match) {
return;
}
vueData.home.joinPrivateGamePopup.code = match;
this.$refs.joinPrivateGamePopup.hide();
vueApp.externPlayObject(vueData.playTypes.joinPrivate, '', this.playerName, '', vueData.home.joinPrivateGamePopup.code);
},
kotcAttachSetup() {
const typePostion = this.typeSelect.getBoundingClientRect();
const kotcPrompt = this.kotcPrompt.getBoundingClientRect();
this.kotcPrompt.style.top = typePostion.top + 'px';
this.kotcPrompt.style.left = typePostion.right + 16 + 'px';
},
anchorKotcPrompt() {
this.$nextTick(() => this.kotcAttachSetup());
}
},
computed: {
serverLocKey: function () {
if (!hasValue(this.serverList) || this.serverList.length === 0) {
return '';
}
var server = this.serverList.find(s => {
return s.id == vueData.currentServerId;
});
return hasValue(server) ? server.locKey : '';
},
},
watch: {
currentGameType: function (val) {
this.pickedGameType = val;
},
isGameReady(val) {
this.isButtonDisabled = val ? false : true;
if (this.gameClickedBeforeReady && val) {
this.onPlayTypeWhenSignInComplete()
}
}
}
};
</script><template id="weaponselect_panel_template" type="text/x-template">
<div :class="{disabled: !vueData.accountSettled}">
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_EggK47.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Soldier)" @click="selectClass(charClass.Soldier)"><span><strong>{{loc.weapon_soldier_title}}:</strong> {{loc.weapon_soldier_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Scrambler.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Scrambler)" @click="selectClass(charClass.Scrambler)"><span><strong>{{loc.weapon_scrambler_title}}: </strong> {{loc.weapon_scrambler_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_FreeRanger.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Ranger)" @click="selectClass(charClass.Ranger)"><span><strong>{{loc.weapon_ranger_title}}: </strong>{{loc.weapon_ranger_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_RPEGG.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Eggsploder)" @click="selectClass(charClass.Eggsploder)"><span><strong>{{loc.weapon_eggsploder_title}}: </strong> {{loc.weapon_eggsploder_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Whipper.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Whipper)" @click="selectClass(charClass.Whipper)"><span><strong>{{loc.weapon_whipper_title}}: </strong>{{loc.weapon_whipper_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Crackshot.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Crackshot)" @click="selectClass(charClass.Crackshot)"><span><strong>{{loc.weapon_crackshot_title}}: </strong>{{loc.weapon_crackshot_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_TriHard.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.TriHard)" @click="selectClass(charClass.TriHard)"><span><strong>{{loc.weapon_trihard_title}}: </strong>{{loc.weapon_trihard_content}}</span>
</div>
</div>
</template>
<script>
var comp_weapon_select_panel = {
template: '#weaponselect_panel_template',
props: ['currentClass', 'loc'],
data: function () {
return {
charClass: CharClass,
vueData,
}
},
methods: {
selectClass: function (classIdx) {
if (!vueData.accountSettled){
return;
}
extern.changeClass(classIdx);
this.$emit('changed-class', classIdx);
BAWK.play('ui_click');
},
addSelectedCssClass: function (classIdx) {
return (this.currentClass === classIdx)
? 'weapon_selected'
: '';
},
}
// watch: {
// accountSettled(val) {
// }
// }
};
</script>
<script id="newsfeed-panel-template" type="text/x-template">
<section class="v_scroll">
<article v-if="items" v-for="item in activeItems" :key="item.id" @click="onItemThatIsClicked(item)" class="news_item roundme_md clickme">
<img :src="imageSrc(item)" class="news_img roundme_sm">
<p>{{ item.content }}</p>
</article>
</section>
</script>
<script>
var comp_newsfeed_panel = {
template: '#newsfeed-panel-template',
props: ['items'],
data: function () {
return vueData;
},
// mounted: function () {
// // this.fetchWebData();
// this.checklocalForNewsData();
// },
methods: {
imageSrc(item) {
return dynamicContentPrefix + 'data/img/newsItems/' + item.id + item.imageExt;
},
onItemThatIsClicked(item) {
console.log(item);
extern.clickedWebFeedItem(item);
BAWK.play('ui_click');
},
},
computed: {
activeItems() {
return this.items.filter(item => item.active);
}
}
};
</script><script id="chicken-panel-template" type="text/x-template">
<div id="showBuyPassDialogButton" class="new">
<div class="chicken-panel--upgraded" v-show="doUpgraded && !isSubscriber">
<div class="tool-tip tool-tip--right">
<span v-if="nugCounter" id="nugget-countdown">{{nugCounter}} Minutes remaining.</span>
<img class="upgraded-nugget" src="img/chicken-nugget/goldenNugget_static.png">
<!-- <div id="nugget-timer" class="nugget-timer--wrapper">
<div class="timer-background"></div>
<div class="timer spinner"></div>
<div class="timer filler"></div>
<div class="mask"></div>
</div> -->
</div>
</div>
<div class="chicken-panel--no-upgraded" v-show="!doUpgraded">
<img src="img/chicken-nugget/starburst.png" @click="onChickenClick" class="clickme starburst">
<img src="img/chicken-nugget/goldenNuggetGIFWIP.gif" @click="onChickenClick" class="clickme nugget-chick">
<div id="buyPassChickenSpeech">
<img src="img/speechtail.png" class="buyPassChickenSpeechTail">
<span v-html="loc.chicken_cta"></span>
</div>
</div>
</div>
</script>
<script>
var comp_chicken_panel = {
template: '#chicken-panel-template',
props: ['local', 'doUpgraded'],
data: function () {
return vueData;
},
methods: {
onChickenClick: function () {
BAWK.play('ui_chicken');
vueApp.showGoldChickenPopup();
ga('send', 'event', this.googleAnalytics.cat.purchases, 'Golden Chicken Click');
},
},
};
</script><script id="footer-links-panel-template" type="text/x-template">
<footer class="main-footer display-grid grid-column-1-2">
<div class="social-icons">
<social-panel id="social_panel"></social-panel>
</div>
<nav class="footer-nav text-left">
<a @click="onChangelogClicked" class="clickme">{{ version }}</a> |
<!-- <a href="https://shell-shockers.myshopify.com/collections/all" target="_blank" @click="BAWK.play('ui_click')">{{ loc.footer_merchandise }}</a> | -->
<a href="https://www.bluewizard.com/privacypolicy" target="_blank" @click="playSound">{{ loc.footer_privacypolicy }}</a> |
<a href="https://bluewizard.com/terms/" target="_blank" @click="playSound">{{ loc.footer_termsofservice }}</a> |
<button class="ss_button_as_text" @click="onHelpClick">{{ loc['account_title_faq'] }}</button> |
<a href="https://www.bluewizard.com" target="_blank" @click="playSound">© 2022 <img class="main-footer--logo-blue-wiz-mini" src="img/blue-wizard-logo-tiny-min.png" :alt="loc.footer_bluewizard + ' logo'"><span class="hideme">{{ loc.footer_bluewizard }}</span></a>
</nav>
</footer>
</script>
<script id="social-panel-template" type="text/x-template">
<div class="social_icons roundme_sm">
<a href="http://eepurl.com/dFPPwb" target="_blank" class="f_col f_center ss_marginright bg_blue4" @click="playSound('newYolker')">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Get the Shell Shocker's Newsletter: The New Yolker</span>
<i aria-hidden="true" class="text_blue1 fas fa-envelope-open-text"></i>
</div>
</a>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Facebook" reward="Facebook" url="https://www.facebook.com/bluewizarddigital" img="footer-social-media-bubble-facebook.png" icon="fa-facebook" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Twitter" reward="Twitter" url="https://twitter.com/bluewizardgames" img="footer-social-media-bubble-twitter.png" icon="fa-twitter" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Instagram" reward="Instagram" url="https://www.instagram.com/bluewizardgames/" img="footer-social-media-bubble-instagram.png" icon="fa-instagram" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="TikTok" reward="tiktok" url="https://www.tiktok.com/@bluewizarddigital" img="footer-social-media-bubble-tiktok.png" icon="fa-tiktok" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Discord" reward="discord" url="https://discord.gg/bluewizard" img="footer-social-media-bubble-discord.png" icon="fa-discord" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Steam" reward="Steam" url="https://store.steampowered.com/publisher/bluewizard" img="footer-social-media-bubble-steam.png" icon="fa-steam-symbol" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Twitch" reward="Twitch" url="https://www.twitch.tv/bluewizarddigital" img="footer-social-media-bubble-twitch.png" icon="fa-twitch" :isActive="true"></social-promo>
</div>
</script>
<script id="social-promo-template" type="text/x-template">
<div>
<div v-if="isActive" class="tool-tip" :class="{'active' : isBubbleActive}">
<a :href="url" target="_blank" :title="urlTitle" class="f_col f_center ss_marginright bg_blue4" @click="onClickReward()">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Vist Shell Shocker's {{ name }} page</span>
<i aria-hidden="true" class="text_blue1 fab" :class="icon"></i>
</div>
</a>
<div class="tool-tip--bubble" v-if="!itemRedeemed && bubbleHover">
<div class="tool-tip--group display-grid grid-column-1-2">
<div class="tool-tip--image box_relative">
<img class="discord-bubble-img box_absolute" :src="imgSrc" :alt="imgAlt">
</div>
<div class="tool-tip--text text-left">
<strong><i>Follow us<br /> on {{name}}</i></strong> <br /> for a free Hat!
</div>
</div>
<!-- .tool-tip--group -->
</div>
<!-- .tool-tip--bubble -->
</div>
<!-- .tool-tip -->
<a v-if="!isActive" :href="url" target="_blank" class="f_col f_center ss_marginright bg_blue4" @click="onClickReward()">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Vist Shell Shocker's {{ name }} page</span>
<i aria-hidden="true" class="text_blue1 fab" :class="icon"></i>
</div>
</a>
</div>
</script>
<script>
var COMPSOCIALPROMO = {
template: '#social-promo-template',
props: ['name', 'reward', 'url', 'img', 'icon', 'isActive'],
data: function () {
return {
isBubbleActive: true,
bubbleRepeat : '',
bubbleHover: true,
}
},
created() {
this.discordBubbleTimer();
},
methods: {
playSound (label) {
BAWK.play('ui_click');
this.gaSend(label);
},
discordBubbleTimer() {
if (this.itemRedeemed) {
this.isBubbleActive = false;
this.bubbleHover = false;
return;
}
this.bubbleRepeat = setInterval(() => {
this.isBubbleActive = this.isBubbleActive ? false : true;
}, 3000);
},
onClickReward() {
this.gaSend(this.reward);
console.log('onClickReward', this.reward);
const rewardGiven = localStore.getItem(`${this.reward}Rewarded`);
if (!hasValue(rewardGiven)) {
extern.socialReward(this.reward);
}
this.playSound();
this.isBubbleActive = false;
this.bubbleHover = false;
if (this.bubbleRepeat) {
clearInterval(this.bubbleRepeat);
}
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'social-buttons', 'click', label);
}
},
computed: {
itemRedeemed() {
return localStore.getItem(this.reward + 'Rewarded');
},
urlTitle() {
return `Blue Wizard ${this.name} page`;
},
imgAlt() {
return `Join Blue Wizard's ${this.name} page`;
},
imgSrc() {
return `img/social-media/${this.img}`;
}
}
};
</script><script>
var comp_social_panel = {
template: '#social-panel-template',
components: {
'social-promo': COMPSOCIALPROMO
},
data: function () {
return {
isBubbleActive: true,
bubbleRepeat : '',
bubbleHover: true,
rewardName: 'Twitch'
}
},
created() {
this.discordBubbleTimer();
},
methods: {
playSound (label) {
BAWK.play('ui_click');
this.gaSend(label);
},
discordBubbleTimer() {
if (this.itemRedeemed) {
this.isBubbleActive = false;
this.bubbleHover = false;
return;
}
this.bubbleRepeat = setInterval(() => {
this.isBubbleActive = this.isBubbleActive ? false : true;
}, 3000);
},
onClickReward(type) {
this.gaSend(type);
console.log('onClickReward', type);
const rewardGiven = localStore.getItem(`${type}Rewarded`);
if (!hasValue(rewardGiven)) {
extern.socialReward(type);
}
this.playSound();
this.isBubbleActive = false;
this.bubbleHover = false;
if (this.bubbleRepeat) {
clearInterval(this.bubbleRepeat);
}
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'social-buttons', 'click', label);
}
},
computed: {
itemRedeemed() {
return localStore.getItem(this.rewardName + 'Rewarded');
},
}
};
</script>
<script>
var comp_footer_links_panel = {
template: '#footer-links-panel-template',
components: {
'social-panel': comp_social_panel,
},
props: ['loc'],
data: function () {
return {
version: version
}
},
methods: {
onChangelogClicked: function () {
vueApp.showChangelogPopup();
BAWK.play('ui_popupopen');
},
playSound() {
BAWK.play('ui_click');
},
onHelpClick() {
vueApp.showHelpPopup();
this.gaSend('openHelp');
BAWK.play('ui_popupopen');
}
}
};
</script>
<template id="comp-vip-cta">
<div class="vip-club-cta" v-on:click="onClicked">
<button v-if="!isSubscriber && !isUpgraded && showVip" class="vip-club-cta-pos ss_button btn_sm btn_pink bevel_pink">
{{ loc.ui_game_playeractions_join_vip }}
</button>
<h4 v-if="isUpgraded && isSubscriber && showVip" class="sub-name">
{{loc[subName]}}
</h4>
<img class="roundme_md" :class="{ 'egg-org-img' : isEggOrg }" :src="getImgSrc" :alt="getImgSrcAlt">
</div>
</template>
<script>
const compVipCta = {
template: '#comp-vip-cta',
props: ['loc', 'upgradeName', 'isUpgraded', 'isSubscriber', 'hasMobileReward', 'isBlackFryday', 'isEggOrg', 'isTwitchEvent'],
data() {
return {
subName: '',
hasPlayedKotc: null,
kotcImgSrc: 'img/kotc/new-game-mode-king-of-coop.png',
vipImgSrc: 'img/vip-club/vip-club-call-to-action.png',
mobileImgSrc: 'img/mobile/shell-mobile-cta-min.png',
blackFrydayImgSrc: 'img/store-black-friday/black-fryday-home-screen-ad.png',
helpUkraine: 'img/stand-with-ukraine-min.png',
eggOrg: 'img/egg-org/eggOrg_timeTravel_houseAd2-min.jpg',
twitchSrc: 'img/twitch-drops/TwitchDrops2022-HouseAd_536x307-min.jpg'
};
},
mounted() {
this.hasPlayedKotc = localStore.getItem('hasPlayedKotc');
},
methods: {
onClicked() {
if (this.isEggOrg) {
vueApp.showSelectedTaggedItemsOnEquipScreen('EGGORG');
ga('send', 'event', 'home-display-ad', 'click', 'egg-org');
return;
}
// above all else show sale
if (this.isBlackFryday) {
vueApp.showEggStorePopup();
ga('send', 'event', 'home-display-ad', 'click', 'black-fryday');
return;
}
// promote KOTC
if (this.hasPlayedKotc) {
ga('send', 'event', 'home-display-ad', 'click', 'item_hat_ukraine');
// ga('send', 'event', 'home-display-ad', 'click', 'kotc-popup');
// vueApp.showKotcInstrucPopup();
vueApp.showPopupEggStoreSingle('item_hat_ukraine');
// localStore.setItem('hasPlayedKotc', true);
return;
}
if (this.isTwitchEvent) {
ga('send', 'event', 'home-display-ad', 'click', 'twitch-drops');
open('https://shellshock.io/twitch/?utm_medium=referral&utm_campaign=featureslot', '_blank');
}
// if has mobile item
if (this.hasMobileReward) {
let vipType = 'vip-ad';
if (this.isUpgraded && this.sSubscriber) {
let vipType = 'vip-manage';
}
ga('send', 'event', 'home-display-ad', 'click', vipType);
vueApp.showSubStorePopup();
return;
} else {
ga('send', 'event', 'home-display-ad', 'click', 'mobile-ad');
vueApp.showGetMobilePopup();
}
},
test() {
this.isBlackFryday = false;
this.hasPlayedKotc = true;
this.hasMobileReward = true;
}
},
computed: {
getImgSrc() {
if (this.isEggOrg) {
return this.eggOrg;
}
if (this.isBlackFryday) {
return this.blackFrydayImgSrc;
}
if (this.hasPlayedKotc) {
return this.kotcImgSrc;
}
if (this.hasMobileReward) {
return this.vipImgSrc;
} else {
return this.mobileImgSrc;
}
if (this.isTwitchEvent) {
return twitchSrc;
}
},
getImgSrcAlt() {
if (this.isEggOrg) {
return 'EggOrg is back!';
}
if (this.isBlackFryday) {
return 'BLACK FRYDAY SALE!';
}
if (this.hasPlayedKotc) {
return 'Click to learn how to play King of the Coop!;';
}
if (this.hasMobileReward) {
return 'Manage VIP';
} else {
return 'Download mobile today!';
}
if (this.isTwitchEvent) {
return 'Get your drops today!';
}
},
showVip() {
return false;
if (!this.hasPlayedKotc || !this.hasMobileReward || this.isBlackFryday) {
return false;
} else {
return true;
}
},
},
watch: {
upgradeName(val) {
if (!hasValue(val)) {
return;
}
this.subName = `s-${val.replace(' ', '-').toLowerCase().replace(' ', '-')}-title`;
}
}
};
</script><script id="media-tabs-template" type="text/x-template">
<div class="media-tabs-container">
<div id="horizontalTabs" class="media-tab-container">
<button id="news-tab" @click="selectTab" class="media-tab ss_smtab ss_marginright" :class="(showNewsTab ? 'selected' : '')"><i class="fas fa-bullhorn"></i></button>
<button id="twitch-tab" @click="selectTab" class="media-tab ss_smtab ss_marginright" :class="(showTwitchTab ? 'selected' : '')"><i class="fab fa-twitch"></i></button>
<button id="video-tab" v-if="youtubeStreams.length > 0" @click="selectTab" class="media-tab ss_smtab" :class="(showVideoTab ? 'selected' : '')"><i class="fab fa-youtube"></i></button>
</div>
<div class="front_panel media-tabs-content roundme_sm f_col" :class="{'tab-news-active' : showNewsTab}">
<div id="news-tab" v-show="showNewsTab">
<h3 class="nospace shadow_blue4 text_white">{{ loc.home_latestnews }}</h3>
<div class="news-container f_row ss_margintop">
<div class="news_mask"></div>
<newsfeed-panel id="news_scroll" class="home-tab-scroll" ref="newsScroll" :items="newsfeedItems"></newsfeed-panel>
</div>
</div>
<!-- #news-tab -->
<div id="twitch-tab" v-show="showTwitchTab">
<h3 class="nospace shadow_blue4 text_white">
Twitch <button id="tab-twitch-btn" @click="onApplyNowClick" class="ss_button btn_md btn_yolk btn-media bevel_yolk">{{loc.home_media_apply_now}}</button>
</h3>
<div class="f_row ss_margintop">
<streamer-panel id="twitch_panel" :loc="loc" :streams="twitchStreams" :title="loc.twitch_title" :viewers="loc.twitch_viewers" icon="ico_twitch"></streamer-panel>
</div>
</div>
<!-- #twitch-tab -->
<div id="video-tab" v-show="showVideoTab">
<h3 class="nospace shadow_blue4 text_white">
YouTube <button id="tab-youtube-btn" @click="onApplyNowClick" class="ss_button btn_md btn_yolk btn-media bevel_yolk">{{loc.home_media_apply_now}}</button>
</h3>
<div class="news-container f_row ss_margintop">
<div class="news_mask"></div>
<div id="yTube-scroll" class="home-tab-scroll v_scroll">
<div v-for="item in youtubeStreams" :key="item.id" v-if="item.active" @click="onVideoClick(item)" class="news_item ytube-item roundme_md clickme">
<div class="image-wrap news_img roundme_sm">
<img :src="item.externalImg" alt="" class="news_img roundme_sm" />
</div>
<div class="content-wrap f_col f_space_between">
<p><strong>{{ item.title }}</strong></p>
<p v-if="item.desc">{{ item.desc }}</p>
<p class="text-right">{{ item.author }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- .media-tabs-content -->
</div>
<!-- .media-tabs-container -->
</script>
<script id="streamer-panel-template" type="text/x-template">
<div class="panel_streamer noscroll">
<div v-if="show" id="stream_mask"></div>
<div id="stream_scroll" class="home-tab-scroll v_scroll" v-show="show">
<div class="stream_item roundme_sm clickme" v-for="s in streams">
<a :href="s.link" target="_blank" @click="BAWK.play('ui_click')" class="display-grid grid-column-1-2">
<img :src="s.image" class="stream_img roundme_sm">
<span>
<p class="stream_name">{{ s.name }}</p>
<p class="stream_viewers">{{ s.viewers }} {{ viewers }}</p>
</span>
</a>
</div>
</div>
<div class="no-stream roundme_sm" v-if="!show">
<p v-html="loc.twitch_no_steam"></p>
</div>
</div>
</script>
<script>
var comp_streamer_panel = {
template: '#streamer-panel-template',
props: ['streams', 'title', 'viewers', 'icon', 'loc'],
methods: {
playSound (sound) {
BAWK.play(sound);
}
},
computed: {
show: function() {
if (!this.streams) {
return false;
}
return this.streams.length > 0;
}
}
};
</script>
<script>
const MEDIATABS = {
template: '#media-tabs-template',
components: {
'newsfeed-panel': comp_newsfeed_panel,
'streamer-panel': comp_streamer_panel,
},
props: ['loc', 'newsfeedItems', 'twitchStreams', 'youtubeStreams'],
created() {
this.$nextTick(() => {
this.randomTabSelect();
});
},
mounted() {
// VUE!!!!!!!!!!!
setTimeout(() => this.getAllTabs(), 500);
},
data: function () {
return {
mediaTabs: [],
mediaTabsCount: 0,
rotateTimeout: '',
showNewsTab: false,
showTwitchTab: false,
showVideoTab: false,
currentTab: ''
}
},
methods: {
getAllTabs() {
this.$nextTick(() => {
let ids = [],
tabs = Array.from(document.querySelectorAll('.media-tab')).forEach(tab => ids.push(tab.id));
this.mediaTabs = ids;
this.mediaTabsCount = this.mediaTabs.length - 1;
this.autoRotateTabs();
});
},
selectTab: function (e) {
ga('send', 'event', 'media-tabs', 'click', e.currentTarget.id);
return this.switchTab(e.currentTarget.id, true, true)
},
autoRotateTabs() {
let nextIdx = this.mediaTabs.indexOf(this.currentTab) + 1;
if (nextIdx > this.mediaTabsCount) nextIdx = 0;
this.rotateTimeout = setTimeout(() => {
this.switchTab(this.mediaTabs[nextIdx], false, false);
this.autoRotateTabs();
}, 10000);
},
randomTabSelect() {
let n = Math.floor(Math.random() * 9);
if (n >= 0 && n <= 2) {
this.showNewsTab = true;
this.currentTab = 'news-tab';
} else if (n >= 3 && n <= 5) {
this.showTwitchTab = true;
this.currentTab = 'twitch-tab';
} else {
this.showVideoTab = true;
this.currentTab = 'video-tab';
}
},
onVideoClick(item) {
ga('send', 'creator', 'videoClick', item.title);
window.open(item.link, '_window');
},
onApplyNowClick(e) {
ga('send', 'creator', 'applyNow', e.target.id);
window.open('https://shellcreators.bluewizard.com', '_window');
},
switchTab(tab, sound, click) {
this.showNewsTab = false;
this.showTwitchTab = false;
this.showVideoTab = false;
switch (tab) {
case 'news-tab':
this.currentTab = 'news-tab';
this.showNewsTab = true;
break;
case 'twitch-tab':
this.currentTab = 'twitch-tab';
this.showTwitchTab = true;
break;
case 'video-tab':
this.currentTab = 'video-tab';
this.showVideoTab = true;
break;
}
if (sound) {
BAWK.play('ui_toggletab');
}
if (click) {
ga('send', 'creator', 'tabClick', this.currentTab);
this.cancelRotate(false);
}
},
cancelRotate(stop) {
clearTimeout(this.rotateTimeout);
this.rotateTimeout = '';
if (!stop) {
this.autoRotateTabs();
}
}
}
};
</script><template id="music-widget">
<div v-if="isMusic" class="music-widget roundme_md" :class="[!show ? hideClass : '']">
<div v-if="theAudio" class="music-widget--wrapper flex flex-nowrap">
<figure class="music-widget--content">
<header class=" roundme_md">
<h3 class="music-widget--now-playing">{{ loc.musicwidget_now_playing }}</h3>
</header>
<figcaption class="music-widget--content-wrapper">
<h4 class="music-widget--album-title">{{ serverTracks.artist }}</h4>
</figcaption>
<figcaption class="music-widget--content-wrapper">
<p v-if="serverTracks.url" class="music-widget--song-title"><a @click="gaSendEvent('click-track', getTitleAlbum)" :href="serverTracks.url" :title="theTitleAttr" target="_blank">{{ getTitleAlbum }}</a></p>
<p v-else class="music-widget--song-title">{{ getTitleAlbum }}</p>
</figcaption>
<div v-if="volumeSlider" v-for="t in settingsUi.adjusters.music" class="music-widget--volume-control nowrap">
<slider-component :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="volumeControl"></slider-component>
</div>
</figure>
<div class="music-widget--cover-image music-widget--cover-controls roundme_md">
<template v-if="serverTracks.url">
<a v-if="serverTracks.albumArt" @click="gaSendEvent('click-albumArt', getTitleAlbum)" :href="serverTracks.url" :title="theTitleAttr" class="ss-absolute" target="_blank"><img :src="serverTracks.albumArt" class="roundme_md ss-absolute" :alt="serverTracks.album" /></a>
</template>
<template v-else>
<img v-if="serverTracks.albumArt" :src="serverTracks.albumArt" class="ss-absolute roundme_md" alt="Album cover art for" :alt="serverTracks.album" />
</template>
<button v-if="playBtn" @click="playAudio">
<i v-if="playing" class="music-widget--cover-control-icon music-widget--cover-control-pause far fa-pause-circle fa-2x"></i>
<i v-if="!playing" class="music-widget--cover-control-icon music-widget--cover-control-pause far fa-play-circle fa-2x"></i>
</button>
</div>
<div class="music-widget--sponsor">
<a @click="gaSendEvent('click-sponsor', sponsor.name)" v-if="sponsor" :href="sponsor.link" :title="getSponsorTitleAttr" target="_blank"><img :src="getSponsorImg" class="music-widget--sponsor-icon" :alt="sponsor.name" /><span class="hideme">{{sponsor.name}}</span></a>
<button v-if="settings" @click="openSettings" class="music-widget--sponsor--settings-btn"><i class="fas fa-cog"></i><span class="hideme">Music Settings</span></button>
<button class="music-widget--sponsor--settings-btn" @click="toggleMusic"><i class="fas" aria-hidden="true" :class="togglePlayStopIcon"></i><span class="hideme">Music</span></button>
</div>
</div>
</div>
</template>
<script>
const createMusicWidget = templateId => {
return {
template: '#music-widget',
props: ['loc','volumeSlider', 'playBtn', 'settings', 'settingsUi', 'show'],
components: {
'slider-component': comp_settings_adjuster
},
data () {
return vueData.music;
},
mounted () {
this.theAudio = document.getElementById('theAudio');
},
methods: {
loadVolume() {
this.$nextTick(() => {
this.theAudio.volume = Number(this.settingsUi.adjusters.music[0].value);
});
},
getAudioServer() {
if (parsedUrl.dom == 'localhost' || parsedUrl.dom == 'dev' || parsedUrl.dom == 'localshelldev') {
var url = 'uswest2-music.shellshock.io';
}
else {
var server = vueApp.serverList.filter(server => server.locKey === vueApp.currentServerLocKey)[0];
var url = server.subdom.slice(0, -1) + '-music.' + parsedUrl.dom + '.' + parsedUrl.top;
}
this.musicSrc = 'https://' + url + '/shellshock.ogg';
},
setIndex(k) {
this.$nextTick(() => {
this.play();
})
this.currIndex = k;
},
play() {
if (!this.isMusic) return;
this.getAudioServer();
},
playMusic() {
// var audio = this.theAudio;
this.theAudio.src = this.musicSrc;
console.log('Play Music');
clearInterval(this.timer);
this.theAudio.play()
.then( // Returns a Promise
() => { // Success
this.playing = true;
this.loadVolume();
this.duration = this.theAudio.duration;
this.theAudio.addEventListener('stalled', () => this.isMusic = false);
},
() => { // Fail
// What to do... just try again after a few seconds, I guess?
setTimeout(() => this.play(), 2000);
}
);
},
pause() {
this.playing = false;
this.theAudio.pause();
clearInterval(this.timer);
},
/*
next() {
if (this.currIndex < this.tracks.length - 1) {
this.currIndex++;
} else {
this.currIndex = 0;
}
},
prev() {
if (this.currIndex > 0) {
this.currIndex--;
} else {
this.currIndex = this.tracks.length - 1;
}
},
*/
playOnce() {
if (this.playing) return;
return this.play();
},
playAudio() {
if (this.theAudio.paused) {
this.play();
} else {
this.pause();
}
},
openSettings() {
vueApp.showSettingsPopup();
vueApp.onSettingsPopupSwitchTabMisc();
this.gaSendEvent('click', 'widgetOpenSettings');
},
volumeControl(id, value) {
extern.setMusicVolume(value);
vueApp.onSettingsQuickSave();
},
hideMe() {
return this.$refs.id.classList.addClass('fade-out-3');
},
showMe() {
this.show = true;
setTimeout(() => this.show = false, 2000);
},
gaSendEvent(action, label) {
action = action || '';
label = label || '';
return ga('send', 'event', 'music', action, label);
},
toggleMusic() {
if (this.playing) {
this.theAudio.removeEventListener('stalled', () => this.isMusic = false);
this.playing = false;
this.pause();
this.musicSrc = '';
this.theAudio.removeAttribute('src');
extern.setMusicStatus(false);
this.gaSendEvent('toggleMusic', 'off');
return;
}
this.theAudio.src = '';
this.play();
extern.setMusicStatus(true);
this.gaSendEvent('toggleMusic', 'on');
},
changeVolume(val) {
this.theAudio.volume = val;
}
},
watch: {
'currIndex': {
handler() {
this.$nextTick(() => {
this.play();
})
}
},
serverTracks(val) {
let sponsor = this.sponsors.filter(sponsor => sponsor.id === val.sponsor);
this.sponsor = sponsor.length || sponsor.length > 0 ? sponsor[0] : '';
},
musicSrc(val) {
if (val) {
this.playMusic();
}
},
},
computed: {
theTitleAttr() {
return 'Read more about ' + this.serverTracks.title;
},
getTitleAlbum() {
return this.serverTracks.title + ' - ' + this.serverTracks.album;
},
getSponsorImg() {
if (!this.sponsor) {
return;
}
return 'data/img/sponsor/' + this.sponsor.id + this.sponsor.imageExt;
},
getSponsorTitleAttr() {
return 'See more about our sponsor ' + this.sponsor.name;
},
togglePlayStopIcon() {
return this.playing ? 'fa-stop-circle' : 'fa-play-circle';
},
},
};
};
// Register component globally
Vue.component('music-widget', createMusicWidget('#music-widget'));
</script>
<script>
var comp_home_screen = {
template: '#home-screen-template',
components: {
'stats-panel': comp_stats_panel,
'play-panel': comp_play_panel,
'weapon-select-panel': comp_weapon_select_panel,
'house-ad-big': comp_house_ad_big,
'house-ad-small': comp_house_ad_small,
'account-panel': comp_account_panel,
'chicken-panel': comp_chicken_panel,
'footer-links-panel': comp_footer_links_panel,
'event-panel': comp_events,
'vip-club-cta': compVipCta,
'media-tabs': MEDIATABS
// 'pwa-button': comp_pwa_btn,
},
data: function () {
return vueData;
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onEquipClicked: function () {
vueApp.switchToEquipUi();
BAWK.play('ui_equip');
},
showSignIn: function () {
extern.showSignInDialog();
vueApp.$refs.firebaseSignInPopup.show();
},
onSignInClicked: function () {
this.showSignIn();
},
onSignOutClicked: function () {
extern.signOut();
},
onResendEmailClicked: function () {
extern.sendFirebaseVerificationEmail();
vueApp.showGenericPopup('verify_email_sent', 'verify_email_instr', 'ok');
},
onBigHouseAdClosed: function () {
console.log('big house ad closed event received');
this.ui.houseAds.big = null;
this.urlParamSet = this.urlParams ? true : null;
// vueApp.showTitleScreenAd();
vueApp.shellShockUrlParamaterEvents();
},
onPlayerNameChanged: function (newName) {
console.log('play name event handler');
vueApp.setPlayerName(newName);
BAWK.play('ui_onchange');
},
onEggPlayClick() {
play: 'play game',
ga('send', 'event', vueData.googleAnalytics.cat.play, vueData.googleAnalytics.action.eggDollClick);
vueApp.$refs.homeScreen.$refs.playPanel.onPlayButtonClick();
},
api_incentivizedVideoRewardRequest() {
extern.api_incentivizedVideoRewardRequested();
},
onTwitchDropsClick() {
window.open(dynamicContentPrefix + 'twitch');
},
showNuggyPopup() {
vueApp.showChicknWinnerPopup();
},
playIncentivizedAd(e) {
if (!this.chicknWinnerReady || this.hasChwPlayClicked) {
e.preventDefault();
return;
}
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', 'click-home');
this.hasChwPlayClicked = true;
vueApp.loadNuggetVideo();
vueApp.chicknWinnerNotReady();
},
chwStopCycle() {
if (this.chwHomeTimer) {
clearInterval(this.chwHomeTimer);
this.chwHomeTimer = '';
this.chwHomeEl.classList.remove('.active');
}
},
chwShowCycle() {
this.chwHomeEl = document.querySelector('.chw-home-timer');
if (this.chwHomeEl) {
this.chwHomeTimer = setInterval(() => {
this.chwHomeEl.classList.toggle('active');
}, this.chwActiveTimer);
}
},
openUnblocked() {
if (crazyGamesActive) {
window.open('https://scrambled.world/unblocked');
}
else {
window.open("unblocked");
}
}
},
computed: {
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '');
},
twitchDropsBtnImgSrs() {
if (this.twitchLinked) {
return '../img/events/twitch-drops-btn-linked.png';
}
return '../img/events/twitch-drops-btn-link-now.png';
},
remainingMsg() {
if (this.isChicknWinnerError) {
return this.loc.chw_error_text;
}
if (this.chicknWinnerDailyLimitReached && this.chicknWinnerCounter > 0) {
return this.loc.chw_daily_limit_msg;
}
if (this.chicknWinnerReady) {
if (this.chicknWinnerCounter === 0) {
return this.loc.chw_ready_msg;
} else {
return this.loc.chw_cooldown_msg;
}
} else {
return this.loc.chw_time_until;
}
},
progressBarWrapClass() {
if (this.chicknWinnerReady) {
return 'chw-progress-bar-wrap-complete';
}
},
playAdText() {
if (this.chicknWinnerReady && this.chicknWinnerCounter === 0) {
return this.loc.chw_btn_free_reward;
} else {
return this.loc.chw_btn_free_reward;
}
},
chwClass() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'grid-column-1-eq';
} else {
if (this.chicknWinnerReady) {
return 'grid-column-1-eq';
} else {
return 'grid-column-1-2';
}
}
},
chwHomeTimerCls() {
//{'chw-home-screen-max-watched': chicknWinnerDailyLimitReached}
if (this.chicknWinnerDailyLimitReached) {
return 'chw-home-screen-max-watched';
} else {
if (this.chicknWinnerReady) {
return 'is-ready active';
} else {
return 'not-ready';
}
}
},
chwChickSrc() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'img/chicken-nugget/chickLoop_daily_limit.svg';
} else {
if (!this.chicknWinnerReady) {
return 'img/chicken-nugget/chickLoop_sleep.svg';
} else {
return 'img/chicken-nugget/chickLoop_speak.svg';
}
}
},
chwShowTimer() {
if (this.chicknWinnerDailyLimitReached) {
// this.chwStopCycle();
return false;
} else {
if (this.chicknWinnerReady) {
this.chwShowCycle();
return false;
} else {
// this.chwStopCycle();
return true;
}
}
},
isTwitchLinked() {
if (this.twitchLinked) return '<i class="fas fa-check-circle text_twitch_yellow"></i>';
return '<i class="fas fa-times-circle text_grey"></i>';
}
}
};
</script><script id="equip-screen-template" type="text/x-template">
<div id="#equip_wrapper">
<div id="mainHead">
<account-panel id="account_panel" ref="accountPanelEquip" :loc="loc" :eggs="eggs" :show-corner-buttons="ui.showCornerButtons" :ui="ui" :show-bottom="false" :is-anonymous="isAnonymous" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" :currentLangOptions="locLanguage" :is-twitch="twitchLinked"></account-panel>
</div>
<div id="equip_box" class="main-content">
<section id="equip_panel_left" class="equip_panel left_panel">
<!--<div class="equip_panelhead">
</div>-->
<div id="equip_sidebox" class="roundme_md">
<equipped-slots id="equip.equipped_slots" ref="equip.equipped_slots" :loc="loc" :primary-item="equip.equippedPrimary" :secondary-item="equip.equippedSecondary" :hat-item="equip.equippedHat" :stamp-item="equip.equippedStamp" :grenade-item="equip.equippedGrenade" @equipped-type-selected="onEquippedTypeSelected"></equipped-slots>
<color-select id="equip.equipped_slots" ref="colorSelect" :loc="loc" :is-upgrade="isUpgraded" :color-idx="equip.colorIdx" :extra-colors-locked="equip.extraColorsLocked" @color-changed="onColorChanged"></color-select>
</div>
<p align="center"><button @click="onRedeemClick" class="ss_button btn_blue1 btn_md bevel_blue">{{ loc.eq_redeem }}</button></p>
</section>
<!-- end.left_panel -->
<section id="equip_panel_middle" class="equip_panel middle_panel">
<div class="equip_panelhead panel_tabs">
<button class="ss_bigtab bevel_blue ss_marginright" :class="getButtonToggleClass(equip.equipModes.inventory)" @click="switchToInventory">{{ loc.eq_inventory }}</button>
<button class="ss_bigtab bevel_blue" :disabled="!accountSettled" :class="getButtonToggleClass(equip.equipModes.shop)" @click="switchToShop">{{ loc.eq_shop }}</i></button>
</div>
<item-type-selector id="item_type_selector" ref="item_type_selector" :selected-item-type="equip.selectedItemType" :show-special-items="equip.showSpecialItems" :in-shop="isInShop" @item-type-changed="onItemTypeChanged" @tagged-items-clicked="onTaggedItemsClicked" @premium-items-clicked="onPremiumItemsClicked"></item-type-selector>
<div id="equip_purchase_top" class="equip_purchase_top">
<price-tag id="price_tag" class="ss_marginright" v-if="equip.buyingItem" ref="price_tag" :loc="loc" :item="equip.buyingItem" @buy-item-clicked="onBuyItemClicked"></price-tag>
<physical-tag id="physical-tag" class="ss_marginright" v-if="equip.physicalUnlockPopup.item" ref="physical-tag" :loc="loc" :item="equip.physicalUnlockPopup.item" @buy-item-clicked="onBuyItemClicked"></physical-tag>
</div>
<div id="equip_weapon_panel">
<weapon-select-panel id="weapon_select" ref="weapon_select":current-class="classIdx" :loc="loc" @changed-class="onChangedClass"></weapon-select-panel>
<button class="ss_button btn_md btn_red bevel_red" @click="onBackClick"><i class="fas fa-backward"></i> {{ loc.back }}</button>
</div>
</section>
<!-- end .middle_panel -->
<section id="equip_panel_right" class="equip_panel right_panel">
<div id="equip_sidebox" class="roundme_md">
<item-grid id="item_grid" ref="item_grid" :loc="loc" :grid-class="getGridClass" :items="equip.showingItems" :selectedItem="equip.selectedItem" :category-loc-key="equip.categoryLocKey" :in-shop="isInShop" @item-selected="onItemSelected" @switch-to-shop="onSwitchToShopClicked"></item-grid>
<!--<house-ad-small id="banner-ad" v-show="!isInShop"></house-ad-small>-->
</div>
</section>
<!-- .right_panel-->
</div>
<!-- Popup: Buy Item -->
<small-popup id="buyItemPopup" ref="buyItemPopup" @popup-confirm="onBuyItemConfirm">
<template slot="header">{{ loc.p_buy_item_title }}</template>
<template slot="content">
<div>
<canvas id="buyItemCanvas" ref="buyItemCanvas" width="250" height="250"></canvas>
</div>
<div class="f_row f_center">
<img v-if="!isBuyingItemPrem" src="img/ico_goldenEgg.png" class="egg_icon"/>
<i v-else class="fas fa-dollar-sign"></i>
<h1>{{ (equip.buyingItem) ? equip.buyingItem.price : '' }}</h1>
</div>
</template>
<template slot="cancel">{{ loc.p_buy_item_cancel }}</template>
<template slot="confirm">{{ loc.p_buy_item_confirm }}</template>
</small-popup>
<!-- Popup: Redeem Code -->
<small-popup id="redeemCodePopup" ref="redeemCodePopup" :popup-model="equip.redeemCodePopup" @popup-confirm="onRedeemCodeConfirm">
<template slot="header">{{ loc.p_redeem_code_title }}</template>
<template slot="content">
<div class="error_text shadow_red" v-show="equip.redeemCodePopup.showInvalidCodeMsg">{{ loc.p_redeem_code_no_code }}</div>
<p><input type="text" class="ss_field ss_margintop ss_marginbottom text-center width_lg" v-model="equip.redeemCodePopup.code" v-bind:placeholder="loc.p_redeem_code_enter"></p>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
<!-- Popup: Physical Unlock -->
<small-popup id="physicalUnlockPopup" ref="physicalUnlockPopup" :popup-model="equip.physicalUnlockPopup" @popup-confirm="onPhysicalUnlockConfirm">
<template slot="header">{{ loc.p_physical_unlock_title }}</template>
<template slot="content">
<div v-if="(equip.physicalUnlockPopup.item !== null)">
<div>
<item :item="equip.physicalUnlockPopup.item" :isSelected="false" :show-item-only="true"></item>
<div class="f_row f_center">
<img src="img/ico_goldenEgg.png" class="egg_icon"/>
<h1>{{ loc.p_buy_special_price }}</h1>
</div>
</div>
<div class="popup_sm__item_desc">
{{ loc[equip.physicalUnlockPopup.item.item_data.physicalUnlockLocKey] }}
</div>
</div>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
</div>
</script>
<script id="equipped-slots-template" type="text/x-template">
<div>
<h3 class="margins_sm">{{ loc.eq_equipped }}</h3>
<div id="equip_equippedslots">
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Primary)">
<item id="primary_item" ref="primary_item" v-if="primaryItem" :item="primaryItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!primaryItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_weaponPrimary.svg" alt="Primary equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Secondary)">
<item id="secondary_item" ref="secondary_item" v-if="secondaryItem" :item="secondaryItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!secondaryItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_weaponSecondary.svg" alt="Secondary equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Grenade)">
<item id="grenade_item" ref="grenade_item" v-if="grenadeItem" :item="grenadeItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!grenadeItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_grenade.svg" alt="Grenade equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Hat)">
<item id="hat_item" ref="hat_item" v-if="hatItem" :item="hatItem" :equippedSlot="true"></item>
<div v-if="!hatItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_hat.svg" alt="Hat item slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Stamp)">
<item id="stamp_item" ref="stamp_item" v-if="stampItem" :item="stampItem" :equippedSlot="true"></item>
<div v-if="!stampItem" class="equip_icon equip_icon_stamp equip_icon_no_item"><img src="img/inventory-icons/ico_stamp.svg" alt="Stamp item slot"></div>
</div>
</div>
</div>
</script>
<script>
var comp_equipped_slots = {
template: '#equipped-slots-template',
components: { 'item': comp_item },
props: ['loc', 'primaryItem', 'secondaryItem', 'hatItem', 'stampItem', 'grenadeItem'],
data: function () {
return {
itemType: ItemType
}
},
methods: {
onClick: function (itemType) {
this.$emit('equipped-type-selected', itemType);
}
},
computed: {
emptyHatClass: function () {
return (this.hatItem === null) ? 'equip_icon_hat' : '';
},
emptyStampClass: function () {
return (this.stampItem === null) ? 'equip_icon_stamp' : '';
}
}
};
</script><script id="color-select-template" type="text/x-template">
<div>
<h3 class="margins_sm">{{ loc.eq_color }}</h3>
<div id="equip_free_colors" class="text-center">
<svg v-for="(c, index) in freeColors" class="eggIcon equip_color" :style="{ color: c }" :class="isSelectedClass(index)" @click="onClick(index)"><use xlink:href="#icon-egg"></use></svg>
</div>
<div id="equip_paid_colors" class="text-center ss_marginbottom_lg">
<svg v-for="(c, index) in paidColors" class="eggIcon equip_color" :style="{ color: c }" :class="isSelectedClass(index + freeColors.length)" @click="onClick(index + freeColors.length)"><use :xlink:href="getExtraColorEggIcon"></use></svg>
</div>
</div>
</script>
<script>
var comp_color_select = {
template: '#color-select-template',
props: ['loc', 'colorIdx', 'extraColorsLocked', 'isUpgrade'],
data: function () {
return {
freeColors: freeColors,
paidColors: paidColors
}
},
methods: {
isSelectedClass: function (idx) {
return (idx === this.colorIdx) ? 'selected' : ''
},
onClick: function (idx) {
if (idx >= freeColors.length && this.extraColorsLocked === true) {
vueApp.showSubStorePopup();
// BAWK.play('ui_chicken');
return;
}
this.$emit('color-changed', idx);
},
},
computed: {
getExtraColorEggIcon() {
return (this.extraColorsLocked === true && !this.isUpgrade) ? '#icon-egg-locked' : '#icon-egg';
},
}
};
</script><script id="item-timer-template" type="text/x-template">
<div>
<div id="equip_timerem" class="box_blue3 roundme_sm shadow_blue4">
<i class="fas fa-hourglass-start"></i> 9{{ loc.eq_day }}<span class="blink">:</span>12{{ loc.eq_hour }}
<br>{{ loc.eq_remaining }}
</div>
</div>
</script>
<script>
var comp_item_timer = {
template: '#item-timer-template',
props: ['loc']
};
</script><script id="price-tag-template" type="text/x-template">
<div id="equip_purchase_items" v-if="isNoPrice" class="equip_purchase_items">
<div id="equip_pricetag" class="equip_pricetag shadow_blue2">
<img src="img/pricetag_left.png" class="equip_pricetag__endpiece">
<div class="equip_pricetag__tag equip_pricetag__is_buy_tag">
<img v-if="!isPremium" src="img/ico_goldenEgg.png">
<i v-else class="fas fa-dollar-sign"></i>
{{ item.price }}
</div>
<img src="img/pricetag_right.png" class="equip_pricetag__endpiece">
</div>
<button style="pointer-events: all" class="ss_button btn_yolk bevel_yolk is_purchase_btn" @click="onBuyClick">{{ loc.eq_buy }}</button>
</div>
</script>
<script>
var comp_price_tag = {
template: '#price-tag-template',
props: ['loc', 'item'],
methods: {
onBuyClick: function () {
if (this.isPremium) {
return vueApp.showPopupEggStoreSingle(this.item.sku);
}
this.$emit('buy-item-clicked', this.item);
}
},
computed: {
isPremium() {
return this.item.unlock === 'premium';
},
isNoPrice() {
return this.item.price < 1000000000;
}
}
};
</script><script id="physical-tag-template" type="text/x-template">
<div id="equip_get_physical_item" class="equip_purchase_items">
<div id="equip_pricetag" class="equip_pricetag shadow_blue2">
<img src="img/pricetag_left.png">
<div class="equip_pricetag__tag equip_pricetag__is_special_tag">
<img src="img/ico_goldenEgg.png" class="ss_marginright">{{ loc.p_buy_special_price }}
</div>
<img src="img/pricetag_right.png">
</div>
<button class="ss_button btn_yolk bevel_yolk is_special_get_btn" @click="onBuyClick">{{ loc.p_chicken_goldbutton }}</button>
</div>
</script>
<script>
var comp_physical_tag = {
template: '#physical-tag-template',
props: ['loc', 'item'],
methods: {
onBuyClick: function () {
this.$emit('buy-item-clicked', this.item);
}
}
};
</script><script id="item-type-selector-template" type="text/x-template">
<div>
<div id="equip_itemtype" class="equip_panelhead">
<img src="img/inventory-icons/ico_weaponPrimary.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Primary)" @click="onItemTypeClick(itemType.Primary)">
<img src="img/inventory-icons/ico_weaponSecondary.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Secondary)" @click="onItemTypeClick(itemType.Secondary)">
<img src="img/inventory-icons/ico_grenade.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Grenade)" @click="onItemTypeClick(itemType.Grenade)">
<img src="img/inventory-icons/ico_hat.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Hat)" @click="onItemTypeClick(itemType.Hat)">
<img src="img/inventory-icons/ico_stamp.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Stamp)" @click="onItemTypeClick(itemType.Stamp)">
<i class="ico_itemtype premium-item-type clickme roundme_lg fas fa-gem" :class="getSelectedClass('premium')" @click="onPremiumTypeClick"></i>
<img src="img/inventory-icons/ico_specialItem.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass('tagged')" @click="onTaggedTypeClick">
</div>
</div>
</script>
<script>
var comp_item_type_selector = {
template: '#item-type-selector-template',
props: ['showSpecialItems', 'selectedItemType', 'inShop'],
data: function () {
return {
itemType: ItemType,
showingTagged: false
}
},
methods: {
onItemTypeClick: function (itemType) {
this.$emit('item-type-changed', itemType);
},
onTaggedTypeClick: function (e) {
if (!this.showSpecialItems) {
return;
}
this.$emit('tagged-items-clicked');
},
onPremiumTypeClick() {
this.$emit('premium-items-clicked');
},
getSelectedClass: function (itemType) {
let noTags = itemType === 'tagged' && !this.showSpecialItems ? 'no-tags' : '';
return (itemType === this.selectedItemType) ? 'selected ' + noTags : '' + noTags;
}
}
};
</script><script id="item-grid-template" type="text/x-template">
<div>
<div id="item_mask"></div>
<h3 v-if="accountSettled" class="margins_sm">{{ loc[categoryLocKey] }}</h3>
<div v-if="accountSettled" id="equip_grid" :class="gridClass">
<item v-for="i in items" :loc="loc" :item="i" :key="i.id" :isSelected="isSelected(i)" @item-selected="onItemSelected"></item>
<div v-show="!inShop" class="store_item roundme_lg '.$is_hi.' '.$is_na.' clickme morestuff bevel_green" @click="onSwitchToShopClick"></div>
<div v-show="inShop && !hiddenPremItemCheck" class="store_item roundme_lg '.$is_hi.' '.$is_na.' soldout">
<div class="soldout_head shadow_bluebig5" v-html="loc.eq_sold_out_head"></div>
<div class="soldout_text" v-html="loc.eq_sold_out_text"></div>
</div>
</div>
<div id="items-account-not-loaded" v-show="!accountSettled" class="text-center">
<h3>{{loc.signin_auth_title}}</h3>
<p>{{loc.signin_auth_msg}}</p>
</div>
</div>
</script>
<script>
var comp_item_grid = {
template: '#item-grid-template',
components: { 'item': comp_item },
props: ['items', 'selectedItem', 'gridClass', 'categoryLocKey', 'inShop'],
data() {
return vueData;
},
methods: {
onItemSelected: function (selectedItem) {
this.$emit('item-selected', selectedItem);
},
isSelected: function (item) {
if (!hasValue(this.selectedItem)) {
return false;
}
return (this.selectedItem.id === item.id);
},
onSwitchToShopClick: function () {
this.$emit('switch-to-shop');
BAWK.play('ui_playconfirm');
},
isPremItemInStore() {
let hasItem = false;
for (let i = 0; i < this.items.length; i++) {
const item = this.items[i];
const isItem = vueApp.premiumShopItems.find(i => i.isActive && i.itemId.id === item.id);
if (hasValue(isItem)) {
hasItem = true;
break;
}
}
return hasItem;
}
},
computed: {
categoryName: function () {
if (!hasValue(this.selectedItem)) {
return null;
}
return this.loc['item_type_' + this.selectedItem.item_type_id];
},
hiddenPremItemCheck() {
if (this.items.some(i => i.unlock === 'purchase') || this.items.length !== 0) return true;
if (this.items.some(i => i.unlock === 'premium')) return this.isPremItemInStore();
return false;
}
}
};
</script>
<script>
var comp_equip_screen = {
template: '#equip-screen-template',
components: {
'account-panel': comp_account_panel,
'equipped-slots': comp_equipped_slots,
'color-select': comp_color_select,
'item-timer': comp_item_timer,
'price-tag': comp_price_tag,
'physical-tag': comp_physical_tag,
'item-type-selector': comp_item_type_selector,
'item-grid': comp_item_grid,
'house-ad-small': comp_house_ad_small,
'weapon-select-panel': comp_weapon_select_panel,
'item': comp_item,
// 'account-panel': comp_account_panel,
'house-ad-small': comp_house_ad_small
},
data: function () {
return vueData;
},
equippedItems: {},
methods: {
setup: function (itemType) {
if (!itemType) { itemType = ItemType.Primary; }
this.updateEquippedItems();
this.poseEquippedItems();
if (itemType === 'tagged') {
this.populateItemGridWithTagged(this.equip.specialItemsTag);
} else {
this.populateItemGridWithType(itemType);
}
this.selectEquippedItemForType();
},
updateEquippedItems: function () {
this.$options.equippedItems = extern.getEquippedItems();
this.equip.equippedHat = this.$options.equippedItems[ItemType.Hat];
this.equip.equippedStamp = this.$options.equippedItems[ItemType.Stamp];
this.equip.equippedGrenade = this.$options.equippedItems[ItemType.Grenade];
this.equip.equippedPrimary = this.$options.equippedItems[ItemType.Primary];
this.equip.equippedSecondary = this.$options.equippedItems[ItemType.Secondary];
},
poseEquippedItems: function () {
this.posingHat = this.equip.equippedHat;
this.posingStamp = this.equip.equippedStamp;
switch (this.equip.showingWeaponType) {
case ItemType.Primary:
this.posingWeapon = this.equip.equippedPrimary;
this.posingGrenade = null;
break;
case ItemType.Secondary:
this.posingWeapon = this.equip.equippedSecondary;
this.posingGrenade = null;
break;
case ItemType.Grenade:
this.posingGrenade = this.equip.equippedGrenade;
break;
}
this.workItBaby();
},
selectEquippedItemForType: function () {
switch (this.equip.selectedItemType) {
case ItemType.Hat: this.equip.selectedItem = this.equip.equippedHat; break;
case ItemType.Stamp: this.equip.selectedItem = this.equip.equippedStamp; break;
case ItemType.Primary: this.equip.selectedItem = this.equip.equippedPrimary; break;
case ItemType.Secondary: this.equip.selectedItem = this.equip.equippedSecondary; break;
case ItemType.Grenade: this.equip.selectedItem = this.equip.equippedGrenade; break;
}
},
populateItemGridWithType: function (itemType) {
this.equip.selectedItemType = itemType;
var items = extern.getItemsOfType(itemType);
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_{0}{1}'.format(itemType, ((itemType === ItemType.Primary) ? '_' + this.classIdx : ''));
},
populateItemGridWithTagged: function (tag) {
var items = extern.getTaggedItems(tag);
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_5';
},
populateItemGrid: function (items) {
if (this.equip.mode === vueData.equip.equipModes.inventory) {
items = items.filter(i => {
return extern.isItemOwned(i) || (i.is_available && i.unlock === "default");
});
}
else {
items = items.filter(i => {
// return (i.is_available || extern.account.isSubscriber) && !extern.isItemOwned(i) && i.unlock !== "default" && i.unlock !== 'manual';
return i.is_available && !extern.isItemOwned(i) && i.unlock !== "default";
})
}
this.equip.showingItems = items;
},
workItBaby: function () {
extern.poseWithItem(ItemType.Hat, this.posingHat);
extern.poseWithItem(ItemType.Stamp, this.posingStamp);
extern.poseWithItem(this.posingWeapon.item_type_id, this.posingWeapon);
if (this.posingGrenade) extern.poseWithItem(this.posingGrenade.item_type_id, this.posingGrenade);
},
onBackClick: function () {
extern.saveEquipment();
this.equip.showingWeaponType = ItemType.Primary;
this.poseEquippedItems();
if (!extern.inGame) {
vueApp.showTitleScreenAd();
vueApp.switchToHomeUi();
} else {
extern.closeEquipInGame();
vueApp.switchToGameUi();
vueApp.showGameMenu();
vueApp.showRespawnDisplayAd();
}
BAWK.play('ui_popupclose');
},
onItemTypeChanged: function (itemType) {
this.switchItemType(itemType);
},
switchItemType: function (itemType) {
if (itemType !== this.equip.selectedItemType) {
if (itemType === ItemType.Primary || itemType === ItemType.Secondary || itemType == ItemType.Grenade) {
this.equip.showingWeaponType = itemType;
}
this.poseEquippedItems();
this.populateItemGridWithType(itemType);
if (this.equip.mode === this.equip.equipModes.inventory) {
this.selectEquippedItemForType();
} else {
this.selectFirstItemInShop();
}
}
if (!this.isInShop) {
this.hideItemForSale();
this.hideItemForSpecial();
}
BAWK.play('ui_click');
},
onTaggedItemsClicked: function () {
BAWK.play('ui_click');
if (this.equip.selectedItemType === 'tagged') {
return;
}
this.showTaggedItems(this.equip.specialItemsTag);
this.selectFirstItemInShop();
},
onPremiumItemsClicked() {
BAWK.play('ui_click');
if (this.equip.selectedItemType === 'premium') {
return;
}
this.showPremiumItems();
this.selectFirstItemInShop();
},
showPremiumItems() {
this.equip.selectedItemType = 'premium';
var items = extern.getPremiumItems();
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_7';
},
showTaggedItems: function (tag) {
this.equip.selectedItemType = 'tagged';
if (this.equip.mode === this.equip.equipModes.inventory && !this.ownsTaggedItems(this.equip.specialItemsTag)) {
this.equip.mode = this.equip.equipModes.shop;
vueApp.conditionalAnonWarningCall();
}
this.populateItemGridWithTagged(tag);
},
showSelectedTagItems(tag) {
this.equip.selectedItemType = 'tagged';
// if (this.equip.mode === this.equip.equipModes.inventory) {
// this.equip.mode = this.equip.equipModes.shop;
// }
this.populateItemGridWithTagged(tag);
},
switchToInventory: function () {
if (this.equip.selectedItemType === 'tagged' && this.equip.mode === this.equip.equipModes.shop) {
if (!this.ownsTaggedItems(this.equip.specialItemsTag)) {
this.switchItemType(ItemType.Primary);
}
}
this.equip.mode = this.equip.equipModes.inventory;
this.hideItemForSale();
this.hideItemForSpecial();
this.poseEquippedItems();
this.showItemsAfterEquipModeSwitch();
this.selectEquippedItemForType();
BAWK.play('ui_toggletab');
// vueApp.histPushState({game: this.ui.screens.equip}, 'Shellshockers equipment inventory', '?equip=inventory');
},
ownsTaggedItems: function (tag) {
return extern.getTaggedItems(tag).filter(i => {
return extern.isItemOwned(i);
}).length > 0;
},
selectFirstItemInShop: function () {
if (this.isInShop && this.equip.showingItems.length > 0) {
this.selectItem(this.equip.showingItems[0]);
}
},
switchToShop: function () {
if (!this.accountSettled) {
return;
}
this.equip.mode = this.equip.equipModes.shop;
this.showItemsAfterEquipModeSwitch();
this.selectFirstItemInShop();
vueApp.conditionalAnonWarningCall();
BAWK.play('ui_toggletab');
// vueApp.histPushState({game: this.ui.screens.equip}, 'Shellshockers equipment shop', '?equip=shop');
},
showItemsAfterEquipModeSwitch: function () {
if (this.equip.selectedItemType === 'tagged') {
this.showTaggedItems(this.equip.specialItemsTag)
} else if (this.equip.selectedItemType === 'premium') {
this.showPremiumItems();
} else {
this.populateItemGridWithType(this.equip.selectedItemType);
}
},
onEquippedTypeSelected: function (itemType) {
this.equip.selectedItemType = itemType;
if (
this.equip.selectedItemType === ItemType.Primary ||
this.equip.selectedItemType === ItemType.Secondary ||
this.equip.selectedItemType === ItemType.Grenade
) {
this.equip.showingWeaponType = itemType;
}
this.switchToInventory();
},
onChangedClass: function () {
this.hideItemForSale();
this.hideItemForSpecial();
if (this.posingGrenade) {
this.posingGrenade = null;
this.onEquippedTypeSelected(ItemType.Primary);
}
if (this.equip.selectedItemType !== ItemType.Primary) {
this.onEquippedTypeSelected(ItemType.Primary);
}
this.updateEquippedItems();
this.poseEquippedItems();
this.populateItemGridWithType(this.equip.selectedItemType);
if (extern.inGame && this.ui.showScreen !== this.ui.screens.equip) {
this.equip.showingWeaponType = ItemType.Primary;
this.poseEquippedItems();
extern.closeEquipInGame();
}
},
autoSelectItem: function (item) {
if (extern.isItemOwned(item)) {
this.switchToInventory();
} else {
this.switchToShop();
}
this.switchItemType(item.item_type_id);
this.selectItem(item);
},
onItemSelected: function (item) {
this.selectItem(item);
},
isPremItemInStore(item) {
let hasItem = false;
const isItem = this.premiumShopItems.find(i => i.isActive && i.itemId.id === item.id);
if (hasValue(isItem)) {
hasItem = true;
}
return hasItem;
},
selectItem: function (item) {
var selectingSame = hasValue(this.equip.selectedItem) && this.equip.selectedItem.id === item.id;
var selectedId = selectingSame ? this.equip.selectedItem.id : null;
var isWeapon = (item.item_type_id === ItemType.Primary || item.item_type_id === ItemType.Secondary);
BAWK.play('ui_click');
if (selectingSame) {
if (this.isInShop) {
// Revert to equipped weapon
item = this.$options[this.equip.selectedItem.item_type_id];
} else {
// Take off hat or stamp
if (!isWeapon) {
item = null;
extern.removeItemType(this.equip.selectedItem.item_type_id);
}
}
}
if (this.isInShop) {
if ( item && item.hasOwnProperty('unlock') && item.unlock === 'premium' && !this.isPremItemInStore(item)) {
// Revert to equipped weapon
item = this.$options[this.equip.selectedItem.item_type_id];
}
}
// Take off any items being tried on
this.poseEquippedItems();
this.equip.selectedItem = item;
extern.tryEquipItem(item);
this.updateEquippedItems();
if (hasValue(item)) {
this.poseWithItem(item);
if (this.isInShop) {
switch (item.unlock) {
case "physical":
console.log('purchasing physical item');
if ( !selectingSame ) {
this.offerItemForSpecial(item)
this.hideItemForSale();
} else {
this.hideItemForSpecial();
}
// this.$refs.physicalUnlockPopup.toggle();
break;
case "purchase":
case "premium":
if (!selectingSame) {
this.offerItemForSale(item);
this.hideItemForSpecial();
} else {
this.hideItemForSale();
}
break;
}
}
} else {
this.poseEquippedItems();
this.hideItemForSale();
this.hideItemForSpecial();
}
},
poseWithItem: function (item) {
switch (item.item_type_id) {
case ItemType.Hat: this.posingHat = item; break;
case ItemType.Stamp: this.posingStamp = item; break;
case ItemType.Grenade: this.posingGrenade = item; break;
case ItemType.Primary:
case ItemType.Secondary: this.posingWeapon = item; break;
}
this.workItBaby();
},
getButtonToggleClass: function (equipMode) {
return (equipMode === this.equip.mode) ? 'btn_toggleon' : 'btn_toggleoff';
},
offerItemForSpecial: function(item) {
return this.equip.physicalUnlockPopup.item = item;
},
hideItemForSpecial: function() {
this.equip.physicalUnlockPopup.item = null;
},
offerItemForSale: function (item) {
this.equip.buyingItem = item;
},
hideItemForSale: function () {
this.equip.buyingItem = null;
// this.equip.physicalUnlockPopup.item = null
},
onBuyItemClicked: function () {
// If item is buying item show buyItemPopup or show physicalUnlockPopup
this.equip.buyingItem ? this.$refs.buyItemPopup.toggle() : this.$refs.physicalUnlockPopup.toggle();
this.equip.buyingItem ? extern.renderItemToCanvas(this.equip.buyingItem, this.$refs.buyItemCanvas) : null;
BAWK.play('ui_popupopen');
},
onBuyItemConfirm: function () {
if (this.equip.buyingItem.unlock === 'premium') {
extern.buyProductForMoney(this.equip.buyingItem.sku);
return;
} else {
extern.api_buy(this.equip.buyingItem, this.boughtItemSuccess, this.boughtItemFailed);
}
BAWK.play('ui_playconfirm');
},
boughtItemSuccess: function () {
this.equip.selectedItem = this.equip.buyingItem;
ga('send', 'event', {
eventCategory: this.googleAnalytics.cat.itemShop,
eventAction: this.googleAnalytics.action.shopItemPopupBuy,
eventLabel: this.equip.buyingItem.name,
eventValue: this.equip.selectedItem.price
});
var itemType = this.equip.selectedItem.item_type_id;
if (itemType === ItemType.Primary || itemType === ItemType.Secondary || itemType == ItemType.Grenade) {
this.equip.showingWeaponType = itemType;
}
this.hideItemForSale();
this.setup(this.equip.selectedItemType);
this.updateEquippedItems();
this.poseEquippedItems();
this.selectEquippedItemForType();
},
boughtItemFailed: function () {
vueApp.showGenericPopup('p_buy_error_title', 'p_buy_error_content', 'ok');
BAWK.play('ui_reset');
},
onRedeemClick: function () {
this.$refs.redeemCodePopup.code = '';
this.$refs.redeemCodePopup.toggle();
BAWK.play('ui_popupopen');
},
onRedeemCodeConfirm: function () {
if (this.equip.redeemCodePopup.code.toUpperCase() === 'D3LL0RKC1R') {
this.giveStuffPopup.eggOrg = false;
this.giveStuffPopup.rickroll = true;
vueApp.showGiveStuffPopup('p_give_stuff_title');
} else {
this.giveStuffPopup.rickroll = false;
this.giveStuffPopup.eggOrg = false;
extern.api_redeem(this.equip.redeemCodePopup.code, this.redeemCodeSuccess, this.redeemCodeFailed);
}
BAWK.play('ui_playconfirm');
},
redeemCodeSuccess: function (eggs, items) {
this.populateItemGridWithType(this.equip.selectedItemType);
this.giveStuffPopup.eggs = eggs;
this.giveStuffPopup.items = items;
vueApp.showGiveStuffPopup('p_give_stuff_title', eggs, items);
let itemString = '';
this.giveStuffPopup.items.forEach(item => itemString += item.name);
ga('send', 'event', {
eventCategory: this.googleAnalytics.cat.redeem,
eventAction: this.googleAnalytics.action.redeemed,
eventLabel: `${itemString ? itemString : ''} ${this.giveStuffPopup.eggs ? this.giveStuffPopup.eggs + 'eggs' : ''}`
});
},
redeemCodeFailed: function () {
vueApp.showGenericPopup('p_redeem_error_title', 'p_redeem_error_content', 'ok');
BAWK.play('ui_reset');
},
onPhysicalUnlockConfirm: function () {
window.open(this.equip.physicalUnlockPopup.item.item_data.physicalItemStoreURL, '_blank');
},
onColorChanged: function (colorIdx) {
this.equip.colorIdx = colorIdx;
extern.setShellColor(this.equip.colorIdx);
BAWK.play('ui_onchange');
},
onSwitchToShopClicked: function () {
this.switchToShop();
}
},
computed: {
isInShop: function () {
return (this.equip.mode === this.equip.equipModes.shop);
},
getGridClass: function () {
return this.isInShop ? '' : 'equip_grid_short';
},
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '');
},
isBuyingItemPrem() {
if (!this.equip.buyingItem) {
return;
}
return this.equip.buyingItem.unlock === 'premium';
}
}
};
</script><script id="game-screen-template" type="text/x-template">
<div>
<event-panel :show-soon="false" :show-ui="ui.showCornerButtons"></event-panel>
<account-panel id="game_account_panel" ref="accountPanelGame" :loc="loc" :eggs="eggs" :show-bottom="false" :show-corner-buttons="ui.showCornerButtons" :ui="ui" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" :currentLangOptions="locLanguage" :is-twitch="twitchLinked"></account-panel>
<div id="chickenBadge" ref="chickenBadge" style="display: none;"><img :src="upgradeBadgeUrl"></div>
<!-- Scope -->
<div id="scopeBorder">
<div id="maskleft"></div>
<div id="maskmiddle"></div>
<div id="maskright"></div>
</div>
<!-- Best Streak -->
<div id="best_streak_container">
<h1 v-show="(((doubleEggWeekend || doubleEggWeekendSoon) && !ui.showCornerButtons) || (!doubleEggWeekend && !doubleEggWeekendSoon))" id="bestStreak">x0</h1>
</div>
<div v-show="announcementMessage" id="announcement_message">{{ announcementMessage }}</div>
<div id="shellStreakContainer">
<h1 id="shellStreakCaption"></h1>
<h1 id="shellStreakMessage" class="disappear"></h1>
</div>
<!-- Team Scores -->
<div id="teamScores">
<div id="teamScore2" class="teamScore red inactive">
<div id="teamScoreNum2" class="number">0</div>
<div class="teamLetter red" style="color: #f00;">R</div>
</div>
<div id="teamScore1" class="teamScore blue inactive">
<div id="teamScoreNum1" class="number">0</div>
<div class="teamLetter blue" style="color: #0af;">B</div>
</div>
<!--<div>
<img src="img/spatulaIcon.png" style="width: 3em; transform: rotate(60deg)">
</div>-->
</div>
<!-- Capture Icon -->
<div id="captureIconContainer">
<div id="captureInsideContainer">
<div id="captureIconCaption">20M</div>
<div id="captureRingBackground"></div>
<div id="captureRingContainer">
<div id="captureRing"></div>
</div>
<svg id="captureIcon" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" />
</svg>
</div>
</div>
<!-- Reticle -->
<div id="reticleContainer">
<div id="dotReticle"></div>
<div id="crosshairContainer">
<div id="crosshair0" class="crosshair normal"></div>
<div id="crosshair1" class="crosshair normal"></div>
<div id="crosshair2" class="crosshair normal"></div>
<div id="crosshair3" class="crosshair normal"></div>
</div>
<div id="shotReticleContainer">
<div id="shotBracket0" class="shotReticle border normal"></div>
<div id="shotBracket1" class="shotReticle border normal"></div>
<div id="shotBracket2" class="shotReticle fill normal"></div>
<div id="shotBracket3" class="shotReticle fill normal"></div>
</div>
<div id="readyBrackets">
<div class="readyBracket"></div>
<div class="readyBracket"></div>
<div class="readyBracket"></div>
<div class="readyBracket"></div>
</div>
</div>
<!-- Capture Zone progress -->
<div id="captureContainer">
<div class="captureScoreContainer">
<svg class="captureCrown" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" fill="var(--ss-team-red-light)" />
</svg>
<div id="captureScoreRed" class="captureScore">0/5</div>
</div>
<div id="captureCenter">
<div id="captureBarContainer">
<div id="captureBar"></div>
</div>
<div id="captureBarText"></div>
</div>
<div class="captureScoreContainer">
<svg class="captureCrown" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" fill="var(--ss-team-blue-light)" />
</svg>
<div id="captureScoreBlue" class="captureScore">0/5</div>
</div>
</div>
<!-- Big Message Bar -->
<div id="bigMessageContainer" style="display: none">
<div id="bigMessageBar">
<div id="bigMessage"></div>
<div id="bigMessageCaption"></div>
</div>
</div>
<!-- Weapon -->
<div id="weaponBox">
<div id="grenades">
<img id="grenade3" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
<img id="grenade2" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
<img id="grenade1" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
</div>
<h2 id="weaponName"></h2>
<h2 id="ammo" class="shadow_grey"></h2>
</div>
<!-- Health -->
<div id="healthContainer">
<svg class="healthSvg">
<circle id="healthBar" class="healthBar" cx="50%" cy="50%" r="2.15em" />
<circle class="healthYolk" cx="50%" cy="50%" r="1.35em" />
</svg>
<div id="healthHp">100</div>
</div>
<!-- Hard Boiled -->
<div id="hardBoiledContainer">
<div id="hardBoiledShieldContainer">
<img class="hardBoiledShield" src="img/hardBoiledEmpty.png">
<img class="hardBoiledShield" id="hardBoiledShieldFill" src="img/hardBoiledFilled.png">
</div>
<div id="hardBoiledValue">100</div>
</div>
<!-- EggBreaker Shellstreak -->
<div id="eggBreakerContainer" class="off">
<img id="eggBreakerIcon" src="img/ico_eggBreaker.png" />
<div id="eggBreakerTimer">15</div>
</div>
<!-- Spatula -->
<img id="spatulaPlayer" src="img/spatulaIcon.png" />
<!-- Grenade throw power -->
<div id="grenadeThrowContainer">
<div id="grenadeThrow"></div>
</div>
<!-- Kill -->
<div id="killBox" class="shadow_grey">
<!-- <h3>{{ loc.ui_game_youkilled }}</h3> -->
<div v-html="killedMessage"></div>
<!-- <h2 id="KILLED_NAME"></h2> -->
<h3 id="KILL_STREAK"></h3>
</div>
<!-- Death -->
<div id="deathBox">
<div v-html="killedByMessage"></div>
</div>
<!-- Game messages -->
<div id="gameMessage"></div>
<!-- Chat -->
<div id="chatOut" class="chat roundme_sm"></div>
<input id="chatIn" class="chat roundme_sm" maxlength=64 tabindex=-1 v-bind:placeholder="loc.ingame_press_tab_to_exit" onkeydown="extern.onChatKeyDown(event)"></input>
<!-- Kill ticker -->
<div id="killTicker" class="chat"></div>
<!-- Spectator controls -->
<div id="spectate">
{{ loc.ui_game_spectating }}
</div>
<div id="serverAndMapInfo" class="shadow_grey"></div>
<!-- Ingame UI Stuff -->
<div id="inGameUI">
<div id="readouts" class="shadow_grey">
{{ loc.ui_game_fps }}: <div id="FPS"></div><br>
{{ loc.ui_game_ping }}: <div id="ping"></div>
</div>
<!-- Corner icon buttons -->
<!--
<div id="corner" style="float: right; margin-top: 0.5em;">
<div id="currentBalanceContainer" style="display: none; position: relative; left: -1em; top: 0.15em;">
<span id="currentBalance" style="display: inline-block; font-size: 1.7em; position: relative; top: -0.25em; left: -0.1em; color: white;"></span>
boopdiddyboop<img src="img/egg_icon.png" style="width: 1.6em; height: 2em;" />
</div>
<div id="cornerButtons" style="display: none; margin-bottom: 0.5em; text-align: right; float: right;">
<-<img id="homeButton" style="display: none; margin-right: 0.5em;" title="Home" class="icon" src="img/home.png?v=1" onclick="extern.showMainMenuConfirm()" />
<img id="friendsButton" style="display: none; margin-right: 0.5em;" title="Invite friends" class="icon" src="img/friends.png?v=1" onclick="extern.inviteFriends()" />
<img style="margin-right: 0.5em;" title="Feedback" class="icon" src="img/feedback.png?v=1" onclick="extern.showFeedbackForm()" />
<img style="margin-right: 0.5em;" title="Settings" class="icon" src="img/settings.png?v=1" onclick="extern.openSettingsMenu()" />
<img class="icon" title="Toggle fullscreen" src="img/fullScreen.png?v=1" onclick="extern.toggleFullscreen()" /> ->
</div>
</div>
-->
</div>
<!-- Popup: Mute/Boot Player -->
<small-popup id="playerActionsPopup" ref="playerActionsPopup" @popup-cancel="onPlayerActionsCancel" @popup-closed="onPlayerActionsCancel" :hide-confirm="true">
<template slot="header">{{ playerActionsPopup.playerName }}</template>
<template slot="content">
<div v-if="playerActionsPopup.vipMember" class="vip-member-wraper display-grid grid-align-items-center grid-column-1-2 ss_marginbottom_xl">
<figure class="player-action-vip-img center_h">
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Vip member icon" class="center_h">
</figure>
<div>
<h6 class="roundme_sm shadow_blue4 ss_margintop ss_marginbottom">{{loc.ui_game_playeractions_vip_member}}</h6>
<button v-if="!isSubscriber" class="ss_button btn_pink bevel_pink fullwidth" @click="openVipPopup">{{loc.ui_game_playeractions_join_vip}}</button>
</div>
</div>
<!-- .vip-member-wraper -->
<p>{{ loc.ui_game_playeractions_header }}</p>
<button v-if="playerActionsPopup.social" class="ss_button btn_medium btn_yolk bevel_yolk fullwidth" @click="onClickCreator(playerActionsPopup.social.url)"><i class="fab" :class="playerSocial"></i> {{loc.ui_game_playeractions_creator}}</button>
<h4 class="ss_button btn_medium btn_blue bevel_blue" v-on:click="onMuteClicked">{{ muteButtonLabel }}</h4>
<h4 class="ss_button btn_medium btn_yolk bevel_yolk" v-if="playerActionsPopup.isGameOwner" v-on:click="onBootClicked">{{ loc.ui_game_playeractions_boot }}</h4>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
</small-popup>
<!-- Popup: Switch Team -->
<small-popup id="switchTeamPopup" ref="switchTeamPopup" @popup-cancel="onSwitchTeamCancel" :overlay-close="false" @popup-closed="onSwitchTeamCancel" @popup-confirm="onSwitchTeamConfirm">
<template slot="header">{{ loc.p_switch_team_title }}</template>
<template slot="content">
<h4 class="roundme_sm" :class="newTeamColorCss">{{ newTeamName }} <i class="fa fa-flag"></i></h4>
<p>{{ loc.p_switch_team_text }}</p>
</template>
<template slot="cancel">{{ loc.no }}</template>
<template slot="confirm">{{ loc.yes }}</template>
</small-popup>
<!-- Popup: Share Link -->
<small-popup id="shareLinkPopup" ref="shareLinkPopup" :popup-model="game.shareLinkPopup" @popup-confirm="onShareLinkConfirm" @popup-closed="onShareLinkClosed">
<template slot="header">{{ loc.p_sharelink_title }}</template>
<template slot="content">
<p>{{ loc.p_sharelink_text }}</p>
<p><input ref="shareLinkUrl" type="text" class="ss_field ss_margintop ss_marginbottom fullwidth" v-model="game.shareLinkPopup.url" @focus="$event.target.select()"></p>
</template>
<template slot="cancel">{{ loc.close }}</template>
<template slot="confirm">{{ loc.p_sharelink_copylink }}</template>
</small-popup>
<!-- Popup: Leave Game Confirm -->
<small-popup id="leaveGameConfirmPopup" ref="leaveGameConfirmPopup" :overlay-close="false" :hide-close="true" @popup-confirm="onLeaveGameConfirm" @popup-cancel="onLeaveGameCancel">
<template slot="header">{{ loc.leave_game_title }}</template>
<template slot="content">
<p>{{ loc.leave_game_text }}</p>
</template>
<template slot="cancel">{{ loc.no }}</template>
<template slot="confirm">{{ loc.yes }}</template>
</small-popup>
<div class="player__container">
<!-- Player List -->
<div id="playerSlot" class="playerSlot" style="display: none">
<div>
<span></span> <!-- Name -->
<span></span> <!-- Score -->
</div>
<div style="display: block;"></div> <!-- Icons -->
</div>
<div id="playerList"></div>
</div>
<!-- end .player__container -->
<div id="inGameScaler">
<div class="pause-popup--container">
<!-- Popup: Pause -->
<large-popup id="pausePopup" ref="pausePopup" hide-close="true" :overlay-close="false" :overlay-class="ui.overlayClass.inGame">
<template slot="content">
<div class="box_blue2 roundme_sm">
<div id="pausePopupInnards" class="roundme_sm f_row">
<div id="pauseButtons" class="f_col pause-btn-group">
<button @click="onHomeClicked" class="ss_button btn_blue bevel_blue"><i class="fa fa-home"></i> {{ loc.p_pause_home }}</button>
<button @click="onEquipClicked()" class="ss_button btn_blue bevel_blue"><i class="fas fa-star"></i> {{ loc.p_pause_equipment }}</button>
<button v-if="!delayTheCracking && !isRespawning" class="ss_button btn_red bevel_red btn_sm" disabled="disabled"><i class="fas fa-eye"></i> {{ loc.ui_game_get_ready }}</button>
<button v-if="delayTheCracking" v-show="!isRespawning" @click="onSpectateClicked()" class="ss_button btn_blue bevel_blue btn_sm" :disabled="isRespawning"><i class="fas fa-eye"></i> {{ loc.p_pause_spectate }}</button>
<music-widget ref="gameScreenMusic" :loc="loc" :settings-ui="settingsUi" :settings="true" :volumeSlider="false" :show="isPaused && showMusicWidget"></music-widget>
</div>
<!-- #pauseButtons -->
<div id="popupTipDay" class="roundme_sm flex-auto">
<div v-if="isPoki && pokiRewardReady" class="poki-reward-container">
<button class="ss_button btn_blue bevel_blue btn_reward pure-wiggle" @click="earnInGameReward"><img src="img/ico_goldenEgg.png" class="egg_icon">Watch Video for 100 Golden Eggs!</button>
</div>
<div v-show="!isPoki && firebaseId" id="chw-progress-wrapper" class="chw-progress-wrapper box_relative">
<!-- incentivized-mini-game -->
<img class="box_aboslute chw-progress-img chw-chick" :src="chwChickSrc">
<div class="chw-progress-bar-wrap roundme_sm box_relative btn_blue bevel_blue" :class="progressBarWrapClass" @click="playIncentivizedAd">
<p class="chw-progress-bar-msg box_aboslute centered nospace text-center fullwidth chw-msg chw-p-msg">
{{ progressMsg }}
<!-- <span class="chw-countdown-wrap" :class="chwShowCountdown">
<span class="chw-minutes"></span><span class="chw-seconds"></span>
</span> -->
</p>
<div class="chw-progress-bar-inner" @click="playIncentivizedAd">
</div>
</div>
<img class="box_aboslute chw-eggs chw-progress-img" src="img/egg_pack_small.png" alt="">
</div>
<!-- #chw-progress-wrapper end -->
<!-- .poki-reward-container -->
<div id="btn_horizontal" class="pause-popup--btn-group">
<header class="weapon-select weapon-select--title pause-bg roundme_sm">
<h1>{{loc.p_weapon_title}}</h1>
</header>
<div class="pause-bg roundme_sm">
<weapon-select-panel ref="weaponSelect" id="weapon_select" :loc="loc" :current-class="classIdx" @changed-class="pauseWeaponSelect"></weapon-select-panel>
</div>
<!-- .pause-bg -->
</div>
<!-- .pause-popup--btn-group -->
<div id="game-play-switch" class="paused-game-cotrols roundme_sm f_row">
<div v-if="delayTheCracking" class="switch-teams-btn">
<button v-show="isTeamGame" @click="onSwitchTeamClicked" class="ss_button btn__team_switch" :class="teamColorCss"><i class="fa fa-flag"></i> {{ teamName }}</button>
</div>
<!-- .switch-teams-btn -->
<div class="pause-popup--btn-group f-grow-full">
<button v-if="!delayTheCracking && !isRespawning" class="btn_big btn_wfull ss_button btn_red bevel_red" disabled="disabled">{{ loc.ui_game_get_ready }}</button>
<button v-if="delayTheCracking" class="btn_big btn_wfull ss_button btn_red bevel_red" v-show="isRespawning" :disabled="isRespawning">{{ game.respawnTime }}</button>
<button v-if="delayTheCracking" v-show="!isRespawning" @click="onPlayClicked()" class="btn-respawn btn_big btn_wfull ss_button btn_yolk bevel_yolk" :disabled="isRespawning"><i class="fa fa-play"></i> {{ loc.p_pause_play }}</span></button>
<!-- .pause-popup--btn-group -->
</div>
<!-- .w-shrinkauto -->
</div>
<!-- #game-play-switch -->
</div>
<!-- #popupTipDay -->
</div>
<!-- #pausePopupInnards -->
</div>
</template>
</large-popup>
<div class="respawn-container respawn-two" v-show="isPaused">
<display-ad :hidden="hideAds" id="shellshockers_respawn_banner_2_ad" ref="respawnTwoDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawnTwo" adSize="300x250"></display-ad>
</div>
<div class="respawn-container respawn-one" v-show="isPaused">
<!-- <display-ad :hidden="hideAds" id="shellshockers_respawn_banner_ad" ref="respawnDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawn" adSize="728x90"></display-ad> -->
<display-ad :hidden="hideAds" id="shellshockers_respawn_banner-new_ad" ref="respawnDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawnThree" adSize="728x90"></display-ad>
</div>
</div>
<!-- .pause-popup--container -->
</div>
<!-- end #inGameScaler -->
<div class="in-game-widgets">
<music-widget ref="musicWidgetinGame" :loc="loc" :settings-ui="settingsUi" :show="showIngameWidget"></music-widget>
</div>
{{showIngameWidget}}
</div>
</script>
<script>
var comp_game_screen = {
template: '#game-screen-template',
components: {
'account-panel': comp_account_panel,
// 'event-panel': comp_events,
'weapon-select-panel': comp_weapon_select_panel,
// 'music-widget': comp_music_widget,
'event-panel': comp_events,
'weapon-select-panel': comp_weapon_select_panel,
},
props: ['kname', 'kdname'],
data: function () {
return vueData;
},
created: function () {
this.isPoki = pokiActive;
},
methods: {
placeBannerAdTagForGame: function (tagEl) {
this.$refs.pauseAdPlacement.appendChild(tagEl);
},
showGameMenu: function () {
// this.game.tipIdx = this.loc.tip_ofthe_day
// ? Math.randomInt(0, this.loc.tip_ofthe_day.length)
// : 0;
this.game.gameType = extern.gameType;
vueApp.showRespawnDisplayAd();
this.$refs.pausePopup.show();
this.isPaused = true;
vueApp.isPaused = true;
setTimeout(() => vueApp.disableRespawnButton(false), 500);
vueData.ui.showCornerButtons = true;
vueApp.gameUiAddClassForNoScroll();
addEventListener('gamepadbuttondown', this.onControllerButton);
this.crazyAdsRespawn();
extern.chicknWinnerOnPause();
vueApp.hideShareLinkPopup();
},
delayGameMenuPlayButtons() {
setTimeout(() => {
this.delayTheCracking = true;
}, 3000);
},
hideGameMenu: function () {
if (!extern.inGame) {
return;
}
this.$refs.pausePopup.hide();
// this.$refs.respawnDisplayAd.hide();
// this.$refs.respawnTwoDisplayAd.hide();
if (crazyGamesActive) crazysdk.clearAllBanners(); // Per CG's request
this.isPaused = false;
vueApp.isPaused = false;
vueApp.gameUiAddClassForNoScroll();
removeEventListener('gamepadbuttondown', this.onControllerButton);
},
onHomeClicked: function () {
this.gaSend('home');
this.hideGameMenu();
this.$refs.leaveGameConfirmPopup.show();
BAWK.play('ui_click');
},
onLeaveGameConfirm: function () {
this.leaveGame();
this.delayTheCracking = false;
},
onLeaveGameCancel: function () {
this.showGameMenu();
},
leaveGame: function () {
// clientGame.js manipulates chickenBadge element directly to hide/show it
vueApp.disablePlayButton(false);
this.$refs.chickenBadge.style.display = 'none';
vueApp.showSpinner();
document.body.style.overflow = 'visible';
window.scrollY = 0;
this.hidePopupsIfGameCloses();
extern.leaveGame(this.afterLeftGame);
vueData.ui.showCornerButtons = true;
// OneSignal elements are not part of the Vue app
var oneSignalBell = document.getElementById('onesignal-bell-container');
if (oneSignalBell) {
oneSignalBell.style.display = 'inline-block';
}
},
hidePopupsIfGameCloses: function() {
const gamePopups = vueApp.$refs.gameScreen.$children;
if (Array.isArray(gamePopups)) {
gamePopups.forEach( gamePopup => {;
if ( gamePopup.isShowing === true && gamePopup.$el.id !== 'pausePopup' ) {
gamePopup.close();
console.log(`Closing ${gamePopup.$el.id}`);
}
});
}
},
afterLeftGame: function () {
vueApp.hideSpinner();
vueApp.showTitleScreenAd();
vueApp.switchToHomeUi();
},
onHelpClicked: function () {
this.hideGameMenu();
vueApp.showHelpPopup();
BAWK.play('ui_popupopen');
},
onShareLinkClicked: function () {
extern.inviteFriends();
BAWK.play('ui_popupopen');
},
onSettingsClicked: function () {
this.hideGameMenu();
vueApp.showSettingsPopup();
BAWK.play('ui_popupopen');
},
onShareLinkConfirm: function () {
extern.copyFriendCode(this.$refs.shareLinkUrl);
},
onShareLinkClosed: function () {
this.showGameMenu();
},
onEquipClicked: function () {
this.game.pauseScreen.wasGameInventoryOpen = true;
this.game.pauseScreen.classChanged = false;
this.gaSend('inventory');
vueApp.switchToEquipUi();
BAWK.play('ui_equip');
},
onSwitchTeamClicked: function () {
this.hideGameMenu();
BAWK.play('ui_popupopen');
this.$refs.switchTeamPopup.show();
},
onSwitchTeamCancel: function () {
this.showGameMenu();
},
onSwitchTeamConfirm: function () {
extern.switchTeam();
},
onControllerButton: function (e) {
switch (e.detail) {
case '9':
if (document.hasFocus() && !this.isRespawning && this.delayTheCracking) {
this.onPlayClicked();
}
break;
case '4':
case '6':
case '14':
vueData.classIdx = Math.max(0, vueData.classIdx - 1);
this.$refs.weaponSelect.selectClass(vueData.classIdx);
break;
case '5':
case '7':
case '15':
vueData.classIdx = Math.min(6, vueData.classIdx + 1);
this.$refs.weaponSelect.selectClass(vueData.classIdx);
break;
}
},
gaSendOnClassChange() {
if (!this.game.pauseScreen.wasGameInventoryOpen && this.game.pauseScreen.classChanged) {
ga('send', 'event', 'respawn-popup', 'classClick', Object.keys(CharClass).find(key => CharClass[key] === vueApp.classIdx));
}
// reset for good measure
this.game.pauseScreen.wasGameInventoryOpen = false;
this.game.pauseScreen.classChanged = false;
},
onPlayClicked: function () {
vueApp.disableRespawnButton(true);
vueData.ui.showCornerButtons = false;
extern.respawn();
this.isPaused = false;
BAWK.play('ui_playconfirm');
this.gaSendOnClassChange();
},
onSpectateClicked: function () {
this.gaSend('spectate');
this.hideGameMenu();
vueData.ui.showCornerButtons = false;
extern.enterSpectatorMode();
BAWK.play('ui_playconfirm');
},
showPlayerActionsPopup: function () {
this.hideGameMenu();
this.$refs.playerActionsPopup.show();
},
onPlayerActionsCancel: function () {
this.showGameMenu();
},
onMuteClicked: function () {
this.$refs.playerActionsPopup.hide();
this.playerActionsPopup.muteFunc();
},
onBootClicked: function () {
this.$refs.playerActionsPopup.hide();
this.playerActionsPopup.bootFunc();
},
resizeBannerAdTagForGame: function() {
const pauseAdPlacement = document.getElementById('pauseAdPlacement');
const rect = document.getElementById('pausePopup').getBoundingClientRect();
pauseAdPlacement.style.top = (rect.height).toString() + 'px';
},
earnInGameReward() {
this.hideGameMenu();
vueApp.setDarkOverlay(true);
this.pokiRewardReady = false;
this.isPokiNewRewardTimer = false;
extern.api_inGameReward(this.inGameRewardSuccessCallback, this.inGameRewardFailedCallback, this.rewardReachedDailyLimits);
extern.setVolume(0);
},
inGameRewardSuccessCallback() {
extern.pokiRewardedBreak(this.inGameRewardIsGranted, this.inGameRewardFailedCallback);
},
inGameRewardIsGranted(rewardValue) {
console.log('inGameRewardSuccessCallback');
this.isPokiNewRewardTimer = true;
vueApp.showGiveStuffPopup('reward_title', rewardValue, '');
ga('send', 'event', 'Poki', 'Rewarded Video', 'Reward Success', this.pokiRewNum);
this.pokiRewNum ++;
},
inGameRewardFailedCallback() {
vueApp.showGenericPopup('p_redeem_error_title', 'in_game_reward_try_again', 'ok');
this.isPokiNewRewardTimer = false;
ga('send', 'event', 'Poki', 'Rewarded Video', 'Failed');
},
rewardReachedDailyLimits() {
vueApp.showGenericPopup('in_game_reward_title', 'in_game_reward_try_again', 'ok');
this.isPokiNewRewardTimer = false;
localStore.setItem('inGameRewardLimitDate', Date.now());
extern.setVolume();
ga('send', 'event', 'Poki', 'Rewarded Video', 'Reached Daily Limit');
},
pokiTimers(value, milliseconds) {
let pokiSetTimer;
if (value === false) {
clearTimeout(pokiSetTimer);
console.log('cancelTimer');
return;
}
pokiSetTimer = setTimeout(() => this.pokiRewardReady = true, milliseconds);
},
pauseWeaponSelect() {
this.game.pauseScreen.wasGameInventoryOpen = false;
this.game.pauseScreen.classChanged = true;
vueApp.$refs.equipScreen.onChangedClass();
},
songHasChanged() {
setTimeout(() => this.songChanged = false , 2000);
},
// So crazy games requires an array for multiple display ad calls on the same screen
crazyAdsRespawn() {
if (!crazyGamesActive && !testCrazy) return;
// Removing delay per CG's request. Refresh rate is restricted server-side
/*if (this.cGrespawnBannerTimeout) return;
this.cGrespawnBannerTimeout = setTimeout(() => {
clearTimeout(this.cGrespawnBannerTimeout);
this.cGrespawnBannerTimeout = null;
}, 20000);*/
this.cGrespawnBannerErrors = 0;
crazysdk.requestBanner([{
containerId: 'shellshockers_respawn_banner-new_ad',
size: '728x90',
},{
containerId: 'shellshockers_respawn_banner_2_ad',
size: '300x250',
}]);
},
onClickCreator(url) {
window.open(url, )
},
openVipPopup() {
this.$refs.playerActionsPopup.hide();
vueApp.showSubStorePopup();
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'respawn-popup', 'click', label);
},
playIncentivizedAd(e) {
if (!this.chicknWinnerReady || this.hasChwPlayClicked || this.isChicknWinnerError) {
e.preventDefault();
return;
}
vueApp.disableRespawnButton(true);
this.hasChwPlayClicked = true;
vueApp.loadNuggetVideo();
vueApp.chicknWinnerNotReady();
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', 'click-in-game');
}
},
computed: {
isRespawning: function () {
return this.game.respawnTime > 0;
},
isTeamGame: function () {
// Would be better to use the same enum as the client game code
return this.game.gameType !== 0;
},
teamColorCss: function () {
return this.game.team === this.ui.team.blue ? 'blueTeam btn_red bevel_red' : 'redTeam btn_blue bevel_blue';
},
teamName: function () {
return this.game.team === this.ui.team.blue ? this.loc.p_pause_joinred : this.loc.p_pause_joinblue;
},
newTeamColorCss: function () {
return this.game.team === this.ui.team.blue ? 'redTeam btn_red' : 'blueTeam btn_blue';
},
newTeamName: function () {
return this.game.team === this.ui.team.blue ? this.loc.team_red : this.loc.team_blue;
},
muteButtonLabel: function () {
return this.playerActionsPopup.muted ? this.loc.ui_game_playeractions_unmute : this.loc.ui_game_playeractions_mute;
},
showIngameWidget() {
if (!this.isPaused && this.songChanged) {
this.songHasChanged();
return true;
}
return false;
},
showMusicWidget() {
return this.ui.showScreen === 2;
},
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '' && this.ui.showCornerButtons);
},
upgradeBadgeUrl() {
return this.isSubscriber ? 'img/vip-club/vip-club-popup-emblem.png' : 'img/ico_chickenBadge.png';
},
playerSocial() {
return SOCIALMEDIA[this.playerActionsPopup.social.id];
},
progressMsg() {
if (this.isChicknWinnerError) {
return this.loc.chw_error_text;
}
if (this.chicknWinnerDailyLimitReached && this.chicknWinnerCounter > 0) {
return this.loc.chw_daily_limit_msg;
}
if (this.chicknWinnerReady) {
if (this.chicknWinnerCounter === 0) {
return this.loc.chw_ready_msg;
} else {
return this.loc.chw_cooldown_msg;
}
} else {
return this.loc.chw_free_eggs_coming;
}
},
progressBarWrapClass() {
if (this.isChicknWinnerError) {
return 'chw-progress-bar-wrap-error';
}
if (this.chicknWinnerReady) {
return 'chw-progress-bar-wrap-complete';
}
},
playAdText() {
if (this.chicknWinnerReady && this.chicknWinnerCounter === 0) {
return this.loc.chw_btn_free_reward;
} else {
return this.loc.chw_btn_watch_ad;
}
},
chwShowCountdown() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'hideme';
} else {
if (this.chicknWinnerReady) {
return 'hideme';
} else {
return 'display-inline';
}
}
},
chwChickSrc() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'img/chicken-nugget/chickLoop_daily_limit.svg';
} else {
if (!this.chicknWinnerReady) {
return 'img/chicken-nugget/chickLoop_sleep.svg';
} else {
return 'img/chicken-nugget/chickLoop_speak.svg';
}
}
},
},
watch: {
isPokiGameLoad(value) {
this.pokiTimers(value, this.videoRewardTimers.initial);
// this.pokiTimers(value, 300);
},
isPokiNewRewardTimer(value) {
this.pokiTimers(value, this.videoRewardTimers.primary);
// this.pokiTimers(value, 300);
},
kname(val) {
this.killedByMessage = this.loc['ui_game_killedby'].format(val);
},
kdname(val) {
this.killedMessage = this.loc['ui_game_youkilled'].format(val);
},
}
};
</script>
<script id="vip-club-template" type="text/x-template">
<div class="vip-club fullwidth">
<div class="vip-club-log-content--outer roundme_sm display-grid grid-align-items-center grid-column-1-2 grid-gap-space-lg">
<header class="grid-span-2-start-1">
<!-- <h2><span class="text-orange">V</span>ery <span class="text-orange">I</span>mportant <span class="text-orange">P</span>oultry</h2> -->
<span class="sr-only">Very Important Poultry</span>
<img class="vip-club-water-mark display-block center_h" src="img/vip-club/very-important-poultry.png" alt="Very Important Poultry text image">
</header>
<div class="vip-club--logo">
<img src="img/vip-club/vip-club-popup-emblem.png">
</div>
<div class="vip-club--content">
<div class="subs-info">
<ul>
<li>{{loc.p_chicken_goldfeature1}}</li>
<li v-html="loc.p_chicken_goldfeature3"></li>
<li>{{loc.p_chicken_goldfeature2}}</li>
<li>{{loc.s_popup_feature_premium_items}}</li>
</ul>
<!-- <p class="more">{{loc.home_media_apply_now}}</p> -->
<button v-on:click="openVipPopup" class="margins_lg ss_button btn_sm btn_vip-button bevel_blue">{{loc.faq}}</button>
</div>
</div>
</div>
<div class="subscription-plans" :class="[hasPlan ? 'display-grid grid-column-1-2 grid-gap-space-lg' : '']">
<div class="vip-club-items--outer display-grid" :class="[hasPlan ? 'grid-column-1-eq grid-just-item-center' : 'grid-column-3-eq']">
<sub-item v-for="sub in subs" :key="sub.sku" :item="sub" :loc="loc" :upgrade-name="upgradeName" :is-subscriber="isSubscriber" :is-upgraded="isUpgraded" :account-set="accountSettled"></sub-item>
</div>
<div v-if="hasPlan" class="manage-subscription-wrapper">
<div v-if="hasPlan" class="plan-details text-center vip-club-log-content--outer roundme_sm">
<h5>{{loc.sRenewalDate}}:</h5>
<p v-if="expireDate" class="plan-expiry">{{ expireDate }}</p>
<p class="manage-details" v-html="manageInfo"></p>
<button class="ss_button btn_manage_sub btn_sm btn_yolk bevel_yolk btn_vip-button bevel_blue"" v-on:click="onManageClick">{{loc.sManageBtn}}</button>
</div>
</div>
</div>
</div>
</script>
<template id="comp-sub-item">
<div v-if="isActive" class="vip-item" :class="nameLowerCaseHyphens">
<div class="vip-item--inner centered">
<div class="subscription-details">
<header>
<h3>{{loc[name]}}</h3>
</header>
<p class="price-tag roundme_sm" v-html="priceTag"></p>
<button v-if="!hasSub" class="ss_button btn_sm btn_vip-button bevel_blue" v-on:click="subClick">
{{loc[buyBtnText]}}
</button>
</div>
</div>
<div v-if="flagText" class="vip-banner" :class="flagText">
<span>{{loc[flagText]}}</span>
</div>
<img aria-hidden="true" :src="img" />
</div>
</template>
<script>
const comp_sub_item = {
template: '#comp-sub-item',
props: ['loc', 'item', 'upgradeName', 'isUpgraded', 'isSubscriber'],
data() {
return {
isCurrentSub: false,
hasSub: false,
hasUpgrade: false,
locName: '',
};
},
methods: {
subClick() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
BAWK.play('ui_click');
if (this.hasSub) {
extern.buyProductForMoney();
} else {
extern.buyProductForMoney(this.item.sku, true);
ga('send', 'event', 'subscriptions', 'click', this.locName);
}
}
},
computed: {
nameLowerCaseHyphens() {
this.locName = this.item.name.replace(' ', '-').toLowerCase().replace(' ', '-');
return this.locName;
},
name() {
return `s-${this.locName}-title`;
},
img() {
return `img/vip-club/vip-club-popup-item-${this.locName}-bg.png`;
},
priceTag() {
let price = this.item.salePrice ? this.item.salePrice : this.item.price,
priceWcents = `${(price / 100).toFixed(2)}`,
thePrice = priceWcents.split('.');
return `$${thePrice[0]}<span class="price-tag--cents">.${thePrice[1]}</span>`;
},
buyBtnText() {
if (this.isCurrentSub && this.hasUpgrade) {
return 's-btn-txt-change';
}
return 's-btn-txt-subscribe';
},
isActive() {
if (this.isCurrentSub && this.hasUpgrade) {
return true
} else if (this.hasSub && this.hasUpgrade) {
return false
} else {
return true
};
},
flagText() {
if (this.isCurrentSub && this.hasUpgrade) return 'p_egg_shop_purchased';
return this.item.flagText;
}
},
watch: {
upgradeName(val) {
},
isUpgraded(val) {
this.hasUpgrade = val;
this.hasSub = this.isSubscriber && this.hasUpgrade;
this.isCurrentSub = this.upgradeName === this.item.name && this.hasUpgrade;
}
}
};
</script>
<script>
var compVipClubTemplate = {
template: '#vip-club-template',
components: {
'sub-item': comp_sub_item,
},
data() {
return vueData;
},
props: ['loc', 'subs'],
methods: {
onManageClick() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
extern.buyProductForMoney();
},
openVipPopup() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
BAWK.play('ui_click');
vueApp.showVipPopup();
}
},
computed: {
hasPlan() {
return this.isSubscriber && this.isUpgraded;
},
expireDate() {
if (this.hasPlan) {
return new Date(extern.account.upgradeExpiryDate).toUTCString();
}
return;
},
planName() {
if (this.hasPlan) {
return 's-' + this.upgradeName.replace(' ', '-').toLowerCase().replace(' ', '-') + '-title';
}
return;
},
manageInfo() {
return this.loc.sManageInfo;
}
}
};
</script><script id="give-stuff-popup" type="text/x-template">
<!-- Popup: Give Stuff -->
<!-- <large-popup id="giveStuffPopup" ref="giveStuffPopup" :popup-model="giveStuffPopup" @popup-closed="onSharedPopupClosed" :class="giveStuffPopup.type"> -->
<large-popup id="giveStuffPopup" ref="giveStuffPopup" :popup-model="giveStuffPopup" :class="giveStuffPopup.type">
<template slot="content">
<div id="giveStuffPopup-content" class="giveStuffPopup-content" :class="{'fullwidth' : giveStuffPopup.type === 'twitchDrops'}">
<div v-if="giveStuffPopup.type === 'vip'" id="give-stuff-icon" class="give-stuff-icon">
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Shell Shockers VIP">
</div>
<h3 v-if="giveStuffPopup.type !== 'twitchDrops'" :class="{'popup-title-vip' : giveStuffPopup.type === 'vip'}" id="popup_title" class="roundme_sm text-center">
{{ loc[giveStuffPopup.titleLoc] }}
</h3>
<h2 v-if="giveStuffPopup.type === 'twitchDrops'" id="popup_title" class="roundme_sm text-center title-shadow text-twitch-yellow">
{{ loc[giveStuffPopup.titleLoc] }}
</h2>
<p v-if="giveStuffPopup.type === 'twitchDrops'" class="text-center">{{ loc.give_stuff_twitch_sub_desc }}</p>
<div v-show="(giveStuffPopup.eggs)" class="f_row">
<div class="egg-give-stuff">
<img src="img/ico_goldenEgg.png" />
<h2>{{giveStuffPopup.eggs}}</h2>
</div>
</div>
<div v-show="giveStuffPopup.rickroll" class="f_row">
<img src="img/rickroll.gif" style="margin-bottom: 1em; height: 25em;" />
</div>
<div v-show="giveStuffPopup.eggOrg" class="f_row">
<img src="img/egg-org/eggOrg_timeTravel_splash800x600-min.png" style="margin-bottom: 1em;">
</div>
<div v-show="(giveStuffPopup.items && giveStuffPopup.items.length > 0)" class="items-container f_row grid-gap-1" :class="{'popup-items-vip' : giveStuffPopup.type === 'vip'}">
<item v-for="i in giveStuffPopup.items" :item="i" :key="i.id" :isSelected="false" :show-item-only="true"></item>
</div>
<p v-if="giveStuffPopup.type === 'twitchDrops'"></p>
</div>
<footer :class="{'text-center' : giveStuffPopup.type === 'twitchDrops'}">
<!-- <p v-if="giveStuffPopup.type === 'twitchDrops'" class="text-center">{{ loc.give_stuff_twitch_footer_desc }}</p> -->
<button class="ss_button width_xs text-center" :class="giveStuffPopup.type === 'twitchDrops' ? 'twitch-btn twitch-btn-purple' : 'btn_green bevel_green'" @click="onGiveStuffComplete">{{ loc.ok }}</button>
<button v-if="giveStuffPopup.type === 'twitchDrops'"class="ss_button twitch-btn twitch-btn-pink width_xs text-center" @click="onClickTwitchDropsMore">Get More!</button>
</footer>
</template>
<template slot="confirm">{{ loc.confirm }}</template>
</large-popup>
</script>
<script>
const GIVESTUFFPOPUP = {
template: '#give-stuff-popup',
components: {
'item': comp_item,
},
props: ['loc', 'giveStuffPopup'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
eggBalance: 0,
vueData,
}
},
methods: {
onGiveStuffComplete: function () {
this.giveStuffPopup.eggOrg = false;
this.giveStuffPopup.rickroll = false;
this.$refs.giveStuffPopup.toggle();
},
onClickTwitchDropsMore() {
window.open(dynamicContentPrefix + 'twitch');
this.onGiveStuffComplete();
}
},
};
</script>
<script>
function startVue(languageCode, locData) {
vueData.extern = extern;
vueData.loc = locData;
vueApp = new Vue({
el: '#app',
components: {
'dark-overlay': comp_dark_overlay,
'light-overlay': comp_light_overlay,
'spinner-overlay': comp_spinner_overlay,
'gdpr': comp_gdpr,
'settings': comp_settings,
'help': comp_help,
'vip-help': vip_help,
'egg-store': comp_egg_store,
'subscription-store': compVipClubTemplate,
// 'subscription-store': comp_egg_store,
'item': comp_item,
'home-screen': comp_home_screen,
'equip-screen': comp_equip_screen,
'game-screen': comp_game_screen,
// 'gold-chicken-popup': comp_gold_chicken_popup,
'chicken-nugget-popup': comp_chickn_winner_popup,
'egg-store-item': comp_store_item,
'give-stuff-popup': GIVESTUFFPOPUP,
},
data: vueData,
createdTime: null,
mountedTime: null,
fullyRenderedTime: null,
multisizeAdTag: null,
created () {
console.log('Vue instance created');
createdTime = performance.now();
this.currentLanguageCode = languageCode;
this.urlParams = parsedUrl.query.open ? parsedUrl.query.open : null;
},
mounted () {
console.log('Vue instance mounted');
mountedTime = performance.now();
console.log('create -> mount time (ms): ' + (mountedTime - createdTime));
this.currentGameType = extern.gameType;
// Cannot modify data within the mounted hook, so wait until next tick
this.$nextTick(function () {
fullyRenderedTime = performance.now();
console.log('mounted -> fully rendered time (ms): ' + (fullyRenderedTime - mountedTime));
console.log('created -> fully rendered time (ms): ' + (fullyRenderedTime - createdTime));
this.ready = true;
// vueApp.getNuggetTimer();
//this.showSpinner('ui_game_loading', 'ui_game_waitforit');
// this.histPushState({game: this.ui.screens.home}, 'Shellshockers home', '?home');
//this.playMusic();
this.getLocLang();
extern.continueStartup();
this.changelog.current = changeLogData;
//this.fetchSponsors();
});
},
methods: {
getCanvas: function () {
return this.$refs.canvas;
},
playMusic: function () {
myAudio = new Audio('./sound/theme');
// Uncomment for looping.
// myAudio.addEventListener('ended', function() {
// this.currentTime = 0;
// this.play();
// }, false);
myAudio.volume = this.volume;
myAudio.play();
},
changeLanguage: function (languageCode) {
extern.getLanguageData(languageCode, this.setLocData);
},
setLocData: function (languageCode, newLocData) {
this.currentLanguageCode = getStoredString('languageSelected', null) ? localStore.getItem('languageSelected') : languageCode;
this.loc = newLocData;
},
setPlayerName: function (playerName) {
this.playerName = playerName.substring(0, 128);
},
showSpinner: function (headerLocKey, footerLocKey) {
this.$refs.spinnerOverlay.show(headerLocKey, footerLocKey);
},
showSpinnerLoadProgress: function (percent) {
this.$refs.spinnerOverlay.showSpinnerLoadProgress(percent);
},
hideSpinner: function () {
this.$refs.spinnerOverlay.hide();
},
onSettingsPopupOpened: function () {
this.$refs.settings.captureOriginalSettings();
},
onSettingsPopupSwitchTabMisc: function () {
this.$refs.settings.switchTab('misc_button');
},
onSettingsX: function () {
this.$refs.settings.applyOriginalSettings();
this.$refs.settings.cancelLanguageSelect();
},
onSettingsQuickSave() {
this.$refs.settings.quickSave();
},
onNoAnonPopupConfirm: function () {
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.denyAnonUserPopup, this.googleAnalytics.label.signInClick);
this.showFirebaseSignIn();
},
onSharedPopupClosed: function () {
// If in-game, show game menu after closing the popup
this.blackFridayBanner = false;
if (this.ui.showScreen === this.ui.screens.game && extern.inGame) {
this.showGameMenu();
}
},
onGiveStuffComplete: function () {
this.$refs.giveStuffPopup.toggle();
},
onPrivacyOptionsOpened: function () {
this.showPrivacyPopup();
},
/**
* Creates a generic popup that passes content 3 data options to slots on the genericPopup smallPopup
* @param titleLockKey mixed - popup header text
* @param contentLocKey mixed- popup content
* @param confirmLocKey mixed - popup button text
*/
showGenericPopup: function (titleLocKey, contentLocKey, confirmLocKey, hideBackgroundPopup) {
this.genericMessagePopup.titleLocKey = titleLocKey;
this.genericMessagePopup.contentLocKey = contentLocKey;
this.genericMessagePopup.confirmLocKey = confirmLocKey;
this.hidePausePopupIfGenericPopupOpen();
this.$refs.genericPopup.show();
// vueApp.setDarkOverlay();
},
hidePausePopupIfGenericPopupOpen: function() {
if (!this.$refs.gameScreen.$refs.pausePopup && $refs.gameScreen.$refs.pausePopup.isShowing === false) {
return;
}
return this.$refs.gameScreen.$refs.pausePopup.hide();
},
showOpenUrlPopup: function (url, titleLocKey, content, confirmLocKey, cancelLocKey) {
console.log('title: ' + this.loc[titleLocKey]);
console.log('confirm: ' + this.loc[confirmLocKey]);
console.log('cancel: ' + this.loc[cancelLocKey]);
this.openUrlPopup.url = url;
this.openUrlPopup.titleLocKey = titleLocKey;
this.openUrlPopup.content = content;
this.openUrlPopup.confirmLocKey = confirmLocKey;
this.openUrlPopup.cancelLocKey = cancelLocKey;
this.$refs.openUrlPopup.show();
},
onOpenUrlPopupConfirm: function () {
extern.openUrlAndGiveReward();
},
showUnsupportedPlatformPopup: function (contentLocKey) {
this.ui.showScreen = -1;
this.unsupportedPlatformPopup.contentLocKey = contentLocKey;
this.$refs.unsupportedPlatformPopup.show();
},
showMissingFeaturesPopup: function () {
this.ui.showScreen = -1;
this.$refs.missingFeaturesPopup.show();
},
showFirebaseSignIn: function () {
this.$refs.homeScreen.showSignIn();
},
hideFirebaseSignIn: function () {
this.$refs.firebaseSignInPopup.hide();
},
showCheckEmail: function () {
this.$refs.homeScreen.$refs.checkEmailPopup.show();
},
hideCheckEmail: function () {
this.$refs.homeScreen.$refs.checkEmailPopup.hide();
},
showResendEmail: function () {
this.$refs.homeScreen.$refs.resendEmailPopup.show();
},
hideResendEmail: function () {
this.$refs.homeScreen.$refs.resendEmailPopup.hide();
},
showChickenPopup: function () {
this.$refs.goldChickenPopup.show();
},
hideChickenPopup: function () {
this.$refs.goldChickenPopup.hide();
},
showHelpPopup: function () {
this.hideGameMenu();
this.$refs.helpPopup.show();
},
showVipPopup: function () {
this.hideGameMenu();
BAWK.play('ui_popupopen');
this.$refs.vipPopup.show();
},
showGetMobilePopup() {
this.$refs.mobileAdPopup.show();
},
showAttentionPopup: function () {
this.hideGameMenu();
this.$refs.anonWarningPopup.show();
},
hideHelpPopup: function () {
this.$refs.helpPopup.hide();
},
showSettingsPopup: function () {
this.hideGameMenu();
this.$refs.settingsPopup.show();
extern.settingsMenuOpened();
},
hideSettingsPopup: function () {
this.$refs.settingsPopup.hide();
},
showEggStorePopup: function () {
this.$nextTick(() => {
this.hideGameMenu();
this.$refs.eggStorePopup.show();
if (this.isSale) {
this.blackFridayBanner = true;
}
ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup, this.googleAnalytics.label.getMoreEggs);
});
},
showSubStorePopup: function () {
this.$nextTick(() => {
this.hideGameMenu();
this.$refs.subStorePopup.show();
BAWK.play('ui_popupopen');
// ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup, this.googleAnalytics.label.getMoreEggs);
});
},
vipEndedPopup() {
this.$refs.vipEnded.show();
BAWK.play('ui_popupopen');
},
showPopupEggStoreSingle(sku) {
if (!sku) {
console.log('No sku for popup');
return;
}
if (!this.premiumShopItems.some( i => i.sku === sku)) {
vueApp.showGenericPopup("uh_oh", "p_egg_shop_no_item_desc", "ok");
return;
}
this.eggStorePopupSku = sku;
this.$refs.popupEggStoreSingle.show();
},
hideEggStorePopup: function () {
this.$refs.eggStorePopup.hide();
},
showChangelogPopup: function () {
this.$refs.changelogPopup.show();
},
showHistoryChangelogPopup() {
fetch('./changelog/oldChangelog.json', {cache: "no-cache"})
.then(response => response.json())
.then(data => {
data.forEach(el => this.changelog.current.push(el));
});
this.changelog.showHistoryBtn = false;
},
hideChangelogPopup: function () {
this.$refs.changelogPopup.hide();
},
showGiveStuffPopup: function (titleLoc, eggs, items, type, callback) {
if (this.giveStuffPopup.eggOrg) {
ga('send', 'event', 'Egg Org', 'Code Cracked', 'redeemed');
}
type = type || '';
this.giveStuffPopup.titleLoc = titleLoc;
this.giveStuffPopup.eggs = eggs;
this.giveStuffPopup.items = items;
this.giveStuffPopup.type = type;
this.$refs.giveStuffPopup.$refs.giveStuffPopup.show();
if (callback) callback();
},
showEggOrgPopup() {
this.giveStuffPopup.eggOrg = true;
this.showGiveStuffPopup('p_give_stuff_title');
},
showShareLinkPopup: function (url) {
this.hideGameMenu();
this.game.shareLinkPopup.url = url;
this.$refs.gameScreen.$refs.shareLinkPopup.show();
},
hideShareLinkPopup() {
if (!this.$refs.gameScreen.$refs.shareLinkPopup.isShowing) {
return;
}
this.$refs.gameScreen.$refs.shareLinkPopup.hide();
},
showJoinPrivateGamePopup: function (code) {
this.$refs.homeScreen.$refs.playPanel.showJoinPrivateGamePopup(code);
},
showPrivateGamePopup() {
this.$refs.homeScreen.$refs.playPanel.$refs.createPrivateGamePopup.toggle();
},
switchToHomeUi: function () {
this.ui.showScreen = this.ui.screens.home;
// vueApp.showTitleScreenAd();
// this.histPushState({game: this.ui.screens.home}, 'Shellshockers home', '?home');
this.gameUiRemoveClassForNoScroll();
extern.chwRadialProgress();
},
switchToEquipUi: function () {
console.log('switchToEquipUi called');
this.ui.showScreen = this.ui.screens.equip;
this.$refs.equipScreen.setup();
this.$refs.equipScreen.switchToInventory();
if (extern.inGame) {
this.hideGameMenu();
extern.openEquipInGame();
}
else {
vueApp.hideTitleScreenAd();
}
},
switchToGameUi: function (isGameOwner) {
this.ui.showScreen = this.ui.screens.game;
this.game.isGameOwner = isGameOwner;
},
gameUiAddClassForNoScroll() {
let html = document.getElementsByTagName("html")[0];
html.classList.add('noScrollIngame');
},
gameUiRemoveClassForNoScroll() {
let html = document.getElementsByTagName("html")[0];
html.classList.remove('noScrollIngame');
},
switchToGameUiQuickPlay(isGameOwner) {
this.ui.showScreen = this.ui.screens.game;
this.game.isGameOwner = isGameOwner;
this.ui.showCornerButtons = false;
vueApp.hideTitleScreenAd();
this.gameUiAddClassForNoScroll();
},
showGameMenu: function () {
this.hideSpinner();
this.$refs.gameScreen.showGameMenu();
// this.histPushState({game: this.ui.screens.game}, 'Shellshockers game menu', '?game=menu');
},
hideGameMenu: function () {
this.$refs.gameScreen.hideGameMenu();
// this.histPushState({game: this.ui.screens.game}, 'Shellshockers in game', '?game=play');
},
onMiniGameCompleted: function () {
this.$refs.homeScreen.onMiniGameCompleted();
},
setShellColor: function (colorIdx) {
this.equip.colorIdx = colorIdx;
},
setAccountUpgraded: function (upgraded, endDate) {
this.isUpgraded = upgraded;
this.equip.extraColorsLocked = !this.isUpgraded;
this.nugStart = endDate;
},
setDarkOverlay: function (visible, overlayClass) {
this.$refs.darkOverlay.show = visible;
this.$refs.darkOverlay.overlayClass = overlayClass;
},
setLightOverlay: function (visible, overlayClass) {
this.$refs.lightOverlay.show = visible;
this.$refs.darkOverlay.overlayClass = overlayClass;
},
authCompleted: function () {
this.accountSettled = true;
if (vueApp.$refs.firebaseSignInPopup.isShowing) this.hideFirebaseSignIn();
},
showItemOnEquipScreen: function (item) {
this.switchToEquipUi();
this.$refs.equipScreen.autoSelectItem(item);
},
showTaggedItemsOnEquipScreen: function (tag) {
this.switchToEquipUi();
this.$refs.equipScreen.showTaggedItems(tag);
},
showSelectedTaggedItemsOnEquipScreen: function (tag) {
this.switchToEquipUi();
this.$refs.equipScreen.showSelectedTagItems(tag);
},
useHouseAdSmall: function (smallHouseAd) {
this.ui.houseAds.small = smallHouseAd;
},
useHouseAdBig: function (bigHouseAd) {
this.ui.houseAds.big = bigHouseAd;
},
denyAnonUser: function () {
ga('send', 'event', vueApp.googleAnalytics.cat.playerStats, vueApp.googleAnalytics.action.denyAnonUserPopup);
if (extern.inGame) {
this.hideGameMenu();
}
this.$refs.noAnonPopup.show();
},
showGdprNotification: function () {
this.$refs.gdpr.show();
},
showPrivacyPopup: function () {
this.hideSettingsPopup();
this.$refs.privacyPopup.show();
},
hidePrivacyPopup: function () {
this.$refs.privacyPopup.hide();
this.showSettingsPopup();
},
ofAgeChanged: function () {
extern.setOfAge(this.isOfAge);
BAWK.play('ui_onchange');
},
targetedAdsChanged: function () {
extern.setTargetedAds(this.showTargetedAds);
BAWK.play('ui_onchange');
},
setPrivacySettings: function (ofAge, targetedAds) {
this.isOfAge = ofAge;
this.showTargetedAds = targetedAds;
},
gameJoined: function (gameType, team) {
this.game.gameType = gameType;
this.setTeam(team);
},
setTeam: function (team) {
if (hasValue(team)) {
this.game.team = team;
}
},
showGoldChickenPopup: function () {
this.$refs.goldChickenPopup.show();
},
hideGoldChickenPopup: function () {
this.$refs.goldChickenPopup.hide();
},
showChicknWinnerPopup: function () {
this.$refs.chicknWinner.show();
vueApp.$refs.chickenNugget.showAd();
// this.$refs.chickenNugget.loadMiniGame();
this.isBuyNugget = true;
console.log('showChicknWinnerPopup()');
},
hideChicknWinnerPopup: function () {
this.$refs.chicknWinner.hide();
this.$refs.chickenNugget.onGotWinner();
console.log('Hide nugget');
},
chicknWinnerIsReady() {
if (this.chicknWinnerDailyLimitReached) {
this.chicknWinnerNotReady();
return;
}
setTimeout(() => {
this.chicknWinnerReady = true;
this.hasChwPlayClicked = false;
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', `ready-in-${(this.ui.showScreen === this.ui.screens.game) ? 'game' : 'home'}`);
}, 1000);
},
chicknWinnerNotReady() {
this.chicknWinnerReady = false;
this.hasChwPlayClicked = false;
},
chicknWinnerError() {
this.isChicknWinnerError = true;
},
chicknWinnerDailyLimit() {
this.chicknWinnerDailyLimitReached = true;
this.chicknWinnerNotReady();
},
loadNuggetVideo() {
this.hideGameMenu();
extern.checkStartChicknWinner(true);
BAWK.play('ui_playconfirm');
},
getNuggetTimer() {
return;
this.$refs.homeScreen.$refs.chickenPanel.setupNuggetTimer();
},
onMiniGameCompleted: function () {
this.$refs.chickenNugget.onMiniGameCompleted();
},
placeBannerAdTagForNugget: function (tagEl) {
this.$refs.chickenNugget.placeBannerAdTag(tagEl);
},
useSpecialItemsTag: function (tag) {
this.equip.specialItemsTag = tag;
this.equip.showSpecialItems = true;
},
disableSpecialItems: function () {
this.equip.showSpecialItems = false;
},
setUiSettings: function (settings) {
this.$refs.settings.setSettings(settings);
},
leaveGame: function () {
this.$refs.gameScreen.leaveGame();
},
showPlayerActionsPopup: function (slot) {
this.playerActionsPopup = slot;
this.$refs.gameScreen.showPlayerActionsPopup();
},
onSignInCancelClicked: function () {
vueApp.$refs.firebaseSignInPopup.hide();
BAWK.play('ui_popupclose');
},
anonWarningPopupCancel: function() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
this.urlParamSet = this.urlParams ? true : null;
this.shellShockUrlParamaterEvents();
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto, this.googleAnalytics.label.understood);
return anonWarnConfrimed === null && localStore.setItem('anonWarningConfirmed', true);
},
anonWarningPopupConfrim() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
anonWarnConfrimed === null && localStore.setItem('anonWarningConfirmed', true);
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto, this.googleAnalytics.label.signInClick);
extern.showSignInDialog();
this.urlParamSet = false;
vueApp.$refs.firebaseSignInPopup.show();
},
conditionalAnonWarningCall: function() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
if ( ! hasValue(anonWarnConfrimed) && this.isAnonymous) {
vueApp.showAttentionPopup();
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto);
}
},
needMoreEggsPopupCall: function() {
ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup);
this.$refs.needMoreEggsPopup.show();
},
/**
* Not 100 % certain this should live in vue but here it is.
* Add the ability to use url paramaters to trigger events in the game.
* e.g. shellshock.io/?open=eggStore&type=Hat&item=1111 will open the spiderman hat item.
* Called in the extern closure under gameApp.js => afterGameReady()
*/
shellShockUrlParamaterEvents() {
// VUE next tick https://vuejs.org/v2/api/#Vue-nextTick
this.$nextTick( ()=> {
this.doSsUlrParams();
});
},
doSsUlrParams() {
if ( ! this.urlParams) {
return;
}
console.log(hasValue(this.isAnonymous));
if (hasValue(this.ui.houseAds.big)) {
this.urlParamSet = false;
return;
} else if (this.isAnonymous && ! hasValue(localStore.getItem('anonWarningConfirmed'))) {
this.urlParamSet = false;
console.log('Almost there!');
this.conditionalAnonWarningCall();
return;
}
console.log('Passed Popup gate');
switch (this.urlParams) {
case 'eggStore' :
// Opens the purchase egg store popup
this.showEggStorePopup();
break;
case 'goldenChicken' :
// Opens the golden chicken popup
vueApp.$refs.goldChickenPopup.show();
break;
case 'twoTimesTheEggs' :
// Opens the chicken nugget video
extern.checkStartChicknWinner(true);
BAWK.play('ui_playconfirm');
break;
case 'itemShop' :
// Opens shop options
// /?open=itemShop
// /?open=itemShop&type=Hat/Stamp/Primary/Secondary/Grenade/Premium/Tagged
// /?open=itemShop&gunClass=Soldier/Soldier/Scrambler/Ranger/Eggsploder/Whipper/Crackshot/TriHard
// /?open=itemShop&item=1111 opens hat store and then selects item
// /?open=itemShop&item=1111&openBuyNow=1 opens hat store, selects item and then opens items popup
this.eggStoreUrlParams();
break;
case 'vipStore' :
vueApp.showSubStorePopup();
break;
case 'redeem' :
vueApp.switchToEquipUi();
BAWK.play('ui_popupopen');
this.$refs.equipScreen.$refs.redeemCodePopup.show();
if ('code' in parsedUrl.query) this.equip.redeemCodePopup.code = parsedUrl.query.code;
break;
case 'faq' :
this.showHelpPopup();
break;
case 'taggedItems' :
this.openSpecialTagItemsTab();
break;
case 'privateGame' :
this.showPrivateGamePopup();
break;
case 'kotcInstruction' :
this.showKotcInstrucPopup();
break;
default:
null;
};
},
eggStoreUrlParams() {
setTimeout(() => {
const ITEMIDPARAM = parsedUrl.query.hasOwnProperty('item') ? parsedUrl.query.item : '',
TYPEPARAM = parsedUrl.query.hasOwnProperty('type') ? parsedUrl.query.type : '',
GUNCLASS = parsedUrl.query.hasOwnProperty('gunClass') && CharClass.hasOwnProperty(parsedUrl.query.gunClass) ? parsedUrl.query.gunClass : '',
BUYNOWPOPUP = parsedUrl.query.hasOwnProperty('openBuyNow');
if (ITEMIDPARAM) {
const IDISNUMBER = parseInt(ITEMIDPARAM);
let item = extern.catalog.findItemById(IDISNUMBER);
if (!item.is_available) {
vueApp.showGenericPopup("uh_oh", "no_anon_title", "ok")
return;
}
this.switchToEquipUi();
this.$refs.equipScreen.autoSelectItem(item);
if (BUYNOWPOPUP === true) {
console.log('Will it open?');
vueApp.$refs.equipScreen.onBuyItemClicked();
return;
}
} else {
this.openEquipUISwitchToShop();
if (GUNCLASS) {
vueApp.$refs.equipScreen.switchItemType(ItemType['Primary']);
vueApp.$refs.equipScreen.$refs.weapon_select.selectClass(CharClass[GUNCLASS]);
console.log('Has GUN');
} else if (TYPEPARAM) {
console.log('OPEN item');
if (ItemType.hasOwnProperty(TYPEPARAM)) {
vueApp.$refs.equipScreen.switchItemType(ItemType[TYPEPARAM]);
} else {
if (TYPEPARAM === 'Premium') {
vueApp.$refs.equipScreen.onPremiumItemsClicked();
} else if (TYPEPARAM === 'Tagged') {
vueApp.$refs.equipScreen.onTaggedItemsClicked();
}
}
}
}
}, 45);
},
openSpecialTagItemsTab() {
let tag = parsedUrl.query.tag ? parsedUrl.query.tag : null;
vueApp.showSelectedTaggedItemsOnEquipScreen(tag);
},
openEquipUISwitchToShop() {
vueApp.switchToEquipUi();
vueApp.$refs.equipScreen.switchToShop();
},
delayInGamePlayButtons() {
vueApp.$refs.gameScreen.delayGameMenuPlayButtons();
},
//Call/hide display ads
hideRespawnDisplayAd() {
this.$refs.gameScreen.$refs.respawnDisplayAd.hide();
this.$refs.gameScreen.$refs.respawnTwoDisplayAd.hide();
},
showRespawnDisplayAd() {
this.$refs.gameScreen.$refs.respawnDisplayAd.show();
this.$refs.gameScreen.$refs.respawnTwoDisplayAd.show();
},
hideLoadingScreenAd() {
this.$refs.spinnerOverlay.$refs.loadingScreenDisplayAd.hide()
},
showLoadingScreenAd() {
this.$refs.spinnerOverlay.$refs.loadingScreenDisplayAd.show();
// this.histPushState({game: 3}, 'Shellshockers Loading display ad', '?loadingAd=true');
},
displayAdEventObject(event) {
let object = event;
this.displayAdObject = object.size[0];
},
showTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.show();
},
hideTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.hide();
},
toggleTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.toggleAd();
},
scrollToTop() {
let position =
document.body.scrollTop || document.documentElement.scrollTop,
scrollAnimation;
if (position) {
window.scrollBy(0, -Math.max(1, Math.floor(position / 10)));
scrollAnimation = setTimeout(this.scrollToTop, 10);
} else clearTimeout(scrollAnimation);
},
externPlayObject(playType, gameType, playerName, mapIdx, joinCode) {
return extern.play({playType, gameType, playerName, mapIdx, joinCode});
},
pleaseWaitPopup() {
vueApp.showGenericPopup("signin_auth_title", "signin_auth_msg");
},
isPlayingPoki() {
this.isPoki = true;
this.ready = true;
return;
},
histPushState(obj, title, param) {
return history.pushState(obj, title, param);
},
disablePlayButton(val) {
return document.querySelector('.play-button').disabled = val;
},
disableRespawnButton(val) {
return document.querySelector('.btn-respawn') ? document.querySelector('.btn-respawn').disabled = val : '';
},
disaplyAdEventObject(event) {
this.displayAdObject = event.size === null ? null : event.size[0];
},
adBlockerPopupToggle() {
return vueApp.$refs.adBlockerPopup.toggle();
},
musicPlayOnce() {
return setTimeout(() => this.$refs.gameScreen.$refs.gameScreenMusic.playOnce(), 2000);
},
musicPause() {
this.$refs.gameScreen.$refs.gameScreenMusic.pause();
},
musicVolumeControl(value) {
return;
this.settingsUi.adjusters.music[0].value = Number(value);
this.$refs.gameScreen.$refs.gameScreenMusic.loadVolume();
},
toggleMusic() {
this.$refs.gameScreen.$refs.gameScreenMusic.toggleMusic();
},
musicWidget(val) {
this.music.isMusic = val;
},
fetchSponsors() {
fetch(this.music.musicJson)
.then((response) => response.json())
.then((sponsors) => this.music.sponsors = sponsors)
.catch((error) => console.log('Sponsors fetch error', error));
},
pwaPopup() {
return this.$refs.pwaPopup.show();
},
pwaBtnClick() {
// Track the click
ga('send', 'event', 'pwa', 'button', 'click');
//close popup
this.$refs.pwaPopup.hide();
// Get the event
this.pwaDeferEvent = extern.getPwaEvent;
if (!this.pwaDeferEvent) {
return;
}
this.pwaDeferEvent.prompt();
this.pwaDeferEvent.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
ga('send', 'event', 'pwa', 'a2hs', choiceResult.outcome);
this.pwaDeferEvent = null;
});
this.pwaDeferEvent = '';
},
signOut() {
this.isUpgraded = false;
this.equip.extraColorsLocked = true;
this.isUpgraded = false;
this.upgradeName = '';
this.isSubscriber = false;
},
mediaTabsStartRotate() {
return this.$refs.homeScreen.$refs.mediaTabs.autoRotateTabs();
},
mediaTabsCancelRotate() {
return this.$refs.homeScreen.$refs.mediaTabs.cancelRotate(true);
},
showAdBlockerVideo() {
this.bannerHouseAd = extern.getHouseAd('bigBanner');
this.showAdBlockerVideoAd = true;
this.hideGameMenu();
this.$refs.adBlockerVideo.show();
},
hideAdBlockerVideo() {
this.$refs.adBlockerVideo.hide();
if (extern.inGame) {
this.showGameMenu();
}
this.bannerHouseAd = {};
this.showAdBlockerVideoAd = false;
},
showKotcInstrucPopup() {
this.$refs.kotcInstrucPopup.show();
},
kotcInstrucPopupHide() {
this.$refs.kotcInstrucPopup.hide();
},
onClickPlayKotcNow() {
this.externPlayObject(vueData.playTypes.joinPublic, 3, this.playerName, '', '');
this.kotcInstrucPopupHide();
},
onVipHelpClosed() {
this.onSharedPopupClosed();
this.showSubStorePopup();
},
getLocLang(val) {
let data = this.loc,
langSetup = {};
if (val) data = val;
const newLoc = Object.entries(data).filter(item => item[0].includes('locLang')).forEach(lang => langSetup[lang[0].split('_').pop('').split("-").pop('')] = lang[1]);
this.$nextTick(() => {
this.locLanguage = langSetup
});
},
onClickTwitchDropsMore() {
window.open(dynamicContentPrefix + 'twitch');
this.onGiveStuffComplete();
},
onPremiumItemsClicked() {
this.openEquipUISwitchToShop();
this.$refs.equipScreen.onPremiumItemsClicked();
}
},
computed: {
portalClass() {
return {
'playing-poki': this.isPoki,
'playing-crazy-games': crazyGamesActive,
'is-vip': this.isSubscriber && this.isUpgraded ? true : false,
}
},
bigBannerAdLink() {
return this.bigHouseAd.link
},
bigBannerAdImg() {
return dynamicContentPrefix + `data/img/art/${this.bigHouseAd.id}${this.bigHouseAd.imageExt}`;
}
},
watch : {
loc(val) {
this.getLocLang(val);
},
}
});
}
</script>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"719d075cbaa072b4","token":"b4cd973aeca34b509bef2ed0c9e0b720","version":"2021.12.0","si":100}' crossorigin="anonymous"></script>
</body>
</html>
</script><!-- include_once('./includes/shared_tags/inc_tag_asc_video_player.php'); -->
<script id="language-selector-template" type="text/x-template">
<select id="pickLanguage" v-model="languageCode" @change="onChangeLanguage" class="ss_select ss_marginright_sm">
<option v-for="(language, code) in langOptions" v-bind:value="code">
{{ language }}
</option>
</select>
</script>
<script>
var comp_language_selector = {
template: '#language-selector-template',
props: ['languages', 'selectedLanguageCode', 'loc', 'langOptions'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onChangeLanguage: function () {
vueApp.changeLanguage(this.languageCode);
// Update localStore for selected language.
localStore.setItem('languageSelected', this.languageCode);
BAWK.play('ui_onchange');
ga('send', 'event', {
eventCategory: vueData.googleAnalytics.cat.playerStats,
eventAction: vueApp.googleAnalytics.action.languageSwitch,
eventLabel: this.languageCode,
});
}
},
watch: {
selectedLanguageCode: function (code) {
this.languageCode = code;
}
}
};
</script><script id="gdpr-template" type="text/x-template">
<transition name="fade">
<div v-show="isShowing">
<div id="consent" v-show="showingNotification" class="gdpr_banner f_row">
<div>{{ loc.gdpr_notification }} <a href="http://www.bluewizard.com/privacypolicy" target="_window">{{ loc.gdpr_link }}</a>
</div>
<div class="f_row">
<button @click="onDisagreeClicked()" class="ss_button btn_red bevel_red ss_marginright ss_marginleft">{{ loc.gdpr_disagree }}</button>
<button @click="onAgreeClicked()" class="ss_button btn_green bevel_green">{{ loc.gdpr_agree }}</button>
</div>
</div>
<div id="doConsent" v-show="showingConsent" class="gdpr_banner f_row">
<div>{{ loc.gdpr_consent }}</div>
<div>
<button @click="close()" class="ss_button btn_green bevel_green btn_md">{{ loc.ok }}</button>
</div>
</div>
<div id="noConsent"v-show="showingNoConsent" class="gdpr_banner f_row">
<div>{{ loc.gdpr_noConsent }}</div>
<div>
<button @click="close()" class="ss_button btn_green bevel_green btn_md">{{ loc.ok }}</button>
</div>
</div>
</div>
</transition>
</script>
<script>
var comp_gdpr = {
template: '#gdpr-template',
props: ['loc'],
data: function () {
return {
isShowing: false,
showingNotification: false,
showingConsent: false,
showingNoConsent: false
}
},
methods: {
show: function () {
this.isShowing = true;
this.showingNotification = true;
this.showingConsent = false;
this.showingNoConsent = false;
},
close: function () {
this.isShowing = false;
BAWK.play('ui_playconfirm');
},
onAgreeClicked: function () {
this.showingConsent = true;
this.showingNotification = false;
extern.doConsent();
BAWK.play('ui_onchange');
},
onDisagreeClicked: function () {
this.showingNoConsent = true;
this.showingNotification = false;
extern.doNotConsent();
BAWK.play('ui_onchange');
}
}
};
</script>
<script id="settings-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_settings_title }}</h1>
<div id="horizontalTabs">
<button id="keyboard_button" @click="selectTab" class="ss_bigtab bevel_blue ss_marginright" :class="(showKeyboardTab ? 'selected' : '')"><img src="img/ico_keyboard.svg" class="ss_bigtab_icon"> <img src="img/ico_mouse.svg" class="ss_bigtab_icon"></button>
<button id="controller_button" @click="selectTab" class="ss_bigtab bevel_blue ss_marginright" :class="(showControllerTab ? 'selected' : '')"><img src="img/ico_gamepad.svg" class="ss_bigtab_icon"></button>
<button id="misc_button" @click="selectTab" class="ss_bigtab bevel_blue" :class="(showMiscTab ? 'selected' : '')"><img src="img/ico_monitor.svg" class="ss_bigtab_icon"> <img src="img/ico_speaker.svg" class="ss_bigtab_icon"> <img src="img/ico_privacy.svg" class="ss_bigtab_icon"></button>
</div>
<div id="popupInnards" class="roundme_sm fullwidth f_col ss_margintop_sm ss_marginbottom_xl">
<div id="settings_keyboard" v-show="showKeyboardTab">
<h3 class="nospace">{{ loc.p_settings_keybindings }}</h3>
<div class="f_row ss_margintop">
<div class="f_col">
<div v-for="c in settingsUi.controls.keyboard.game" v-if="c.side == 'left'" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGameControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
<div class="ss_margintop_xl">
<div v-for="c in settingsUi.controls.keyboard.spectate" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onSpectateControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
</div>
<div class="f_col ss_marginleft_xl">
<div v-for="c in settingsUi.controls.keyboard.game" v-if="c.side == 'right'" class="nowrap">
<settings-control-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGameControlCaptured"></settings-control-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
<div class="ss_margintop">
<div v-for="t in settingsUi.adjusters.mouse" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.togglers.mouse" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
</div>
</div>
<div id="settings_controller" v-show="showControllerTab">
<h3 class="nospace">{{ loc.p_settings_gamepadbindings }}</h3>
<div class="f_row ss_margintop">
<div class="f_col">
<div v-for="c in settingsUi.controls.gamepad.game" class="nowrap">
<settings-gamepad-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGamepadGameControlCaptured" :controller-type="controllerType"></settings-gamepad-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
<div class="f_col ss_marginleft_xl">
<div class="ss_marginbottom_xl">
<div v-for="c in settingsUi.controls.gamepad.spectate" class="nowrap">
<settings-gamepad-binder :loc="loc" :control-id="c.id" :control-value="c.value" @control-captured="onGamepadSpectateControlCaptured" :controller-type="controllerType"></settings-gamepad-binder>
<div class="label">{{ loc[c.locKey] }}</div>
</div>
</div>
<div v-for="t in settingsUi.adjusters.gamepad" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" :precision="t.precision" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.togglers.gamepad" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
<p>{{ controllerId }}</p>
<p>{{ loc.p_settings_controllerhelp }} <a target="_blank" href="https://html5gamepad.com">html5gamepad.com</a></p>
</div>
<div id="settings_misc" v-show="showMiscTab">
<div class="f_row">
<div class="f_col">
<header>
<h2>{{loc.p_settings_volume_controls}}</h2>
</header>
<div v-for="t in settingsUi.adjusters.misc" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<div v-for="t in settingsUi.adjusters.music" class="nowrap">
<settings-adjuster :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="onSettingAdjusted"></settings-adjuster>
</div>
<h3 class="nospace ss_margintop">{{ loc.p_settings_language }}</h3>
<language-selector :languages="languages" :loc="loc" :selectedLanguageCode="currentLanguageCode" class="ss_select" :langOptions="langOption"></language-selector>
<button v-if="showPrivacyOptions" @click="onPrivacyOptionsClicked" class="ss_button btn_blue bevel_blue btn_md ss_margintop_xl">{{ loc.p_settings_privacy }}</button>
</div>
<div class="f_col ss_marginleft_xl">
<div v-for="t in settingsUi.togglers.misc" class="nowrap">
<settings-toggler v-if="(t.id === 'shadowsEnabled' || t.id === 'highRes') ? showDetailSettings : true" :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :hide="hideSetting(t.id)" @setting-toggled="onSettingToggled"></settings-toggler>
</div>
</div>
</div>
</div>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onCloseClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
<button @click="onResetClick" class="ss_button btn_yolk bevel_yolk btn_sm">{{ loc.p_settings_reset }}</button>
<button @click="onSaveClick()" class="ss_button btn_green bevel_green btn_sm">{{ loc.confirm }}</button>
</div>
</div>
</script>
<script id="settings-control-binder-template" type="text/x-template">
<input ref="controlInput" @change="BAWK.play('ui_onchange')" type="text" v-model="currentValue" :placeholder="loc.press_key" class="ss_keybind clickme" :class="(currentValue === 'undefined' ? 'ss_keybind_undefined' : '')"
v-on:mousedown="onMouseDown($event)"
v-on:keydown="onKeyDown($event)"
v-on:keyup="onKeyUp($event)"
v-on:wheel="onWheel($event)"
v-on:focusout="onFocusOut($event)">
</script>
<script>
var comp_settings_control_binder = {
template: '#settings-control-binder-template',
props: ['loc', 'controlId', 'controlValue'],
data: function () {
return {
currentValue: this.controlValue,
isCapturing: false
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
reset: function () {
this.currentValue = (this.controlValue === null) ? 'undefined' : this.controlValue;
this.isCapturing = false;
this.$refs.controlInput.blur();
},
capture: function (value) {
this.isCapturing = false;
this.$refs.controlInput.blur();
this.$emit('control-captured', this.controlId, value);
},
onMouseDown: function (event) {
if (!this.isCapturing) {
this.currentValue = '';
this.isCapturing = true;
} else {
BAWK.play('ui_onchange')
this.capture('MOUSE ' + event.button);
}
},
onKeyDown: function (event) {
this.currentValue = '';
event.stopPropagation();
},
onKeyUp: function (event) {
event.stopPropagation();
var key = event.key;
if (key == 'Escape' || key == 'Tab' || key == 'Enter') {
return;
}
if (key == ' ') {
key = 'space';
event.preventDefault();
}
this.capture(key);
},
onWheel: function (event) {
if (this.isCapturing) {
BAWK.play('ui_onchange')
if (event.deltaY > 0) {
this.capture('WHEEL DOWN');
} else if (event.deltaY < 0) {
this.capture('WHEEL UP');
}
}
},
onFocusOut: function (event) {
this.reset();
}
},
watch: {
// The value prop gets updated by the parent control; watch for changes and update the backing field of the textbox
controlValue: function (newValue) {
this.currentValue = (newValue === null) ? 'undefined' : newValue;
}
}
};
</script><script id="settings-gamepad-binder-template" type="text/x-template">
<button ref="gamepadInput" class="ss_keybind clickme" :class="(currentValue === 'undefined' ? 'ss_keybind_undefined' : '')"
v-on:mousedown="onMouseDown($event)"
v-on:keydown="onKeyDown($event)"
v-on:keyup="onKeyUp($event)"
v-on:focusout="onFocusOut($event)"
:key="controllerType">
<span v-html="currentValue"></span></button>
</script>
<script>
var comp_settings_gamepad_binder = {
template: '#settings-gamepad-binder-template',
props: ['loc', 'controlId', 'controlValue', 'controllerType'],
data: function () {
return {
currentValue: (this.controlValue === null) ? 'undefined' : vueData.controllerButtonIcons[this.controllerType][this.controlValue],
isCapturing: false
}
},
beforeUpdate: function () {
if (!this.isCapturing) {
this.setIcon(this.controlValue);
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
reset: function () {
this.setIcon(this.controlValue);
this.isCapturing = false;
removeEventListener('gamepadbuttondown', this.onButtonDown);
removeEventListener('gamepadbuttonup', this.onButtonUp);
},
capture: function (value) {
this.isCapturing = false;
this.$refs.gamepadInput.blur();
this.$emit('control-captured', this.controlId, value);
this.reset();
},
onMouseDown: function (event) {
if (!this.isCapturing) {
this.currentValue = this.loc.press_button;
this.isCapturing = true;
addEventListener('gamepadbuttondown', this.onButtonDown);
addEventListener('gamepadbuttonup', this.onButtonUp);
}
},
onKeyDown: function (event) {
event.stopPropagation();
},
onKeyUp: function (event) {
event.stopPropagation();
},
onButtonDown: function (event) {
if (event.detail == 8 || event.detail == 9) return;
BAWK.play('ui_onchange')
this.capture(event.detail);
},
onFocusOut: function (event) {
this.reset();
},
setIcon: function (value) {
this.currentValue = (value === null) ? 'undefined' : vueData.controllerButtonIcons[this.controllerType][value];
}
},
watch: {
// The value prop gets updated by the parent control; watch for changes and update the backing field of the textbox
controlValue: function (newValue) {
this.setIcon(newValue);
}
}
};
</script><script id="settings-adjuster-template" type="text/x-template">
<div>
<h3 class="nospace">{{ loc[locKey] }}</h3>
<div class="f_row">
<input class="ss_slider" type="range" :min="min" :max="max" :step="step" v-model="currentValue" @change="onChange">
<label class="ss_slider label">{{ getCurrentValue() }}</label>
</div>
</div>
</script>
<script>
var comp_settings_adjuster = {
template: '#settings-adjuster-template',
props: ['loc', 'locKey', 'controlId', 'controlValue', 'min', 'max', 'step', 'multiplier', 'precision'],
data: function () {
return {
currentValue: this.controlValue
}
},
methods: {
onChange: function (event) {
this.$emit('setting-adjusted', this.controlId, this.currentValue);
BAWK.play('ui_onchange');
},
getCurrentValue: function () {
if (this.precision) {
return Number.parseFloat(this.currentValue).toFixed(this.precision);
}
else {
return Math.floor(this.currentValue * (this.multiplier || 1));
}
}
},
watch: {
// controlValue prop could change when player X's out or clicks Cancel
controlValue: function (newValue) {
if (this.currentValue !== newValue) {
this.currentValue = newValue;
}
}
}
};
</script><script id="settings-toggler-template" type="text/x-template">
<label v-if="!hide" class="ss_checkbox label"> {{ loc[locKey] }}
<input type="checkbox" v-model="currentValue" @change="onChange($event)">
<span class="checkmark"></span>
</label>
</script>
<script>
var comp_settings_toggler = {
template: '#settings-toggler-template',
props: ['loc', 'locKey', 'controlId', 'controlValue', 'hide'],
data: function () {
return {
currentValue: this.controlValue
}
},
methods: {
onChange: function (event) {
this.$emit('setting-toggled', this.controlId, this.currentValue);
BAWK.play('ui_onchange');
}
},
watch: {
// controlValue prop could change when player X's out or clicks Cancel
controlValue: function (newValue) {
if (this.currentValue !== newValue) {
this.currentValue = newValue;
}
}
}
};
</script>
<script>
var comp_settings = {
template: '#settings-template',
components: {
'settings-control-binder': comp_settings_control_binder,
'settings-gamepad-binder': comp_settings_gamepad_binder,
'language-selector': comp_language_selector,
'settings-adjuster': comp_settings_adjuster,
'settings-toggler': comp_settings_toggler
},
props: ['loc', 'settingsUi', 'languages', 'currentLanguageCode', 'showPrivacyOptions', 'controllerId', 'isFromEU', 'controllerType', 'langOption', 'isVip'],
data: function () {
return {
showKeyboardTab: true,
showControllerTab: false,
showMiscTab: false,
originalSettings: {},
showDetailSettings: false,
originalLanguage: '',
originalMusicVolume: '',
musicStatChg: ''
}
},
methods: {
selectTab: function (e) {
return this.switchTab(e.target.id)
},
switchTab(tab) {
this.showKeyboardTab = false;
this.showControllerTab = false;
this.showMiscTab = false;
switch (tab) {
case 'keyboard_button':
this.showKeyboardTab = true;
break;
case 'controller_button':
this.showControllerTab = true;
break;
case 'misc_button':
this.showMiscTab = true;
break;
}
BAWK.play('ui_toggletab');
},
captureOriginalSettings: function () {
this.originalSettings = deepClone(vueData.settingsUi);
this.originalLanguage = this.currentLanguageCode;
// this.originalMusicVolume = this.originalSettings.adjusters.music[0].value;
},
applyOriginalSettings: function () {
vueData.settingsUi = this.originalSettings;
this.showDetailSettings = !vueData.settingsUi.togglers.misc.find( a => { return a.id === 'autoDetail'; }).value;
console.log('applying original settings: ' + JSON.stringify(vueData.settingsUi));
},
onGameControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.keyboard.game, id, value)
},
onSpectateControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.keyboard.spectate, id, value)
},
onGamepadGameControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.gamepad.game, id, value)
},
onGamepadSpectateControlCaptured: function (id, value) {
this.onControlCaptured(this.settingsUi.controls.gamepad.spectate, id, value)
},
onControlCaptured: function (controls, id, value) {
value = value.toLocaleUpperCase();
controls
.forEach( (c) => {
if (c.id === id) {
c.value = value;
} else {
if (c.value === value) {
c.value = null;
}
}
});
},
onSettingToggled: function (id, value) {
console.log('value: ' + value);
Object.values(this.settingsUi.togglers).forEach(v => {
var toggler = v.find(t => { return t.id === id; });
if (toggler) toggler.value = value;
})
if (id === 'autoDetail') {
this.showDetailSettings = !value;
}
if (id === 'safeNames') {
extern.setSafeNames(value);
}
// if (id === 'musicStatus') {
// extern.setMusicStatus(value);
// this.musicStatChg = true;
// if (extern.inGame) {
// vueApp.toggleMusic();
// }
// }
},
onSettingAdjusted: function (id, value) {
Object.values(this.settingsUi.adjusters).forEach(v => {
var adjuster = v.find( (a) => { return a.id === id; });
if (adjuster) adjuster.value = value;
})
if (id === 'volume') {
extern.setVolume(value);
}
if (id === 'mouseSpeed') {
extern.setMouseSpeed(value);
}
if (id === 'sensitivity') {
extern.setControllerSpeed(value);
}
if (id === 'deadzone') {
extern.setDeadzone(value);
}
if (id === 'musicVolume') {
extern.setMusicVolume(value);
}
},
onVolumeChange: function () {
extern.setVolume(this.settingsUi.volume);
},
onPrivacyOptionsClicked: function () {
this.$emit('privacy-options-opened');
BAWK.play('ui_popupopen');
},
onCancelClick: function () {
this.applyOriginalSettings();
//extern.setMusicVolume(this.originalMusicVolume);
this.cancelLanguageSelect();
if (this.musicStatChg) {
if (extern.inGame) {
vueApp.toggleMusic();
}
};
this.$parent.close();
},
onCloseClick: function () {
this.applyOriginalSettings();
//extern.setMusicVolume(this.originalMusicVolume);
this.cancelLanguageSelect();
if (this.musicStatChg) {
if (extern.inGame) {
vueApp.toggleMusic();
}
};
this.$parent.close();
BAWK.play('ui_popupclose');
},
quickSave() {
extern.applyUiSettings(this.settingsUi, this.originalSettings);
this.resetOriginalLanguage();
},
onSaveClick: function () {
// if (vueApp.music.serverTracks.title) {
// this.gaMusicVol();
// }
// this.gaMusicVol();
extern.applyUiSettings(this.settingsUi, this.originalSettings);
this.resetOriginalLanguage();
this.$parent.toggle();
BAWK.play('ui_playconfirm');
},
gaMusicVol() {
let newVol = Number(this.settingsUi.adjusters.music[0].value);
if (newVol === Number(this.originalMusicVolume)) return;
if ((Math.round(newVol*100)) <= 1) {
ga('send', 'event', 'music', 'mute', vueApp.music.serverTracks.title);
}
},
onResetClick: function () {
extern.resetSettings();
BAWK.play('ui_reset');
},
cancelLanguageSelect: function() {
this.originalLanguage === vueApp.$data.currentLanguageCode ?
vueApp.changeLanguage(vueApp.$data.currentLanguageCode) : vueApp.changeLanguage(this.originalLanguage);
// Revert localStore for language
localStore.setItem('languageSelected', this.originalLanguage);
this.resetOriginalLanguage();
},
resetOriginalLanguage: function() {
this.originalLanguage = '';
},
setSettings: function (settings) {
var getSettingById = (list, id) => {
return list.filter( o => {
return o.id == id;
})[0];
};
// Keyboard
getSettingById(this.settingsUi.controls.keyboard.game, 'up').value = settings.controls.keyboard.game.up;
getSettingById(this.settingsUi.controls.keyboard.game, 'down').value = settings.controls.keyboard.game.down;
getSettingById(this.settingsUi.controls.keyboard.game, 'left').value = settings.controls.keyboard.game.left;
getSettingById(this.settingsUi.controls.keyboard.game, 'right').value = settings.controls.keyboard.game.right;
getSettingById(this.settingsUi.controls.keyboard.game, 'jump').value = settings.controls.keyboard.game.jump;
getSettingById(this.settingsUi.controls.keyboard.game, 'fire').value = settings.controls.keyboard.game.fire;
getSettingById(this.settingsUi.controls.keyboard.game, 'scope').value = settings.controls.keyboard.game.scope;
getSettingById(this.settingsUi.controls.keyboard.game, 'reload').value = settings.controls.keyboard.game.reload;
getSettingById(this.settingsUi.controls.keyboard.game, 'swap_weapon').value = settings.controls.keyboard.game.swap_weapon;
getSettingById(this.settingsUi.controls.keyboard.game, 'grenade').value = settings.controls.keyboard.game.grenade;
getSettingById(this.settingsUi.controls.keyboard.spectate, 'ascend').value = settings.controls.keyboard.spectate.ascend;
getSettingById(this.settingsUi.controls.keyboard.spectate, 'descend').value = settings.controls.keyboard.spectate.descend;
// Gamepad
getSettingById(this.settingsUi.controls.gamepad.game, 'jump').value = settings.controls.gamepad.game.jump;
getSettingById(this.settingsUi.controls.gamepad.game, 'fire').value = settings.controls.gamepad.game.fire;
getSettingById(this.settingsUi.controls.gamepad.game, 'scope').value = settings.controls.gamepad.game.scope;
getSettingById(this.settingsUi.controls.gamepad.game, 'reload').value = settings.controls.gamepad.game.reload;
getSettingById(this.settingsUi.controls.gamepad.game, 'swap_weapon').value = settings.controls.gamepad.game.swap_weapon;
getSettingById(this.settingsUi.controls.gamepad.game, 'grenade').value = settings.controls.gamepad.game.grenade;
getSettingById(this.settingsUi.controls.gamepad.spectate, 'ascend').value = settings.controls.gamepad.spectate.ascend;
getSettingById(this.settingsUi.controls.gamepad.spectate, 'descend').value = settings.controls.gamepad.spectate.descend;
// Misc
getSettingById(this.settingsUi.adjusters.misc, 'volume').value = settings.volume;
// getSettingById(this.settingsUi.adjusters.music, 'musicVolume').value = settings.musicVolume;
getSettingById(this.settingsUi.adjusters.mouse, 'mouseSpeed').value = settings.mouseSpeed;
getSettingById(this.settingsUi.adjusters.gamepad, 'sensitivity').value = settings.controllerSpeed;
getSettingById(this.settingsUi.adjusters.gamepad, 'deadzone').value = settings.deadzone;
getSettingById(this.settingsUi.togglers.mouse, 'mouseInvert').value = (settings.mouseInvert !== 1);
getSettingById(this.settingsUi.togglers.mouse, 'fastPollMouse').value = settings.fastPollMouse;
getSettingById(this.settingsUi.togglers.gamepad, 'controllerInvert').value = (settings.controllerInvert !== 1);
getSettingById(this.settingsUi.togglers.misc, 'holdToAim').value = settings.holdToAim;
getSettingById(this.settingsUi.togglers.misc, 'enableChat').value = settings.enableChat;
getSettingById(this.settingsUi.togglers.misc, 'safeNames').value = settings.safeNames;
getSettingById(this.settingsUi.togglers.misc, 'autoDetail').value = settings.autoDetail;
getSettingById(this.settingsUi.togglers.misc, 'shadowsEnabled').value = settings.shadowsEnabled;
getSettingById(this.settingsUi.togglers.misc, 'highRes').value = settings.highRes;
getSettingById(this.settingsUi.togglers.misc, 'hideBadge').value = settings.hideBadge;
// getSettingById(this.settingsUi.togglers.misc, 'musicStatus').value = settings.musicStatus;
console.log('auto detail: ' + settings.autoDetail);
this.showDetailSettings = !settings.autoDetail;
},
hideSetting(id) {
if (id === 'hideBadge' && !this.isVip) {
return true;
}
return false;
}
}
};
</script><script id="help-template" type="text/x-template">
<div>
<div id="horizontalTabs">
<button id="faq_button" @click="toggleTabs" class="ss_bigtab bevel_blue ss_marginright" :class="(showTab1 ? 'selected' : '')">{{ loc.faq }}</button>
<button id="fb_button" @click="toggleTabs" class="ss_bigtab bevel_blue" :class="(!showTab1 ? 'selected' : '')">{{ loc.feedback }}</button>
</div>
<div v-show="showTab1">
<div id="feedback_panel">
<h1>{{ loc.faq_title }}</h1>
<help-questions :content="localizeThis"></help-questions>
<hr>
<div id="btn_horizontal" class="f_center">
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
</div>
</div>
</div>
<div v-show="!showTab1">
<div id="feedback_panel">
<h1>{{ loc.fb_feedback_title }}</h1>
<p>{{ loc.fb_feedback_intro }}</p>
<div id="btn_horizontal" class="f_center">
<select v-model="selectedType" class="ss_field ss_marginright" @click="BAWK.play('ui_click')" @change="BAWK.play('ui_onchange')">
<option v-for="type in feedbackType" :value="type.id">{{ loc[type.locKey] }}</option>
</select>
<input id="feedbackEmail" v-model="email" :placeholder="loc.fb_email_ph" class="ss_field" v-on:keyup="validateEmail">
</div>
<div>
<textarea id="feedbackText" class="ss_field" v-model="feedback" :placeholder="loc.fb_feedback_ph" v-on:keyup="validateMessage"></textarea>
</div>
<div class="f_center f_col">
<span v-show="emailInvalid" class="ss_marginright error_text">{{ loc.fb_bad_email }}</span>
<span v-show="messageInvalid" class="ss_marginright error_text">{{ loc.fb_no_comment }}</span>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
<button @click="onSendClick" class="ss_button btn_md btn_green bevel_green">{{ loc.fb_send }}</button>
</div>
</div>
</div>
</div>
</script>
<script id="help-question-template" type="text/x-template">
<div>
<div v-for="qa in content">
<a :name="qa[0]"></a>
<h3>{{ qa[1] }}</h3>
<span v-html="qa[2]"></span>
</div>
</div>
</script>
<script>
var comp_help_question = {
template: '#help-question-template',
props: ['content'],
};
</script>
<script>
var comp_help = {
template: '#help-template',
components: {
'help-questions': comp_help_question,
},
props: ['loc'],
mounted() {
this.helpLocSetup();
},
data: function () {
return {
showTab1: true,
feedbackType: [
{ id: 0, locKey: 'fb_type_commquest' },
{ id: 1, locKey: 'fb_type_request' },
{ id: 2, locKey: 'fb_type_bug' },
{ id: 3, locKey: 'fb_type_purchase' },
{ id: 4, locKey: 'fb_type_account' },
{ id: 5, locKey: 'fb_type_abuse' },
{ id: 6, locKey: 'fb_type_other' }
],
selectedType: 0,
email: '',
feedback: '',
doValidation: false,
emailInvalid: false,
messageInvalid: false,
qaNum: [1,2,3,4,5,6,7,8,9,10,11],
newLoc: [],
localizeThis: [],
}
},
feedbackValidateTimeout: 0,
methods: {
playSound (sound) {
BAWK.play(sound);
},
validateEmail: function () {
if (!this.doValidation) {
return;
}
// Insane e-mail-validating regex
var re = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
this.emailInvalid = (this.email === '' || !re.test(this.email));
return !this.emailInvalid;
},
validateMessage: function () {
if (!this.doValidation) {
return;
}
this.messageInvalid = this.feedback === '';
return !this.messageInvalid;
},
toggleTabs: function () {
this.showTab1 = !this.showTab1;
BAWK.play('ui_toggletab');
! this.showTab1 && ga('send', 'event', 'feedback opened');
},
onBackClick: function () {
vueApp.$refs.helpPopup.toggle();
BAWK.play('ui_popupclose');
},
onSendClick: function () {
this.doValidation = true;
if (!this.validateEmail() || !this.validateMessage()) {
return;
}
BAWK.play('ui_playconfirm');
// Send that shit out
extern.api_feedback(this.selectedType, this.email, this.feedback);
setTimeout(() => {
this.$parent.toggle();
this.selectedType = 0;
this.feedback = null;
this.email = null;
}, 900);
},
helpLocSetup(locContent) {
let content = this.loc;
// if (locContent) {
// content = locContent
// }
const locArray = Object.entries(content);
this.newLoc = locArray.filter( (item, i) => {
if (item[0].includes('faqItems_q')) {
return item;
}
});
const tranlateThat = [];
for (let n = 0; n < this.qaNum.length; n++) {
tranlateThat.push([]);
for (let i = 0; i < this.newLoc.length; i++) {
if (this.newLoc[i][0].includes('faqItems_q' + this.qaNum[n] + '_')) {
tranlateThat[n].push(this.newLoc[i][1]);
}
}
}
// Cause once again... vue
setTimeout(() => {this.localizeThis = tranlateThat}, 500);
}
},
watch: {
loc(val) {
this.helpLocSetup(val);
}
}
};
</script><script id="vip-help-template" type="text/x-template">
<div>
<div id="feedback_panel">
<h1>{{ loc.vipHelptitle }}</h1>
<small class="text_red"><i class="fas fa-exclamation-triangle"></i> {{loc.vipHelpDesc2}}</small>
<p>{{loc.vipHelpDesc}}</p>
<div>
<a :name="loc.vipFaqItems_q1_anchor"></a>
<h3>{{ loc.vipFaqItems_q1_q }}</h3>
<p>{{ loc.vipFaqItems_q1_a_1 }}</p>
<ul>
<li>{{ loc.vipFaqItems_q1_li_1 }}</li>
<li>{{ loc.vipFaqItems_q1_li_2 }}</li>
<li>{{ loc.vipFaqItems_q1_li_3 }}</li>
<li>{{ loc.vipFaqItems_q1_li_4 }}</li>
<li>{{ loc.vipFaqItems_q1_li_5 }}</li>
<li>{{ loc.vipFaqItems_q1_li_6 }}</li>
</ul>
</div>
<div>
<a :name="loc.vipFaqItems_q2_anchor"></a>
<h3>{{ loc.vipFaqItems_q2_q }}</h3>
<p>{{ loc.vipFaqItems_q2_a_1 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q3_anchor"></a>
<h3>{{ loc.vipFaqItems_q3_q }}</h3>
<p>{{ loc.vipFaqItems_q3_a_1 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q4_anchor"></a>
<h3>{{ loc.vipFaqItems_q4_q }}</h3>
<p>{{ loc.vipFaqItems_q4_a_mobile_3 }}</p>
<p>{{ loc.vipFaqItems_q4_a_1 }}</p>
<p>{{ loc.vipFaqItems_q4_a_2 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q5_anchor"></a>
<h3>{{ loc.vipFaqItems_q5_q }}</h3>
<p>{{ loc.vipFaqItems_q5_a_1 }}</p>
<p>{{ loc.vipFaqItems_q5_a_2 }}</p>
<p>{{ loc.vipFaqItems_q5_a_3 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q6_anchor"></a>
<h3>{{ loc.vipFaqItems_q6_q }}</h3>
<p>{{ loc.vipFaqItems_q6_a_1 }}</p>
<p>{{ loc.vipFaqItems_q6_a_2 }}</p>
<p>{{ loc.vipFaqItems_q6_a_3 }}</p>
</div>
<div>
<a :name="loc.vipFaqItems_q7_anchor"></a>
<h3>{{ loc.vipFaqItems_q7_q }}</h3>
<p>{{ loc.vipFaqItems_q7_a_1 }}</p>
</div>
<!--
<div v-for="qa in loc.vipFaqItems">
<a :name="qa.anchor"></a>
<h3>{{ qa.q }}</h3>
<p v-for="p in qa.a">
{{p}}
</p>
<ul v-if="qa.li">
<li v-for="li in qa.li">{{li}}</li>
</ul>
</div> -->
<hr>
<div id="btn_horizontal" class="f_center">
<button @click="openVipStore" class="ss_button btn_md btn_green bevel_green ss_marginright">{{ subButtonTxt }}</button>
<button @click="onBackClick" class="ss_button btn_md btn_red bevel_red ss_marginright">{{ loc.cancel }}</button>
</div>
</div>
</div>
</script>
<script>
var vip_help = {
template: '#vip-help-template',
props: ['loc', 'isVip'],
data: function () {
return {
}
},
methods: {
onBackClick() {
BAWK.play('ui_popupclose');
this.$parent.hide();
},
openVipStore() {
this.$parent.hide();
vueApp.showSubStorePopup();
}
},
computed: {
subButtonTxt() {
return this.isVip ? this.loc.sManageBtn : this.loc.account_vip;
}
}
};
</script><script id="egg-store-template" type="text/x-template">
<div class="fullwidth">
<h1 class="roundme_sm">{{ loc.p_egg_shop_title }}</h1>
<div class="display-grid grid-column-4-eq grid-gap-space-lg">
<egg-store-item v-for="item in products" :key="item.sku" :item="item" :loc="loc" inStore="true" :account-set="accountSettled" :isUpgraded="isUpgraded" :isSaleEvent="saleEvent"></egg-store-item>
</div>
</div>
</script>
<template id="comp-store-item">
<figure id="popupInnards" v-if="showItem" class="single-egg-store-item box_blue4 roundme_md f_col text-center box_relative" :class="[itemType, {purchased: purchased}]">
<div v-if="purchased" class="single-egg-store-item-purchased">{{loc.p_egg_shop_purchased}}</div>
<div v-if="item.flagText" id="eggshop_banner" :class="{sale: item.salePrice}">
<img v-if="!item.salePrice && !item.itemId" src="img/egg-shop-banner-left.png">
<div class="eggshop_banner_mid">
<i v-if="item.salePrice || item.itemId" class="fas" :class="flagTxt"></i>
{{ item.discount }} {{ loc[item.flagText] }}
</div>
</div>
<figcaption>
<p align="center" class="nospace roundme_md"><img :src="img" class="eggshop_image roundme_md"></p>
<h6 class="nospace shadow_bluebig4 eggshop_bigtitle">{{ loc[title] }}</h6>
<span v-if="showSubtitle" class="eggshop_subtitle text_white">{{ loc[description] }}</span>
<div class="f_row">
<div class="eggshop_pricebox roundme_sm" :class="{ slashed: item.salePrice }">${{ item.price }} USD</div>
<div v-if="item.salePrice" class="eggshop_pricebox roundme_sm sale-price">${{ item.salePrice }} USD</div>
</div>
<button class="store_btn ss_button btn_green bevel_green btn_sm center_h" @click="onItemClicked(item.sku)">{{ buyBtnText }}</button>
<div v-if="item.type === 'item' && !hasPurchased && inStore">
<button class="ss_button btn_yolk bevel_yolk btn_sm center_h vip-get-btn box_absolute" @click="onVipClick"><span>{{ loc.p_egg_shop_free_with_vip }}</span> <img src="img/vip-club/vip-club-emblem-sm.png" alt=""></button>
</div>
</figcaption>
</figure>
</template>
<script>
const comp_store_item = {
template: '#comp-store-item',
props: ['loc', 'item', 'inStore', 'accountSet', 'isUpgraded', 'isSaleEvent'],
data() {
return {
purchased: false,
attempt: 0,
};
},
methods: {
onItemClicked() {
if (!this.accountSet || !vueApp.accountSettled) {
vueApp.hideEggStorePopup();
setTimeout(() => {
if (this.attempt < 5) {
this.onItemClicked(this.item.sku);
this.attempt++;
} else {
vueApp.showGenericPopup('uh_oh', 'error', 'ok');
}
}, 300);
vueApp.pleaseWaitPopup();
return;
}
if (this.$parent.$el.id === 'help') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
if (this.item.type === 'item' && !hasValue(this.item.itemId.id) && !Number.isInteger(this.item.itemId)) {
vueApp.showGenericPopup('uh_oh', 'p_egg_shop_no_item_id', 'ok');
return;
}
if (this.purchased) {
console.log('Item is owned so lets go see it.');
vueApp.showItemOnEquipScreen(extern.catalog.findItemById(this.item.itemId.id));
return;
}
extern.buyProductForMoney(this.item.sku);
ga('send', 'event', vueApp.googleAnalytics.cat.purchases, vueApp.googleAnalytics.action.eggShackProductClick, this.item.sku);
},
isPurchased() {
if (this.item.itemId) {
return this.purchased = extern.isItemOwned(this.item.itemId);
}
},
onVipClick() {
this.$parent.$parent.hide();
vueApp.showSubStorePopup();
}
},
computed: {
title() {
return `${this.item.sku}_title`;
},
description() {
return `${this.item.sku}_desc`;
},
img() {
if (this.item.type === 'item') {
return `img/store/items/${this.item.sku}.gif`;
}
const path = !this.isSaleEvent ? '' : 'store-black-friday/';
return `img/${path}${this.item.sku}.png`;
},
itemType() {
return 'single-egg-store-item-is-' + this.item.type;
},
buyBtnText() {
if (this.purchased) {
return this.loc.p_egg_shop_see_item;
}
return this.loc.p_buy_item_confirm;
},
showItem() {
if (this.inStore) return this.item.inStore;
this.isPurchased();
return true;
},
flagTxt() {
if (this.item.salePrice) {
return 'fa-tag';
}
return 'fa-gem'
},
showSubtitle() {
if (this.item.type === 'item') return true;
if (this.isSaleEvent) {
return false;
}
return true;
},
hasPurchased() {
return this.isPurchased();
}
},
watch: {
accountSet(val) {
if (val) {
this.isPurchased();
}
},
isUpgraded(val) {
if (val) {
this.isPurchased();
}
}
}
};
</script>
<script>
var comp_egg_store = {
template: '#egg-store-template',
components: {
'egg-store-item': comp_store_item,
},
data() {
return vueData;
},
props: ['loc', 'products', 'saleEvent'],
methods: {
onItemClicked: function (sku) {
if (!this.accountSettled) {
console.log(this.$parent.hide());
setTimeout(() => {
this.onItemClicked(sku)
}, 300);
vueApp.pleaseWaitPopup();
return;
}
if (vueApp.$refs.genericPopup.isShowing === true) vueApp.$refs.genericPopup.close();
this.$parent.hide();
extern.buyProductForMoney(sku);
ga('send', 'event', this.googleAnalytics.cat.purchases, this.googleAnalytics.action.eggShackProductClick, sku);
}
},
};
</script><script id="house-ad-big-template" type="text/x-template">
<div v-show="(useAd !== null)">
<button @click="onCloseClicked" class="popup_close splash_ad_close ad_close"></button>
<img :src="adImageUrl" @click="onClicked" class="splash_ad_image centered roundme_md">
</div>
</script>
<script>
var comp_house_ad_big = {
template: '#house-ad-big-template',
data: function() {
return {
removeOverlayClick: '',
}
},
props: ['useAd'],
bigAdTimeout: null,
methods: {
onCloseClicked: function () {
console.log('big ad closed');
this.close();
},
onClicked: function () {
this.close();
BAWK.play('ui_click');
extern.clickedHouseAdBig(this.useAd);
},
close: function () {
if (this.useAd === null) {
return;
}
BAWK.play('ui_popupclose');
this.$emit('big-house-ad-closed');
},
outsideClickClose: function() {
const showingId = document.getElementById('house-ad-big-template', true);
this.removeOverlayClick = this.handleOutsideClick;
document.addEventListener('click', this.removeOverlayClick);
},
handleOutsideClick: function(e) {
// Stop bubbling
e.stopPropagation();
// If the target does NOT include the class splash_ad_image use the onCloseClicked method and remove the eventListener
if ( ! e.target.id.includes('splash_ad_image') ) {
this.onCloseClicked();
document.removeEventListener('click', this.removeOverlayClick);
}
},
},
computed: {
adImageUrl: function () {
if (!hasValue(this.useAd)) {
return;
}
return dynamicContentPrefix + 'data/img/art/{0}{1}'.format(this.useAd.id, this.useAd.imageExt);
}
},
watch: {
useAd: function (bigAd) {
if (hasValue(bigAd)) {
setTimeout(() => {
vueApp.hideTitleScreenAd();
}, 100);
this.$options.bigAdTimeout = setTimeout(function () {
vueApp.ui.houseAds.big = null;
}, 15000);
// Close with outside click
this.outsideClickClose();
} else {
vueApp.showTitleScreenAd();
}
}
}
};
</script><script id="house-ad-small-template" type="text/x-template">
<img v-show="(useAd !== null)" :src="adImageUrl" @click="onClicked" class="news_banner roundme_md">
</script>
<script>
var comp_house_ad_small = {
template: '#house-ad-small-template',
props: ['useAd'],
methods: {
onClicked: function () {
BAWK.play('ui_click');
extern.clickedHouseAdSmall(this.useAd);
}
},
computed: {
adImageUrl: function () {
if (!hasValue(this.useAd)) {
return;
}
ga('send', 'event', {
eventCategory: 'House banner ad',
eventAction: 'show',
eventLabel: this.useAd.label
});
return dynamicContentPrefix + 'data/img/art/{0}{1}'.format(this.useAd.id, this.useAd.imageExt);
}
}
};
</script>
<script id="item-template" type="text/x-template">
<div v-if="active" class="store_item roundme_lg clickme" ref="eggItemInvetory" :class="highlightSelected()" @click="onClick">
<div v-if="isPremium" class="store_item-premium" :class="{'is-vip-item': isVipItem}">
{{itemBannerText}}
</div>
<div v-if="showPrice" class="equip_smallprice">
<svg v-if="!isPremium" class="equip_egg eggIcon"><use xlink:href="#icon-egg"></use></svg>
<i v-if="isPremium" class="fas fa-dollar-sign equip_egg eggIcon"></i>
<div class="equip_cost"> {{ item.price }}</div>
</div>
<canvas ref="itemCanvas" class="equip_icon" width="250" height="250"></canvas>
</div>
</script>
<script>
var comp_item = {
template: '#item-template',
props: ['loc', 'item', 'showItemOnly', 'isSelected', 'equippedSlot'],
data: function () {
return {
itemOnly: hasValue(this.showItemOnly) ? this.showItemOnly : false,
active: true,
}
},
mounted() {
this.prepareItem();
this.itemHightlightedOrder();
},
methods: {
isItemSellable: function () {
return !this.itemOnly && vueData.equip.mode == vueData.equip.equipModes.shop;
},
isPremItem() {
if (this.isPremium && this.isItemSellable()) {
const ITEM = vueData.premiumShopItems.find(i => {
return i.itemId.id && i.itemId.id === this.item.id && i.type === 'item';
});
if (ITEM !== undefined && ITEM.isActive) {
this.item.sku = ITEM.sku;
this.item.price = ITEM.salePrice ? ITEM.salePrice : ITEM.price;
} else {
this.active = false;
}
}
this.isMerch();
},
isMerch() {
if (this.showPhysicalMerch && vueData.equip.mode === vueData.equip.equipModes.shop) {
this.item.active = false;
}
this.isEquippedSlot();
},
isEquippedSlot() {
if (this.equippedSlot) {
this.active = true;
}
vueApp.equip.lazyRenderTimeouts.push(setTimeout(() => this.renderItem(), 0));
},
prepareItem: function () {
this.isPremItem();
},
renderItem() {
extern.renderItemToCanvas(this.item, this.$refs.itemCanvas);
},
highlightSelected: function () {
return this.isSelected ? 'highlight' : '';
},
onClick: function () {
this.$emit('item-selected', this.item);
},
itemHightlightedOrder: function() {
if (this.showPhysicalMerch && vueData.equip.mode == vueData.equip.equipModes.shop) return;
return this.$refs.eggItemInvetory.classList.contains('highlight') ? this.$refs.eggItemInvetory.style.order='-1' : null;
},
},
computed: {
showPrice () {
return this.isItemSellable() && this.item.price > 0;
},
showPhysicalMerch () {
return this.isItemSellable() && this.item.unlock === 'physical';
},
isPremium() {
return this.item.unlock === 'premium';
},
isVipItem() {
if ('tags' in this.item.item_data ) {
if (this.item.item_data.tags.includes('vipItem')) {
return true;
}
}
},
itemBannerText() {
return this.isVipItem ? 'VIP' : 'Premium';
}
},
watch: {
item: function (val) {
this.prepareItem();
}
}
};
</script><script id="chickn-winner-template" type="text/x-template">
<div id="popupInnards" class="box_dark roundme_sm fullwidth f_col">
<header class="display-grid grid-column-1-eq grid-align-items-center roundme_lg">
<h1 class="chickn-winner-title nospace text-center">{{ loc.chw_ready_msg }}</h1>
</header>
<section id="chickn-winner-wrapper" class="egg-chick-wrapper f_row roundme_lg">
<div class="egg-chick-box box_relative" v-for="egg in eggs" :key="egg.id">
<div v-if="showAmountRewarded && busted && egg.value > 5" class="text-center chw-reward-amount box_absolute">
<h2 class="box_relative shadow_grey">{{ showAmountRewarded }} <img class="chw-winner-egg" src="img/ico_goldenEgg.svg" /></h2>
</div>
<img class="incentivized-egg-chick box_relative" :class="eggClass(egg.value)" @click="eggClickCounter" :src="eggSrc(egg.value)" :id="egg.id">
</div>
</section>
<!-- #chickn-winner-wrapper -->
<footer class="text-center">
<h2 v-if="!busted">{{ loc.p_nugget_instruction }}</h2>
<button v-if="busted" id="gotWinnerOk" v-show="isMiniGameComplete" @click="onGotWinner" class="ss_button btn_medium btn_yolk bevel_yolk btn_shiny">{{ loc.p_nugget_button }}</button>
<display-ad id="shellshockers_chicken_nugget_banner_ad" ref="nuggetDisplayAd" class="pauseFiller center_h" :ignoreSize="true" :adUnit="adUnits.display.nugget" adSize="728x90"></display-ad>
</footer>
</div>
<!-- #popupInnards -->
</script>
<script>
var comp_chickn_winner_popup = {
template: '#chickn-winner-template',
props: ['loc', 'amountGiven', 'adUnits'],
data: function () {
return {
clickedIdx: 0,
eggs: [{id:'eggOne', value: 0, active: true}, {id:'eggTwo', value: 0, active: true}, {id:'eggThree', value: 0, active: true}],
isMiniGameComplete: false,
bustedSrc: `img/incentivized-mini-game/svg/Egg07.svg`,
busted: false,
bustedTimer: 1414
}
},
methods: {
placeBannerAdTag: function (tagEl) {
this.$refs.chickenNuggetAdContainer.appendChild(tagEl);
},
showAd() {
return this.$refs.nuggetDisplayAd.show();
},
hideAd() {
return this.$refs.nuggetDisplayAd.hide();
},
eggSrc(count) {
if (count > 6) {
return `img/incentivized-mini-game/svg/Egg06.svg`;
}
return `img/incentivized-mini-game/svg/Egg0${count}.svg`;
},
eggSrcBusted() {
setTimeout(() => {
return `img/incentivized-mini-game/svg/Egg07.svg`;
}, 2424);
},
eggBg(count) {
if (count > 5) {
return 'incentivized-show'
}
},
eggClass(count) {
if (count > 5) {
return 'chick-alive';
}
},
eggClickCounter(e) {
if (!this.busted) {
BAWK.play('mini-egg-game_shellhit');
} else {
BAWK.play('mini-egg-game_chick');
}
this.clickedIdx = this.eggs.findIndex(i => i.id === e.target.id);
let elem = document.getElementById(this.eggs[this.clickedIdx].id);
if (this.eggs[this.clickedIdx].value < 6) {
elem.classList.add('chickn-winner-clicked');
setTimeout(() => elem.classList.remove('chickn-winner-clicked'), 650);
}
if (this.eggs[this.clickedIdx].value === 5) {
this.isMiniGameComplete = true;
ga('send', 'event', 'Chickn Winner', 'Egg Game', `egg-cracked-${this.eggs[this.clickedIdx].id}`);
setTimeout(() => {
this.eggs[this.clickedIdx].active = false;
elem.src = this.bustedSrc;
}, this.bustedTimer);
this.busted = true;
extern.api_checkBalance();
this.eggs.forEach(i => {
if (i.id === e.target.id) {
return;
}
let btn = document.getElementById(i.id).style.pointerEvents = 'none';
btn.disabled = true;
});
}
if (this.eggs[this.clickedIdx].value === 100) {
BAWK.play('mini-egg-game_shial');
}
this.eggs[this.clickedIdx].value++;
},
resetGame() {
setTimeout(() => {
this.isMiniGameComplete = false;
this.busted = false;
this.eggs.forEach(i => {
let btn = document.getElementById(i.id).style.pointerEvents = 'all';
btn.disabled = false;
});
this.eggs = [{id:'eggOne', value: 0, active: true}, {id:'eggTwo', value: 0, active: true}, {id:'eggThree', value: 0, active: true}];
}, 1000);
},
onGotWinner: function () {
this.$parent.hide();
this.hideAd();
this.resetGame();
extern.checkStartChicknWinner(false, true);
if (extern.inGame) {
vueApp.showGameMenu();
}
},
// loadMiniGame: function () {
// this.isMiniGameComplete = false;
// this.$refs.miniGameFrame.src = "app_nugget/index.html";
// this.$refs.nuggetDisplayAd.show();
// },
// unloadMiniGame: function () {
// this.$refs.miniGameFrame.src = "about:blank";
// },
// onMiniGameCompleted: function () {
// this.isMiniGameComplete = true;
// }
},
computed: {
showAmountRewarded() {
if (this.amountGiven === 0) {
return;
}
return `+${this.amountGiven}`;
},
},
watch: {
busted(val) {
if (val) {
BAWK.play('mini-egg-game_shellburst');
setTimeout(() => {
BAWK.play('mini-egg-game_victory');
}, 500);
}
}
}
};
</script>
<script id="home-screen-template" type="text/x-template">
<div>
<house-ad-big id="big-house-ad" ref="bigHouseAd" :useAd="ui.houseAds.big" @big-house-ad-closed="onBigHouseAdClosed"></house-ad-big>
<div ref="chw-home-timer" v-show="!isPoki && firebaseId" class="chw-home-timer display-grid grid-column-1-2 grid-align-items-center box_absolute grid-gap-1" :class="chwHomeTimerCls">
<div>
<img class="chw-home-timer-chick" :src="chwChickSrc">
</div>
<div class="display-grid grid-align-items-center bg_white chw-circular-timer-container box_relative" :class="chwClass">
<div v-show="chwShowTimer" class="chw-home-screen-timer"></div>
<!-- #chw-circular-timer-outer -->
<div>
<p class="chw-circular-timer-countdown nospace">
<span class="chw-pie-remaining text_center chw-msg chw-r-msg">{{ remainingMsg }}</span>
<span v-show="chwShowTimer" class="chw-pie-num chw-pie-mins"></span><span v-show="chwShowTimer" class="chw-pie-num chw-pie-secs"></span>
</p>
<button v-if="chicknWinnerReady && !hasChwPlayClicked && !isChicknWinnerError" class="ss_button btn_sm btn_yolk bevel_yolk" @click="playIncentivizedAd">{{ playAdText }}</button>
</div>
</div>
<!-- <img src="img/chicken-nugget/speechBubble_static2_tail1.svg" class="chw-bubble-tail box_absolute" alt=""> -->
</div>
<div id="mainHead">
<account-panel id="account_panel" ref="accountPanelHome" :loc="loc" :selected-language-code="currentLanguageCode" :eggs="eggs" :languages="languages" :currentLangOptions="locLanguage" :show-corner-buttons="ui.showCornerButtons" :show-bottom="true" :photo-url="photoUrl" :is-anonymous="isAnonymous" :is-of-age="isOfAge" :show-targeted-ads="showTargetedAds" :ui="ui" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" @sign-in-clicked="onSignInClicked" @sign-out-clicked="onSignOutClicked" :is-twitch="twitchLinked"></account-panel>
<!-- <pwa-button :show="ui.showCornerButtons"></pwa-button> -->
<!-- <streamer-panel id="youtube_panel" :streams="youtubeStreams" :title="loc.youtube_title" :viewers="loc.youtube_viewers" icon="ico_youtube"></streamer-panel> -->
</div>
<div id="mainLayout">
<div id="logo">
<a href="https://www.shellshock.io" @click="BAWK.play('ui_click')"><img class="home-screen-logo" src="img/logo.svg"></a>
<img v-if="eggOrg" class="egg-org-logo" src="img/egg-org/logo_EggOrg.svg">
</div>
<div class="main-content">
<div id="panel_front_play">
<div class="front_panel-events center_h">
<!-- <event-panel :show-soon="true" :show-ui="true"></event-panel> -->
<!-- <img @click="onTwitchDropsClick" title="Click here to manage your Twitch account on Shell Shockers" :src="twitchDropsBtnImgSrs" alt="Twitch drops parachute" class="events-twitch-drop"> -->
<button v-if="isTwitchEvent" class="ss_button twitch-btn btn_sm box_relative" @click="onTwitchDropsClick">Twitch Drops! <span v-html="isTwitchLinked"></span> <img class="box_absolute" src="img/twitch-drops/twitch-drops-parachute.svg" alt=""></button>
</div>
<play-panel id="play_game" ref="playPanel" :loc="loc" :player-name="playerName" :game-types="gameTypes" :current-game-type="currentGameType" :is-game-ready='accountSettled' :server-list="serverList" :current-server-id="currentServerId" :home="home" @playerNameChanged="onPlayerNameChanged"></play-panel>
<vip-club-cta :loc="loc" :upgrade-name="upgradeName" :is-upgraded="isUpgraded" :is-subscriber="isSubscriber" :has-mobile-reward="hasMobileReward" :is-black-fryday="isSale" :is-egg-org="eggOrg" :is-twitch-event="isTwitchEvent"></vip-club-cta>
</div>
<div id="panel_front_egg">
<div id="paper_doll_container"
class="paper-doll--click-container" @click="onEggPlayClick"></div>
<stats-panel id="stats_panel" :loc="loc" :kills="kills" :deaths="deaths" :kdr="kdr" :streak="streak"></stats-panel>
<weapon-select-panel id="weapon_select" :loc="loc" :current-class="classIdx"></weapon-select-panel>
<button class="ss_button btn_md btn_yolk bevel_yolk" @click="onEquipClicked">{{ loc.eq_equipment }}</button>
</div>
<div id="panel_front_news">
<media-tabs ref="mediaTabs" :loc="loc" :newsfeedItems="newsfeedItems" :twitchStreams="twitchStreams" :youtubeStreams="youtubeStreams"></media-tabs>
<!-- <house-ad-small id="banner-ad" :useAd="ui.houseAds.small"></house-ad-small> -->
<display-ad id="shellshockers_titlescreen_wrap" :hidden="hideAds" ref="titleScreenDisplayAd" class="house-small" :ignoreSize="true" :adUnit="adUnits.display.home" adSize="300x250"></display-ad>
</div>
<!-- <house-ad-small id="banner-ad" :useAd="ui.houseAds.small"></house-ad-small> -->
</div>
<!-- .main-content -->
</div>
<div id="mainFooter">
<!-- <chicken-panel ref="chickenPanel" id="chicken_panel" :local="loc" :do-upgraded="isUpgraded"></chicken-panel> -->
<footer-links-panel id="footer_links_panel" :loc="loc"></footer-links-panel>
</div>
<div id="gameDescription">
<h1 class="text-center">{{ loc.home_desc_about }}</h1>
<p class="text-center">{{ loc.home_desc_pick }}
<svg class="eggIcon"><use xlink:href="#icon-egg"></use></svg>
{{ loc.home_desc_loadout }}
<svg class="eggIcon"><use xlink:href="#icon-egg"></use></svg>
{{ loc.home_desc_madeof }}</p>
<section class="text-center">
<p>{{ loc.home_blocked_start }} Alt URL: geometry.best. {{ loc.home_blocked_end }}</p>
</section>
<div class="display-grid grid-column-2-eq grid-gap-1">
<section>
<p>{{ loc.home_desc_p1 }}</p>
<p>
<img src="img/eggPose05.png" style="width: 350px; float: left; margin-right: 1em; shape-outside: polygon(0% 0%, 100% 0%, 100% 41%, 84% 48%, 80% 63%, 59% 74%, 46% 100%, 0% 99%);">{{ loc.home_desc_p2 }}
</p>
</section>
<section>
<p>
<img src="img/eggPose01.png" style="float: right; margin-left: 1em; margin-top: 1em; shape-outside: polygon(1% 0%, 100% 1%, 100% 99%, 50% 100%, 28% 86%, 16% 68%, 14% 51%, 0 35%);">
{{ loc.home_desc_p3 }} <br /><br />
{{ loc.home_desc_p4 }}
</p>
</section>
</div>
<section>
<header>
<h2 class="text-center">{{ loc.home_game_mode_title }}</h2>
</header>
<ul class="display-grid grid-column-2-eq grid-gap-1">
<li v-html="loc.home_game_mode_content_li_1"></li>
<li v-html="loc.home_game_mode_content_li_2"></li>
<li v-html="loc.home_game_mode_content_li_3"></li>
<li v-html="loc.home_game_mode_content_li_4"></li>
</ul>
</section>
<h2 class="text-center">{{ loc.home_desc_controls }}</h2>
<p class="text-center">{{ loc.home_desc_standard }}</p>
<ul class="display-grid grid-column-2-eq" style="min-width: 25em;max-width: 35em;margin:0 auto">
<li> {{ loc.home_desc_control1 }}</li>
<li> {{ loc.home_desc_control2 }}</li>
<li> {{ loc.home_desc_control3 }}</li>
<li> {{ loc.home_desc_control4 }}</li>
<li> {{ loc.home_desc_control5 }}</li>
<li> {{ loc.home_desc_control6 }}</li>
<li> {{ loc.home_desc_control7 }}</li>
</ul>
<p class="text-center">
<button class="ss_button btn_lg btn_blue bevel_blue" @click="openUnblocked">{{ loc.home_unblocked_text }}</button>
</p>
<p>
{{ loc.home_desc_p7 }}
</p>
<p align="center"><button class="ss_button btn_yolk bevel_yolk" @click="vueApp.scrollToTop()">{{ loc.home_backtotop }}</button></p>
</div>
<!-- Popup: Check Email -->
<small-popup id="checkEmailPopup" ref="checkEmailPopup" :hide-cancel="true">
<template slot="header">{{ loc.p_check_email_title }}</template>
<template slot="content">
<p>{{ loc.p_check_email_text1 }}:</p>
<h5 class="nospace text-center">{{ maskedEmail }}</h5>
<p class="ss_marginbottom">{{ loc.p_check_email_text2 }}</p>
</template>
<template slot="confirm">{{ loc.ok }}</template>
</small-popup>
<!-- Popup: Resend Email -->
<small-popup id="resendEmailPopup" ref="resendEmailPopup" @popup-confirm="onResendEmailClicked">
<template slot="header">{{ loc.p_resend_email_title }}</template>
<template slot="content">
<p>{{ loc.p_resend_email_text1 }}:</p>
<h5 class="nospace text-center">{{ maskedEmail }}</h5>
<p class="ss_marginbottom">{{ loc.p_resend_email_text2 }}</p>
</template>
<template slot="cancel">{{ loc.ok }}</template>
<template slot="confirm">{{ loc.p_resend_email_resend }}</template>
</small-popup>
</div>
</script><script data-cmp-ab="1" src="https://c.delivery.consentmanager.net/delivery/cmp.php?id=13566cdid=abbb821549a1&h=https%3A%2F%2Fshellshockers.silkandpepper.com%2F&&__cmpfcc=1&l=en&o=1730107356203" type="text/javascript" async=""></script><script src="https://cdn.consentmanager.net/delivery/js/cmp_en.min.js" type="text/javascript" data-cmp-ab="1" async=""></script><iframe name="__cmpLocator" style="display: none;"></iframe><iframe name="__uspapiLocator" style="display: none;"></iframe><iframe name="__tcfapiLocator" style="display: none;"></iframe>
<script id="create-private-game-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_privatematch_title }}</h1>
<div class="box_blue2 roundme_sm fullwidth">
<div id="popupInnards" class="fullwidth f_row f_spaced">
<div id="private_left" class="f_col f_start">
<h3 class="text-center fullwidth">{{ loc.p_privatematch_gametype }}</h3>
<select name="gameType" v-model="pickedGameType" class="ss_select fullwidth" @click="BAWK.play('ui_click')" @change="onGameTypeChanged">
<option v-for="g in gameTypes" v-bind:value="g.value" :class="'create-game-' + g.locKey" v-html="loc[g.locKey]"></option>
</select>
<button class="ss_button button_blue bevel_blue fullwidth" @click="onServerClick">{{ loc.server }}: {{ loc[serverLocKey] }}</button>
<button name="play" @click="onPlayClick" class="ss_button btn_big fullwidth btn_green bevel_green btn_sm"><i class="fa fa-play fa-sm"></i> {{ loc.p_privatematch_create }}</button>
<!-- Player limit is not in place yet
<h3 class="nospace">{{ loc.p_privatematch_players }}</h3>
<div id="player_selector">
<img src="./img/ico_arrowLeft.png" class="numberArrow">
<input type="text" v-model class="ss_field fld_number">
<img src="./img/ico_arrowRight.png" class="numberArrow">
</div> -->
</div>
<div class="f_col j_start">
<h3 class="ss_marginleft_lg text-center">{{ loc.p_privatematch_selectmap }}</h3>
<div id="private_maps" class="ss_marginleft_lg roundme_md">
<img :src="mapImgPath" id="mapThumb" class="roundme_sm">
<div id="mapNav">
<button id="mapLeft" @click="onMapChange(-1)" class="clickme"> </button>
<h5 id="mapText" class="shadow_grey">
{{ vueData.maps[mapIdx].name }}
<span class="map_playercount shadow_grey roundme_sm">
<img src="img/ico_eggColour_normal.png">
<span class="ss_marginbottom_xs ss_marginright_xs">x</span>
<span>{{vueData.maps[mapIdx].numPlayers}}</span>
</span>
</h5>
<button id="mapRight" @click="onMapChange(1)" class="clickme"> </button>
</div>
</div>
</div>
</div>
<div id="btn_horizontal" class="f_center nospace">
<button @click="onCloseClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
</div>
</div>
</div>
</script>
<script>
var comp_create_private_game_popup = {
template: '#create-private-game-template',
props: ['loc', 'serverLocKey', 'mapImgBasePath', 'isGameReady'],
data: function () {
let mapIdx = Math.randomInt(0, vueData.maps.length);
let map = vueData.maps[mapIdx];
return {
showingServerList: false,
pickedGameType: 0,
gameTypes: vueData.gameTypes,
mapIdx: mapIdx,
mapImgPath: this.mapImgBasePath + map.filename + '.png?' + map.hash,
mapLocKey: map.locKey,
playClickedBeforeReady: false,
vueData,
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onCloseClick: function () {
this.$parent.close();
BAWK.play('ui_popupclose');
},
onServerClick: function () {
this.showingServerList = true;
this.$parent.toggle();
vueApp.$refs.homeScreen.$refs.playPanel.$refs.pickServerPopup.toggle();
BAWK.play('ui_click');
},
onMapChange: function (dir) {
this.selectMapForPickedGameType(dir);
BAWK.play('ui_onchange');
},
selectMapForPickedGameType (dir) {
let idx = this.mapIdx;
for (var i = 0; i < vueData.maps.length; i++) { // Prevent race condition
if (dir) idx = (idx + dir + vueData.maps.length) % vueData.maps.length;
let map = vueData.maps[idx];
let gameTypeShortName = vueData.gameTypeKeys[this.pickedGameType];
if (map.modes[gameTypeShortName]) {
break;
}
if (dir == 0) dir = 1
//idx = (idx + dir + vueData.maps.length) % vueData.maps.length;
}
this.mapImgPath = this.mapImgBasePath + vueData.maps[idx].filename + '.png?' + vueData.maps[idx].hash;
this.mapLocKey = vueData.maps[idx].locKey;
this.mapIdx = idx;
},
onGameTypeChanged () {
BAWK.play('ui_onchange');
this.selectMapForPickedGameType(0);
},
onPlayTypeWhenSignInComplete() {
return this.playClickFunction();
},
onPlaySentBeforeSignIn() {
this.gameClickedBeforeReady = true;
vueApp.showSpinner('signin_auth_title', 'signin_auth_msg');
},
onPlayClick: function () {
this.$parent.close();
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn();
return;
}
vueApp.externPlayObject(vueData.playTypes.createPrivate, this.pickedGameType, this.vueData.playerName, this.mapIdx, '');
BAWK.play('ui_playconfirm');
}
},
watch: {
isGameReady(val) {
if (this.gameClickedBeforeReady && val) {
setTimeout(() => this.onPlayClick(), 700);
}
}
}
};
</script><script id="account-panel-template" type="text/x-template">
<div>
<div id="account_top">
<!-- <eggstore-notify ref="shirtStore" :show="showCornerButtons" :loc="loc" :sku="sku" icon="fa-tshirt" :text-hide="true" text="p_egg_shop_sale_notify" title="account_threadless" color="blue" url="https://bluewizard.threadless.com/" analytics="threadless"></eggstore-notify> -->
<eggstore-notify ref="eggStoreSaleNotify" :text-hide="!hideNewItemNotify" :show="showCornerButtons" :loc="loc" :sku="sku" title="account_premium_item" icon="fa-gem" text="p_egg_shop_sale_notify" analytics="diamond"></eggstore-notify>
<button v-if="showVipButton" @click="onVipClick" class="ss_button btn_yolk bevel_yolk btn_vip" :title="loc['account_vip']" :class="{'has-sub' : isVipLive}"><img src="img/vip-club/vip-club-emblem-sm.png" alt="VIP Emblem"> {{vipButtonText}}</button>
<div class="account_eggs roundme_sm clickme" @click="onEggStoreClick" v-bind:title="loc['account_title_eggshop']">
<button v-if="isAnonymous" type="image" src="img/attention_indicator.png" v-show="showCornerButtons" @click="onAnonWarningClick" class="ss_button btn_yolk bevel_yolk attention_btn" v-bind:title="loc['account_title_shop']"><i class="fas fa-exclamation"></i></button>
<img src="img/ico_goldenEgg.png" class="egg_icon">
<span class="egg_count shadow_blue2_micro">{{ eggBalance }}</span>
</div>
<!-- <input type="image" src="img/ico_nav_leaderboards.png" class="account_icon roundme_sm"> -->
<div id="corner-buttons" v-show="showCornerButtons">
<input type="image" src="img/ico_nav_shop.png" @click="itemStoreClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_shop']">
<!-- <input type="image" src="img/ico_nav_help.png" @click="onHelpClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_faq']"> -->
<input type="image" src="img/ico_nav_share.png" v-show="showShareLinkButton" @click="onShareLinkClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_invite']">
<input type="image" src="img/ico_nav_settings.png" @click="onSettingsClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_settings']">
<input type="image" src="img/ico_nav_fullscreen.png" v-if="!vueData.isPoki && !crazyGamesActive" @click="onFullscreenClick" class="account_icon roundme_sm" v-bind:title="loc['account_title_fullscreen']">
</div>
</div>
<div id="account_bottom" v-show="showBottom">
<language-selector :languages="languages" :loc="loc" :selectedLanguageCode="selectedLanguageCode" :langOptions="currentLangOptions"></language-selector>
<button id="signInButton" v-show="(isAnonymous && showSignIn)" @click="onSignInClicked" class="ss_button btn_yolk bevel_yolk">{{ loc.sign_in }}</button>
<button id="signOutButton" v-show="!isAnonymous" @click="onSignOutClicked" class="ss_button btn_yolk bevel_yolk">{{ loc.sign_out }}</button>
<div id="player_photo" class="box_relative" v-show="photoUrl !== null && photoUrl !== undefined && photoUrl !== '' && ! isAnonymous">
<img :src="photoUrl" class="roundme_sm bevel_blue"/>
<div v-if="isTwitch" class="box_aboslute account-panel-twitch roundme_sm" @click="onTwitchIconClick"><i class="fab fa-twitch"></i></div>
</div>
</div>
</div>
</script>
<template id="egg-store-notify">
<div v-if="show" class="egg-store-sale-notify" :class="{'white-blue' : color}" @click="notifyClick">
<button class="account_icon roundme_sm account_icon-item" :title="getTitle"><i aria-hidden="true" class="fas" :class="icon"><span class="hideme">Egg</span></i>
<span class="text" :class="{hideme : textHide}"> {{loc[text]}}</span>
</button>
</div>
</template>
<script>
const compEggStoreSaleNotify = {
template: '#egg-store-notify',
props: ['loc', 'show', 'sku', 'textHide', 'text', 'icon', 'color', 'url', 'title', 'analytics'],
methods: {
notifyClick() {
if (this.analytics) ga('send', 'event', 'header-buttons', 'click', this.analytics);
if (this.url) {
window.open(this.url, '_window');
return;
}
// if (!vueData.firebaseId) {
// vueApp.showGenericPopup('p_redeem_error_no_player_title', 'p_redeem_error_no_player_content', 'ok');
// return;
// }
vueApp.eggStoreReferral = 'Sale notify ref';
if (this.sku) {
return vueApp.showPopupEggStoreSingle(this.sku)
}
return vueApp.onPremiumItemsClicked();
}
},
computed: {
getTitle() {
if (!this.title) return null;
return this.loc[this.title];
}
}
};
</script><script>
var comp_account_panel = {
template: '#account-panel-template',
components: {
'language-selector': comp_language_selector,
'eggstore-notify': compEggStoreSaleNotify,
},
props: ['loc', 'eggs', 'languages', 'selectedLanguageCode', 'showBottom', 'photoUrl', 'isAnonymous', 'isOfAge', 'showTargetedAds', 'showCornerButtons', 'ui', 'isEggStoreSale', 'sku', 'isSubscriber', 'isTwitch', 'currentLangOptions'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
eggBalance: 0,
vueData,
}
},
created() {
this.getEggsLocalStorage();
},
methods: {
getEggsLocalStorage() {
const raw = localStore.getItem('localLoadOut');
if (!raw) {
return;
}
const storage = JSON.parse(raw);
if (!'balance' in storage) {
return;
}
return this.eggBalance = storage.balance;
},
onEggStoreClick: function () {
if (!vueData.firebaseId) {
vueApp.showGenericPopup('p_redeem_error_no_player_title', 'p_redeem_error_no_player_content', 'ok');
return;
}
vueApp.showEggStorePopup();
BAWK.play('ui_popupopen');
this.gaSend('shoppingCart');
},
itemStoreClick: function() {
this.gaSend('openItemShop');
vueApp.switchToEquipUi();
vueApp.$refs.equipScreen.switchToShop();
BAWK.play('ui_popupopen');
},
onHelpClick: function () {
vueApp.showHelpPopup();
this.gaSend('openHelp');
BAWK.play('ui_popupopen');
},
onSettingsClick: function () {
this.gaSend('openSettings');
vueApp.showSettingsPopup();
BAWK.play('ui_popupopen');
},
onFullscreenClick: function () {
extern.toggleFullscreen();
BAWK.play('ui_click');
},
onSignInClicked: function () {
vueApp.setDarkOverlay(true);
this.$emit('sign-in-clicked');
BAWK.play('ui_playconfirm');
},
onSignOutClicked: function () {
vueApp.setDarkOverlay(true);
this.$emit('sign-out-clicked');
BAWK.play('ui_reset');
},
onShareLinkClick: function () {
this.gaSend('openShareLink');
extern.inviteFriends();
},
onAnonWarningClick: function() {
ga('send', 'event', vueApp.googleAnalytics.cat.playerStats, vueApp.googleAnalytics.action.anonymousPopupOpen);
vueApp.showAttentionPopup();
},
onVipClick() {
this.gaSend('openVipPopup');
vueApp.showSubStorePopup();
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'header-buttons', 'click', label);
},
onTwitchIconClick() {
window.open(dynamicContentPrefix + 'twitch');
}
},
computed: {
showSignIn: function () {
if (!isFromEU) {
return true;
}
return isFromEU && this.isOfAge && this.showTargetedAds;
},
showShareLinkButton: function () {
return this.showCornerButtons && (this.ui.showScreen === this.ui.screens.game);
},
hideNewItemNotify() {
// if (!ssChangelogDate) return false;
// if (!this.showCornerButtons) return false;
// const lapsed = Date.now() - ssChangelogDate.valueOf(),
// days = Math.floor((lapsed / (60*60*24*1000)));
// if (days <= 5 ) return true;
// return false;
return;
},
vipButtonText() {
return this.isSubscriber && !extern.account.upgradeIsExpired ? '' : this.loc['s-btn-txt-subscribe'];
},
showVipButton() {
return this.ui.showScreen === this.ui.screens.home || this.ui.showScreen === this.ui.screens.equip;
},
isVipLive() {
return this.isSubscriber && !extern.account.upgradeIsExpired;
}
},
watch: {
eggs() {
this.eggBalance = this.eggs;
}
}
};
</script>
<template id="stats_panel_template" type="text/x-template">
<div>
<!-- <h3 class="nospace">{{ loc.home_stats }}</h3> -->
<div class="stats-wrapper">
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.kills.toUpperCase() }}</h4>
<div class="stat_stat">{{ lKills }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.deaths.toUpperCase() }}</h4>
<div class="stat_stat">{{ lDeaths }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.kdr.toUpperCase() }}</h4>
<div class="stat_stat">{{ lKdr }}</div>
</div>
<div id="stat_item" class="roundme_sm">
<h4>{{ loc.streak.toUpperCase() }}</h4>
<div class="stat_stat">{{ lStreak }}</div>
</div>
</div>
</div>
</template>
<script>
var comp_stats_panel = {
template: '#stats_panel_template',
props: ['loc', 'kills', 'deaths', 'kdr', 'streak'],
data: () => {
return {
localLoadOut : Object,
lKills: 0,
lDeaths: 0,
lKdr: 0,
lStreak: 0,
}
},
created() {
this.getStatsLocalStorage();
},
methods: {
getStatsLocalStorage() {
const raw = localStore.getItem('localLoadOut');
if (!raw) {
return;
}
const storage = JSON.parse(raw);
const {kills, deaths, kdr, streak} = storage;
this.lKills = kills;
this.lDeaths = deaths;
this.lKdr = kdr;
this.lStreak = streak;
},
},
watch: {
kills() {
this.lKills = this.kills;
this.lDeaths = this.deaths;
this.lKdr = this.kdr;
this.lStreak = this.streak;
}
}
};
</script>
<script id="play-panel-template" type="text/x-template">
<div>
<div class="front_panel roundme_md">
<input name="name" :value="playerName" v-bind:placeholder="loc.play_enter_name" @change="onNameChange($event)" v-on:keyup="onPlayerNameKeyUp($event)" class="ss_field fullwidth"><br>
<div class="select-box-wrap">
<label for="create-select-type" class="ss_button btn_yolk bevel_yolk"><i class="fas fa-chevron-down"></i></label>
<select id="create-select-type" name="gameType" v-model="pickedGameType" class="ss_select select" @change="onGameTypeChange($event)">
<option v-for="g in gameTypes" v-bind:value="g.value" :class="'game-select-' + g.locKey" v-html="loc[g.locKey]"></option>
</select>
</div>
<br>
<button name="server" @click="onPickServerButtonClick" :disabled="isButtonDisabled" class="ss_button btn_blue bevel_blue fullwidth">{{ loc.server }}: {{ loc[serverLocKey] }}</button><br>
<button name="play" @click="onPlayButtonClick" class="ss_button btn_big btn_yolk bevel_yolk fullwidth nospace play-button"><i class="fa fa-play fa-sm"></i> {{ loc.home_play }}</button>
<h3>{{ loc.home_privategames }}</h3>
<div id="btn_horizontal" class="nospace">
<button name="create" @click="onCreatePrivateGameClick" class="ss_button btn_sm btn_blue bevel_blue">{{ loc.home_create }}</button>
<button name="join" @click="onJoinPrivateGameClick" class="ss_button btn_sm btn_blue bevel_blue">{{ loc.home_join }}</button>
</div>
</div>
<!-- Popup: Pick Server -->
<large-popup id="pickServerPopup" ref="pickServerPopup" @popup-closed="onPickServerPopupClosed">
<template slot="header">{{ loc.server }}</template>
<template slot="content">
<server-list-popup id="server_list_popup" ref="serverListPopup" v-if="(serverList.length > 0)" :loc="loc" :servers="serverList" :picked-server-id="currentServerId" @server-picked="onServerPicked"></server-list-popup>
</template>
</large-popup>
<!-- Popup: Create Private Game -->
<large-popup id="createPrivateGamePopup" ref="createPrivateGamePopup">
<template slot="content">
<create-private-game-popup id="createPrivateGame" ref="createPrivateGame" :loc="loc" :server-loc-key="serverLocKey" :is-game-ready="isGameReady" map-img-base-path="maps/"></create-private-game-popup>
</template>
</large-popup>
<!-- Popup: Join Private Game -->
<small-popup id="joinPrivateGamePopup" ref="joinPrivateGamePopup" :popup-model="home.joinPrivateGamePopup" @popup-confirm="onJoinConfirmed">
<template slot="header">{{ loc.p_game_code_title }}</template>
<template slot="content">
<div class="error_text shadow_red" v-show="home.joinPrivateGamePopup.showInvalidCodeMsg">{{ loc.p_game_code_blank }}</div>
<p><input type="text" class="ss_field ss_margintop ss_marginbottom fullwidth text-center" v-model="home.joinPrivateGamePopup.code" v-bind:placeholder="loc.p_game_code_enter" v-on:keyup.enter="onJoinConfirmed"></p>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
</div>
</script>
<script id="server-list-template" type="text/x-template">
<div>
<h1 class="roundme_sm">{{ loc.p_servers_title }}</h1>
<div v-for="s in servers" :key="s.id">
<div id="server_list_item">
<input type="radio" :id="('rb_' + s.id)" name="pickServer" v-bind:value="s.id" v-model="serverId" @click="BAWK.play('ui_onchange')">
<label :for="('rb_' + s.id)" class="serverName">{{ loc[s.locKey] }} </label>
<label :for="('rb_' + s.id)" class="serverPingWrap roundme_sm">
<span class="pingBar" :class="barColorClass(s)" :style="barStyle(s)"></span>
</label>
<label :for="('rb_' + s.id)" class="serverPingNumber ss_marginleft_lg"> {{ s.ping }}ms</label>
</div>
</div>
<div id="btn_horizontal" class="f_center">
<button @click="onCancelClick()" class="ss_button btn_red bevel_red btn_sm">{{ loc.cancel }}</button>
<button @click="onConfirmClick()" class="ss_button btn_green bevel_green btn_sm">{{ loc.ok }}</button>
</div>
</div>
</script>
<script>
var comp_server_list_popup = {
template: '#server-list-template',
props: ['loc', 'servers', 'pickedServerId'],
data: function () {
return {
colorClasses: ['greenPing', 'yellowPing','orangePing', 'redPing'],
serverId: this.pickedServerId
}
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
barColorClass: function (server) {
var colorIdx = Math.min(3, Math.floor(server.ping / 100));
return this.colorClasses[colorIdx];
},
barStyle: function (server) {
return {
width: Math.min(10, Math.max(0, server.ping / 100)) + 0.1 + 'em'
}
},
onCancelClick: function () {
this.serverId = this.pickedServerId;
this.$parent.close();
BAWK.play('ui_popupclose');
},
onConfirmClick: function () {
this.$emit('server-picked', this.serverId);
this.$parent.close();
BAWK.play('ui_playconfirm');
}
}
};
</script>
<script>
var comp_play_panel = {
template: '#play-panel-template',
components: {
'create-private-game-popup': comp_create_private_game_popup,
'server-list-popup': comp_server_list_popup
},
props: ['loc', 'playerName', 'gameTypes', 'currentGameType', 'serverList', 'currentServerId', 'home', 'isGameReady'],
// mounted() {
// this.kotcPrompt = document.getElementById('kotc-play-kotc');
// this.typeSelect = document.getElementById('create-select-type');
// this.anchorKotcPrompt();
// window.addEventListener('resize', this.anchorKotcPrompt);
// },
data: function() {
return {
pickedServerId: null,
pickedGameType: this.currentGameType,
isButtonDisabled: true,
playClickedBeforeReady: false,
playClickFunction: Function,
kotcPrompt: '',
typeSelect: ''
}
},
methods: {
onPickServerButtonClick: function () {
this.$refs.pickServerPopup.toggle();
BAWK.play('ui_popupopen');
},
onServerPicked: function (serverId) {
if (vueData.currentServerId === serverId) { return; }
vueData.currentServerId = serverId;
extern.selectServer(vueData.currentServerId);
BAWK.play('ui_onchange');
},
onPickServerPopupClosed: function () {
if (this.$refs.createPrivateGame.showingServerList) {
this.$refs.createPrivateGame.showingServerList = false;
this.$refs.createPrivateGamePopup.toggle();
}
},
onNameChange: function (event) {
console.log('name changed to: ' + event.target.value);
this.$emit('playerNameChanged', event.target.value);
},
onPlayerNameKeyUp: function (event) {
event.target.value = extern.filterUnicode(event.target.value);
event.target.value = extern.fixStringWidth(event.target.value);
event.target.value = event.target.value.substring(0, 128);
// Send username to server to start the game!
if (event.code == "Enter" || event.keyCode == 13) {
if (vueData.playerName.length > 0) {
extern.play({
playType: vueData.playTypes.joinPublic,
playerName: vueData.playerName
});
}
}
},
onGameTypeChange: function (event) {
extern.selectGameType(event.target.value);
BAWK.play('ui_onchange');
},
onPlayTypeWhenSignInComplete() {
return this.playClickFunction();
},
onPlaySentBeforeSignIn(callback) {
this.gameClickedBeforeReady = true;
vueApp.showSpinner('signin_auth_title', 'signin_auth_msg');
this.playClickFunction = callback;
},
hasValidPlayerNameCheck() {
console.log('invalid player name');
vueApp.showGenericPopup('play_pu_name_title', 'play_pu_name_content', 'ok');
vueApp.hideSpinner();
return;
},
onPlayButtonClick: function () {
if (!hasValue(this.playerName)) {
this.hasValidPlayerNameCheck();
return;
}
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn(this.onPlayButtonClick);
return;
}
vueApp.disablePlayButton(true);
vueApp.game.respawnTime = 0;
vueApp.externPlayObject(vueData.playTypes.joinPublic, this.pickedGameType, this.playerName, -1, '');
BAWK.play('ui_playconfirm');
},
onCreatePrivateGameClick: function () {
this.$refs.createPrivateGamePopup.toggle();
BAWK.play('ui_popupopen');
},
onJoinPrivateGameClick: function () {
this.showJoinPrivateGamePopup(vueData.home.joinPrivateGamePopup.code);
BAWK.play('ui_popupopen');
},
showJoinPrivateGamePopup: function (showCode) {
// The popup must be active before it will update; set code after showing
this.$refs.joinPrivateGamePopup.show();
vueData.home.joinPrivateGamePopup.code = showCode;
},
onJoinConfirmed: function () {
if (!hasValue(this.playerName)) {
this.hasValidPlayerNameCheck();
return;
}
if (!this.isGameReady) {
this.onPlaySentBeforeSignIn(this.onJoinConfirmed)
return;
}
let match = null;
if (vueData.home.joinPrivateGamePopup.code.match(/\#\w+/)) {
match = vueData.home.joinPrivateGamePopup.code.match(/\#\w+/)[0];
} else if (vueData.home.joinPrivateGamePopup.code.includes('crazyShare')) {
match = vueData.home.joinPrivateGamePopup.code.match(/=\w*$/)[0].substring(1);
}
else { // In case someone copy/pastes the thing without including the #
match = vueData.home.joinPrivateGamePopup.code;
}
if (!match) {
return;
}
vueData.home.joinPrivateGamePopup.code = match;
this.$refs.joinPrivateGamePopup.hide();
vueApp.externPlayObject(vueData.playTypes.joinPrivate, '', this.playerName, '', vueData.home.joinPrivateGamePopup.code);
},
kotcAttachSetup() {
const typePostion = this.typeSelect.getBoundingClientRect();
const kotcPrompt = this.kotcPrompt.getBoundingClientRect();
this.kotcPrompt.style.top = typePostion.top + 'px';
this.kotcPrompt.style.left = typePostion.right + 16 + 'px';
},
anchorKotcPrompt() {
this.$nextTick(() => this.kotcAttachSetup());
}
},
computed: {
serverLocKey: function () {
if (!hasValue(this.serverList) || this.serverList.length === 0) {
return '';
}
var server = this.serverList.find(s => {
return s.id == vueData.currentServerId;
});
return hasValue(server) ? server.locKey : '';
},
},
watch: {
currentGameType: function (val) {
this.pickedGameType = val;
},
isGameReady(val) {
this.isButtonDisabled = val ? false : true;
if (this.gameClickedBeforeReady && val) {
this.onPlayTypeWhenSignInComplete()
}
}
}
};
</script><template id="weaponselect_panel_template" type="text/x-template">
<div :class="{disabled: !vueData.accountSettled}">
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_EggK47.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Soldier)" @click="selectClass(charClass.Soldier)"><span><strong>{{loc.weapon_soldier_title}}:</strong> {{loc.weapon_soldier_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Scrambler.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Scrambler)" @click="selectClass(charClass.Scrambler)"><span><strong>{{loc.weapon_scrambler_title}}: </strong> {{loc.weapon_scrambler_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_FreeRanger.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Ranger)" @click="selectClass(charClass.Ranger)"><span><strong>{{loc.weapon_ranger_title}}: </strong>{{loc.weapon_ranger_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_RPEGG.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Eggsploder)" @click="selectClass(charClass.Eggsploder)"><span><strong>{{loc.weapon_eggsploder_title}}: </strong> {{loc.weapon_eggsploder_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Whipper.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Whipper)" @click="selectClass(charClass.Whipper)"><span><strong>{{loc.weapon_whipper_title}}: </strong>{{loc.weapon_whipper_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_Crackshot.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.Crackshot)" @click="selectClass(charClass.Crackshot)"><span><strong>{{loc.weapon_crackshot_title}}: </strong>{{loc.weapon_crackshot_content}}</span>
</div>
<div class="tool-tip">
<img src="img/weapon-icons/ico_weapon_TriHard.svg" class="weapon_img roundme_lg" :class="addSelectedCssClass(charClass.TriHard)" @click="selectClass(charClass.TriHard)"><span><strong>{{loc.weapon_trihard_title}}: </strong>{{loc.weapon_trihard_content}}</span>
</div>
</div>
</template>
<script>
var comp_weapon_select_panel = {
template: '#weaponselect_panel_template',
props: ['currentClass', 'loc'],
data: function () {
return {
charClass: CharClass,
vueData,
}
},
methods: {
selectClass: function (classIdx) {
if (!vueData.accountSettled){
return;
}
extern.changeClass(classIdx);
this.$emit('changed-class', classIdx);
BAWK.play('ui_click');
},
addSelectedCssClass: function (classIdx) {
return (this.currentClass === classIdx)
? 'weapon_selected'
: '';
},
}
// watch: {
// accountSettled(val) {
// }
// }
};
</script>
<script id="newsfeed-panel-template" type="text/x-template">
<section class="v_scroll">
<article v-if="items" v-for="item in activeItems" :key="item.id" @click="onItemThatIsClicked(item)" class="news_item roundme_md clickme">
<img :src="imageSrc(item)" class="news_img roundme_sm">
<p>{{ item.content }}</p>
</article>
</section>
</script>
<script>
var comp_newsfeed_panel = {
template: '#newsfeed-panel-template',
props: ['items'],
data: function () {
return vueData;
},
// mounted: function () {
// // this.fetchWebData();
// this.checklocalForNewsData();
// },
methods: {
imageSrc(item) {
return dynamicContentPrefix + 'data/img/newsItems/' + item.id + item.imageExt;
},
onItemThatIsClicked(item) {
console.log(item);
extern.clickedWebFeedItem(item);
BAWK.play('ui_click');
},
},
computed: {
activeItems() {
return this.items.filter(item => item.active);
}
}
};
</script><script id="chicken-panel-template" type="text/x-template">
<div id="showBuyPassDialogButton" class="new">
<div class="chicken-panel--upgraded" v-show="doUpgraded && !isSubscriber">
<div class="tool-tip tool-tip--right">
<span v-if="nugCounter" id="nugget-countdown">{{nugCounter}} Minutes remaining.</span>
<img class="upgraded-nugget" src="img/chicken-nugget/goldenNugget_static.png">
<!-- <div id="nugget-timer" class="nugget-timer--wrapper">
<div class="timer-background"></div>
<div class="timer spinner"></div>
<div class="timer filler"></div>
<div class="mask"></div>
</div> -->
</div>
</div>
<div class="chicken-panel--no-upgraded" v-show="!doUpgraded">
<img src="img/chicken-nugget/starburst.png" @click="onChickenClick" class="clickme starburst">
<img src="img/chicken-nugget/goldenNuggetGIFWIP.gif" @click="onChickenClick" class="clickme nugget-chick">
<div id="buyPassChickenSpeech">
<img src="img/speechtail.png" class="buyPassChickenSpeechTail">
<span v-html="loc.chicken_cta"></span>
</div>
</div>
</div>
</script>
<script>
var comp_chicken_panel = {
template: '#chicken-panel-template',
props: ['local', 'doUpgraded'],
data: function () {
return vueData;
},
methods: {
onChickenClick: function () {
BAWK.play('ui_chicken');
vueApp.showGoldChickenPopup();
ga('send', 'event', this.googleAnalytics.cat.purchases, 'Golden Chicken Click');
},
},
};
</script><script id="footer-links-panel-template" type="text/x-template">
<footer class="main-footer display-grid grid-column-1-2">
<div class="social-icons">
<social-panel id="social_panel"></social-panel>
</div>
<nav class="footer-nav text-left">
<a @click="onChangelogClicked" class="clickme">{{ version }}</a> |
<!-- <a href="https://shell-shockers.myshopify.com/collections/all" target="_blank" @click="BAWK.play('ui_click')">{{ loc.footer_merchandise }}</a> | -->
<a href="https://www.bluewizard.com/privacypolicy" target="_blank" @click="playSound">{{ loc.footer_privacypolicy }}</a> |
<a href="https://bluewizard.com/terms/" target="_blank" @click="playSound">{{ loc.footer_termsofservice }}</a> |
<button class="ss_button_as_text" @click="onHelpClick">{{ loc['account_title_faq'] }}</button> |
<a href="https://www.bluewizard.com" target="_blank" @click="playSound">© 2022 <img class="main-footer--logo-blue-wiz-mini" src="img/blue-wizard-logo-tiny-min.png" :alt="loc.footer_bluewizard + ' logo'"><span class="hideme">{{ loc.footer_bluewizard }}</span></a>
</nav>
</footer>
</script>
<script id="social-panel-template" type="text/x-template">
<div class="social_icons roundme_sm">
<a href="http://eepurl.com/dFPPwb" target="_blank" class="f_col f_center ss_marginright bg_blue4" @click="playSound('newYolker')">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Get the Shell Shocker's Newsletter: The New Yolker</span>
<i aria-hidden="true" class="text_blue1 fas fa-envelope-open-text"></i>
</div>
</a>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Facebook" reward="Facebook" url="https://www.facebook.com/bluewizarddigital" img="footer-social-media-bubble-facebook.png" icon="fa-facebook" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Twitter" reward="Twitter" url="https://twitter.com/bluewizardgames" img="footer-social-media-bubble-twitter.png" icon="fa-twitter" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Instagram" reward="Instagram" url="https://www.instagram.com/bluewizardgames/" img="footer-social-media-bubble-instagram.png" icon="fa-instagram" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="TikTok" reward="tiktok" url="https://www.tiktok.com/@bluewizarddigital" img="footer-social-media-bubble-tiktok.png" icon="fa-tiktok" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Discord" reward="discord" url="https://discord.gg/bluewizard" img="footer-social-media-bubble-discord.png" icon="fa-discord" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Steam" reward="Steam" url="https://store.steampowered.com/publisher/bluewizard" img="footer-social-media-bubble-steam.png" icon="fa-steam-symbol" :isActive="false"></social-promo>
<!-- ['name', 'reward', 'url', 'img', 'icon'] -->
<social-promo name="Twitch" reward="Twitch" url="https://www.twitch.tv/bluewizarddigital" img="footer-social-media-bubble-twitch.png" icon="fa-twitch" :isActive="true"></social-promo>
</div>
</script>
<script id="social-promo-template" type="text/x-template">
<div>
<div v-if="isActive" class="tool-tip" :class="{'active' : isBubbleActive}">
<a :href="url" target="_blank" :title="urlTitle" class="f_col f_center ss_marginright bg_blue4" @click="onClickReward()">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Vist Shell Shocker's {{ name }} page</span>
<i aria-hidden="true" class="text_blue1 fab" :class="icon"></i>
</div>
</a>
<div class="tool-tip--bubble" v-if="!itemRedeemed && bubbleHover">
<div class="tool-tip--group display-grid grid-column-1-2">
<div class="tool-tip--image box_relative">
<img class="discord-bubble-img box_absolute" :src="imgSrc" :alt="imgAlt">
</div>
<div class="tool-tip--text text-left">
<strong><i>Follow us<br /> on {{name}}</i></strong> <br /> for a free Hat!
</div>
</div>
<!-- .tool-tip--group -->
</div>
<!-- .tool-tip--bubble -->
</div>
<!-- .tool-tip -->
<a v-if="!isActive" :href="url" target="_blank" class="f_col f_center ss_marginright bg_blue4" @click="onClickReward()">
<div class="icon-wrap bg_blue3 roundme_sm">
<span class="sr-only">Vist Shell Shocker's {{ name }} page</span>
<i aria-hidden="true" class="text_blue1 fab" :class="icon"></i>
</div>
</a>
</div>
</script>
<script>
var COMPSOCIALPROMO = {
template: '#social-promo-template',
props: ['name', 'reward', 'url', 'img', 'icon', 'isActive'],
data: function () {
return {
isBubbleActive: true,
bubbleRepeat : '',
bubbleHover: true,
}
},
created() {
this.discordBubbleTimer();
},
methods: {
playSound (label) {
BAWK.play('ui_click');
this.gaSend(label);
},
discordBubbleTimer() {
if (this.itemRedeemed) {
this.isBubbleActive = false;
this.bubbleHover = false;
return;
}
this.bubbleRepeat = setInterval(() => {
this.isBubbleActive = this.isBubbleActive ? false : true;
}, 3000);
},
onClickReward() {
this.gaSend(this.reward);
console.log('onClickReward', this.reward);
const rewardGiven = localStore.getItem(`${this.reward}Rewarded`);
if (!hasValue(rewardGiven)) {
extern.socialReward(this.reward);
}
this.playSound();
this.isBubbleActive = false;
this.bubbleHover = false;
if (this.bubbleRepeat) {
clearInterval(this.bubbleRepeat);
}
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'social-buttons', 'click', label);
}
},
computed: {
itemRedeemed() {
return localStore.getItem(this.reward + 'Rewarded');
},
urlTitle() {
return `Blue Wizard ${this.name} page`;
},
imgAlt() {
return `Join Blue Wizard's ${this.name} page`;
},
imgSrc() {
return `img/social-media/${this.img}`;
}
}
};
</script><script>
var comp_social_panel = {
template: '#social-panel-template',
components: {
'social-promo': COMPSOCIALPROMO
},
data: function () {
return {
isBubbleActive: true,
bubbleRepeat : '',
bubbleHover: true,
rewardName: 'Twitch'
}
},
created() {
this.discordBubbleTimer();
},
methods: {
playSound (label) {
BAWK.play('ui_click');
this.gaSend(label);
},
discordBubbleTimer() {
if (this.itemRedeemed) {
this.isBubbleActive = false;
this.bubbleHover = false;
return;
}
this.bubbleRepeat = setInterval(() => {
this.isBubbleActive = this.isBubbleActive ? false : true;
}, 3000);
},
onClickReward(type) {
this.gaSend(type);
console.log('onClickReward', type);
const rewardGiven = localStore.getItem(`${type}Rewarded`);
if (!hasValue(rewardGiven)) {
extern.socialReward(type);
}
this.playSound();
this.isBubbleActive = false;
this.bubbleHover = false;
if (this.bubbleRepeat) {
clearInterval(this.bubbleRepeat);
}
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'social-buttons', 'click', label);
}
},
computed: {
itemRedeemed() {
return localStore.getItem(this.rewardName + 'Rewarded');
},
}
};
</script>
<script>
var comp_footer_links_panel = {
template: '#footer-links-panel-template',
components: {
'social-panel': comp_social_panel,
},
props: ['loc'],
data: function () {
return {
version: version
}
},
methods: {
onChangelogClicked: function () {
vueApp.showChangelogPopup();
BAWK.play('ui_popupopen');
},
playSound() {
BAWK.play('ui_click');
},
onHelpClick() {
vueApp.showHelpPopup();
this.gaSend('openHelp');
BAWK.play('ui_popupopen');
}
}
};
</script>
<template id="comp-vip-cta">
<div class="vip-club-cta" v-on:click="onClicked">
<button v-if="!isSubscriber && !isUpgraded && showVip" class="vip-club-cta-pos ss_button btn_sm btn_pink bevel_pink">
{{ loc.ui_game_playeractions_join_vip }}
</button>
<h4 v-if="isUpgraded && isSubscriber && showVip" class="sub-name">
{{loc[subName]}}
</h4>
<img class="roundme_md" :class="{ 'egg-org-img' : isEggOrg }" :src="getImgSrc" :alt="getImgSrcAlt">
</div>
</template>
<script>
const compVipCta = {
template: '#comp-vip-cta',
props: ['loc', 'upgradeName', 'isUpgraded', 'isSubscriber', 'hasMobileReward', 'isBlackFryday', 'isEggOrg', 'isTwitchEvent'],
data() {
return {
subName: '',
hasPlayedKotc: null,
kotcImgSrc: 'img/kotc/new-game-mode-king-of-coop.png',
vipImgSrc: 'img/vip-club/vip-club-call-to-action.png',
mobileImgSrc: 'img/mobile/shell-mobile-cta-min.png',
blackFrydayImgSrc: 'img/store-black-friday/black-fryday-home-screen-ad.png',
helpUkraine: 'img/stand-with-ukraine-min.png',
eggOrg: 'img/egg-org/eggOrg_timeTravel_houseAd2-min.jpg',
twitchSrc: 'img/twitch-drops/TwitchDrops2022-HouseAd_536x307-min.jpg'
};
},
mounted() {
this.hasPlayedKotc = localStore.getItem('hasPlayedKotc');
},
methods: {
onClicked() {
if (this.isEggOrg) {
vueApp.showSelectedTaggedItemsOnEquipScreen('EGGORG');
ga('send', 'event', 'home-display-ad', 'click', 'egg-org');
return;
}
// above all else show sale
if (this.isBlackFryday) {
vueApp.showEggStorePopup();
ga('send', 'event', 'home-display-ad', 'click', 'black-fryday');
return;
}
// promote KOTC
if (this.hasPlayedKotc) {
ga('send', 'event', 'home-display-ad', 'click', 'item_hat_ukraine');
// ga('send', 'event', 'home-display-ad', 'click', 'kotc-popup');
// vueApp.showKotcInstrucPopup();
vueApp.showPopupEggStoreSingle('item_hat_ukraine');
// localStore.setItem('hasPlayedKotc', true);
return;
}
if (this.isTwitchEvent) {
ga('send', 'event', 'home-display-ad', 'click', 'twitch-drops');
open('https://shellshock.io/twitch/?utm_medium=referral&utm_campaign=featureslot', '_blank');
}
// if has mobile item
if (this.hasMobileReward) {
let vipType = 'vip-ad';
if (this.isUpgraded && this.sSubscriber) {
let vipType = 'vip-manage';
}
ga('send', 'event', 'home-display-ad', 'click', vipType);
vueApp.showSubStorePopup();
return;
} else {
ga('send', 'event', 'home-display-ad', 'click', 'mobile-ad');
vueApp.showGetMobilePopup();
}
},
test() {
this.isBlackFryday = false;
this.hasPlayedKotc = true;
this.hasMobileReward = true;
}
},
computed: {
getImgSrc() {
if (this.isEggOrg) {
return this.eggOrg;
}
if (this.isBlackFryday) {
return this.blackFrydayImgSrc;
}
if (this.hasPlayedKotc) {
return this.kotcImgSrc;
}
if (this.hasMobileReward) {
return this.vipImgSrc;
} else {
return this.mobileImgSrc;
}
if (this.isTwitchEvent) {
return twitchSrc;
}
},
getImgSrcAlt() {
if (this.isEggOrg) {
return 'EggOrg is back!';
}
if (this.isBlackFryday) {
return 'BLACK FRYDAY SALE!';
}
if (this.hasPlayedKotc) {
return 'Click to learn how to play King of the Coop!;';
}
if (this.hasMobileReward) {
return 'Manage VIP';
} else {
return 'Download mobile today!';
}
if (this.isTwitchEvent) {
return 'Get your drops today!';
}
},
showVip() {
return false;
if (!this.hasPlayedKotc || !this.hasMobileReward || this.isBlackFryday) {
return false;
} else {
return true;
}
},
},
watch: {
upgradeName(val) {
if (!hasValue(val)) {
return;
}
this.subName = `s-${val.replace(' ', '-').toLowerCase().replace(' ', '-')}-title`;
}
}
};
</script><script id="media-tabs-template" type="text/x-template">
<div class="media-tabs-container">
<div id="horizontalTabs" class="media-tab-container">
<button id="news-tab" @click="selectTab" class="media-tab ss_smtab ss_marginright" :class="(showNewsTab ? 'selected' : '')"><i class="fas fa-bullhorn"></i></button>
<button id="twitch-tab" @click="selectTab" class="media-tab ss_smtab ss_marginright" :class="(showTwitchTab ? 'selected' : '')"><i class="fab fa-twitch"></i></button>
<button id="video-tab" v-if="youtubeStreams.length > 0" @click="selectTab" class="media-tab ss_smtab" :class="(showVideoTab ? 'selected' : '')"><i class="fab fa-youtube"></i></button>
</div>
<div class="front_panel media-tabs-content roundme_sm f_col" :class="{'tab-news-active' : showNewsTab}">
<div id="news-tab" v-show="showNewsTab">
<h3 class="nospace shadow_blue4 text_white">{{ loc.home_latestnews }}</h3>
<div class="news-container f_row ss_margintop">
<div class="news_mask"></div>
<newsfeed-panel id="news_scroll" class="home-tab-scroll" ref="newsScroll" :items="newsfeedItems"></newsfeed-panel>
</div>
</div>
<!-- #news-tab -->
<div id="twitch-tab" v-show="showTwitchTab">
<h3 class="nospace shadow_blue4 text_white">
Twitch <button id="tab-twitch-btn" @click="onApplyNowClick" class="ss_button btn_md btn_yolk btn-media bevel_yolk">{{loc.home_media_apply_now}}</button>
</h3>
<div class="f_row ss_margintop">
<streamer-panel id="twitch_panel" :loc="loc" :streams="twitchStreams" :title="loc.twitch_title" :viewers="loc.twitch_viewers" icon="ico_twitch"></streamer-panel>
</div>
</div>
<!-- #twitch-tab -->
<div id="video-tab" v-show="showVideoTab">
<h3 class="nospace shadow_blue4 text_white">
YouTube <button id="tab-youtube-btn" @click="onApplyNowClick" class="ss_button btn_md btn_yolk btn-media bevel_yolk">{{loc.home_media_apply_now}}</button>
</h3>
<div class="news-container f_row ss_margintop">
<div class="news_mask"></div>
<div id="yTube-scroll" class="home-tab-scroll v_scroll">
<div v-for="item in youtubeStreams" :key="item.id" v-if="item.active" @click="onVideoClick(item)" class="news_item ytube-item roundme_md clickme">
<div class="image-wrap news_img roundme_sm">
<img :src="item.externalImg" alt="" class="news_img roundme_sm" />
</div>
<div class="content-wrap f_col f_space_between">
<p><strong>{{ item.title }}</strong></p>
<p v-if="item.desc">{{ item.desc }}</p>
<p class="text-right">{{ item.author }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- .media-tabs-content -->
</div>
<!-- .media-tabs-container -->
</script>
<script id="streamer-panel-template" type="text/x-template">
<div class="panel_streamer noscroll">
<div v-if="show" id="stream_mask"></div>
<div id="stream_scroll" class="home-tab-scroll v_scroll" v-show="show">
<div class="stream_item roundme_sm clickme" v-for="s in streams">
<a :href="s.link" target="_blank" @click="BAWK.play('ui_click')" class="display-grid grid-column-1-2">
<img :src="s.image" class="stream_img roundme_sm">
<span>
<p class="stream_name">{{ s.name }}</p>
<p class="stream_viewers">{{ s.viewers }} {{ viewers }}</p>
</span>
</a>
</div>
</div>
<div class="no-stream roundme_sm" v-if="!show">
<p v-html="loc.twitch_no_steam"></p>
</div>
</div>
</script>
<script>
var comp_streamer_panel = {
template: '#streamer-panel-template',
props: ['streams', 'title', 'viewers', 'icon', 'loc'],
methods: {
playSound (sound) {
BAWK.play(sound);
}
},
computed: {
show: function() {
if (!this.streams) {
return false;
}
return this.streams.length > 0;
}
}
};
</script>
<script>
const MEDIATABS = {
template: '#media-tabs-template',
components: {
'newsfeed-panel': comp_newsfeed_panel,
'streamer-panel': comp_streamer_panel,
},
props: ['loc', 'newsfeedItems', 'twitchStreams', 'youtubeStreams'],
created() {
this.$nextTick(() => {
this.randomTabSelect();
});
},
mounted() {
// VUE!!!!!!!!!!!
setTimeout(() => this.getAllTabs(), 500);
},
data: function () {
return {
mediaTabs: [],
mediaTabsCount: 0,
rotateTimeout: '',
showNewsTab: false,
showTwitchTab: false,
showVideoTab: false,
currentTab: ''
}
},
methods: {
getAllTabs() {
this.$nextTick(() => {
let ids = [],
tabs = Array.from(document.querySelectorAll('.media-tab')).forEach(tab => ids.push(tab.id));
this.mediaTabs = ids;
this.mediaTabsCount = this.mediaTabs.length - 1;
this.autoRotateTabs();
});
},
selectTab: function (e) {
ga('send', 'event', 'media-tabs', 'click', e.currentTarget.id);
return this.switchTab(e.currentTarget.id, true, true)
},
autoRotateTabs() {
let nextIdx = this.mediaTabs.indexOf(this.currentTab) + 1;
if (nextIdx > this.mediaTabsCount) nextIdx = 0;
this.rotateTimeout = setTimeout(() => {
this.switchTab(this.mediaTabs[nextIdx], false, false);
this.autoRotateTabs();
}, 10000);
},
randomTabSelect() {
let n = Math.floor(Math.random() * 9);
if (n >= 0 && n <= 2) {
this.showNewsTab = true;
this.currentTab = 'news-tab';
} else if (n >= 3 && n <= 5) {
this.showTwitchTab = true;
this.currentTab = 'twitch-tab';
} else {
this.showVideoTab = true;
this.currentTab = 'video-tab';
}
},
onVideoClick(item) {
ga('send', 'creator', 'videoClick', item.title);
window.open(item.link, '_window');
},
onApplyNowClick(e) {
ga('send', 'creator', 'applyNow', e.target.id);
window.open('https://shellcreators.bluewizard.com', '_window');
},
switchTab(tab, sound, click) {
this.showNewsTab = false;
this.showTwitchTab = false;
this.showVideoTab = false;
switch (tab) {
case 'news-tab':
this.currentTab = 'news-tab';
this.showNewsTab = true;
break;
case 'twitch-tab':
this.currentTab = 'twitch-tab';
this.showTwitchTab = true;
break;
case 'video-tab':
this.currentTab = 'video-tab';
this.showVideoTab = true;
break;
}
if (sound) {
BAWK.play('ui_toggletab');
}
if (click) {
ga('send', 'creator', 'tabClick', this.currentTab);
this.cancelRotate(false);
}
},
cancelRotate(stop) {
clearTimeout(this.rotateTimeout);
this.rotateTimeout = '';
if (!stop) {
this.autoRotateTabs();
}
}
}
};
</script><template id="music-widget">
<div v-if="isMusic" class="music-widget roundme_md" :class="[!show ? hideClass : '']">
<div v-if="theAudio" class="music-widget--wrapper flex flex-nowrap">
<figure class="music-widget--content">
<header class=" roundme_md">
<h3 class="music-widget--now-playing">{{ loc.musicwidget_now_playing }}</h3>
</header>
<figcaption class="music-widget--content-wrapper">
<h4 class="music-widget--album-title">{{ serverTracks.artist }}</h4>
</figcaption>
<figcaption class="music-widget--content-wrapper">
<p v-if="serverTracks.url" class="music-widget--song-title"><a @click="gaSendEvent('click-track', getTitleAlbum)" :href="serverTracks.url" :title="theTitleAttr" target="_blank">{{ getTitleAlbum }}</a></p>
<p v-else="" class="music-widget--song-title">{{ getTitleAlbum }}</p>
</figcaption>
<div v-if="volumeSlider" v-for="t in settingsUi.adjusters.music" class="music-widget--volume-control nowrap">
<slider-component :loc="loc" :loc-key="t.locKey" :control-id="t.id" :control-value="t.value" :min="t.min" :max="t.max" :step="t.step" :multiplier="t.multiplier" @setting-adjusted="volumeControl"></slider-component>
</div>
</figure>
<div class="music-widget--cover-image music-widget--cover-controls roundme_md">
<template v-if="serverTracks.url">
<a v-if="serverTracks.albumArt" @click="gaSendEvent('click-albumArt', getTitleAlbum)" :href="serverTracks.url" :title="theTitleAttr" class="ss-absolute" target="_blank"><img :src="serverTracks.albumArt" class="roundme_md ss-absolute" :alt="serverTracks.album"></a>
</template>
<template v-else="">
<img v-if="serverTracks.albumArt" :src="serverTracks.albumArt" class="ss-absolute roundme_md" alt="Album cover art for" :alt="serverTracks.album">
</template>
<button v-if="playBtn" @click="playAudio">
<i v-if="playing" class="music-widget--cover-control-icon music-widget--cover-control-pause far fa-pause-circle fa-2x"></i>
<i v-if="!playing" class="music-widget--cover-control-icon music-widget--cover-control-pause far fa-play-circle fa-2x"></i>
</button>
</div>
<div class="music-widget--sponsor">
<a @click="gaSendEvent('click-sponsor', sponsor.name)" v-if="sponsor" :href="sponsor.link" :title="getSponsorTitleAttr" target="_blank"><img :src="getSponsorImg" class="music-widget--sponsor-icon" :alt="sponsor.name"><span class="hideme">{{sponsor.name}}</span></a>
<button v-if="settings" @click="openSettings" class="music-widget--sponsor--settings-btn"><i class="fas fa-cog"></i><span class="hideme">Music Settings</span></button>
<button class="music-widget--sponsor--settings-btn" @click="toggleMusic"><i class="fas" aria-hidden="true" :class="togglePlayStopIcon"></i><span class="hideme">Music</span></button>
</div>
</div>
</div>
</template>
<script>
const createMusicWidget = templateId => {
return {
template: '#music-widget',
props: ['loc','volumeSlider', 'playBtn', 'settings', 'settingsUi', 'show'],
components: {
'slider-component': comp_settings_adjuster
},
data () {
return vueData.music;
},
mounted () {
this.theAudio = document.getElementById('theAudio');
},
methods: {
loadVolume() {
this.$nextTick(() => {
this.theAudio.volume = Number(this.settingsUi.adjusters.music[0].value);
});
},
getAudioServer() {
if (parsedUrl.dom == 'localhost' || parsedUrl.dom == 'dev' || parsedUrl.dom == 'localshelldev') {
var url = 'uswest2-music.shellshock.io';
}
else {
var server = vueApp.serverList.filter(server => server.locKey === vueApp.currentServerLocKey)[0];
var url = server.subdom.slice(0, -1) + '-music.' + parsedUrl.dom + '.' + parsedUrl.top;
}
this.musicSrc = 'https://' + url + '/shellshock.ogg';
},
setIndex(k) {
this.$nextTick(() => {
this.play();
})
this.currIndex = k;
},
play() {
if (!this.isMusic) return;
this.getAudioServer();
},
playMusic() {
// var audio = this.theAudio;
this.theAudio.src = this.musicSrc;
console.log('Play Music');
clearInterval(this.timer);
this.theAudio.play()
.then( // Returns a Promise
() => { // Success
this.playing = true;
this.loadVolume();
this.duration = this.theAudio.duration;
this.theAudio.addEventListener('stalled', () => this.isMusic = false);
},
() => { // Fail
// What to do... just try again after a few seconds, I guess?
setTimeout(() => this.play(), 2000);
}
);
},
pause() {
this.playing = false;
this.theAudio.pause();
clearInterval(this.timer);
},
/*
next() {
if (this.currIndex < this.tracks.length - 1) {
this.currIndex++;
} else {
this.currIndex = 0;
}
},
prev() {
if (this.currIndex > 0) {
this.currIndex--;
} else {
this.currIndex = this.tracks.length - 1;
}
},
*/
playOnce() {
if (this.playing) return;
return this.play();
},
playAudio() {
if (this.theAudio.paused) {
this.play();
} else {
this.pause();
}
},
openSettings() {
vueApp.showSettingsPopup();
vueApp.onSettingsPopupSwitchTabMisc();
this.gaSendEvent('click', 'widgetOpenSettings');
},
volumeControl(id, value) {
extern.setMusicVolume(value);
vueApp.onSettingsQuickSave();
},
hideMe() {
return this.$refs.id.classList.addClass('fade-out-3');
},
showMe() {
this.show = true;
setTimeout(() => this.show = false, 2000);
},
gaSendEvent(action, label) {
action = action || '';
label = label || '';
return ga('send', 'event', 'music', action, label);
},
toggleMusic() {
if (this.playing) {
this.theAudio.removeEventListener('stalled', () => this.isMusic = false);
this.playing = false;
this.pause();
this.musicSrc = '';
this.theAudio.removeAttribute('src');
extern.setMusicStatus(false);
this.gaSendEvent('toggleMusic', 'off');
return;
}
this.theAudio.src = '';
this.play();
extern.setMusicStatus(true);
this.gaSendEvent('toggleMusic', 'on');
},
changeVolume(val) {
this.theAudio.volume = val;
}
},
watch: {
'currIndex': {
handler() {
this.$nextTick(() => {
this.play();
})
}
},
serverTracks(val) {
let sponsor = this.sponsors.filter(sponsor => sponsor.id === val.sponsor);
this.sponsor = sponsor.length || sponsor.length > 0 ? sponsor[0] : '';
},
musicSrc(val) {
if (val) {
this.playMusic();
}
},
},
computed: {
theTitleAttr() {
return 'Read more about ' + this.serverTracks.title;
},
getTitleAlbum() {
return this.serverTracks.title + ' - ' + this.serverTracks.album;
},
getSponsorImg() {
if (!this.sponsor) {
return;
}
return 'data/img/sponsor/' + this.sponsor.id + this.sponsor.imageExt;
},
getSponsorTitleAttr() {
return 'See more about our sponsor ' + this.sponsor.name;
},
togglePlayStopIcon() {
return this.playing ? 'fa-stop-circle' : 'fa-play-circle';
},
},
};
};
// Register component globally
Vue.component('music-widget', createMusicWidget('#music-widget'));
</script>
<script>
var comp_home_screen = {
template: '#home-screen-template',
components: {
'stats-panel': comp_stats_panel,
'play-panel': comp_play_panel,
'weapon-select-panel': comp_weapon_select_panel,
'house-ad-big': comp_house_ad_big,
'house-ad-small': comp_house_ad_small,
'account-panel': comp_account_panel,
'chicken-panel': comp_chicken_panel,
'footer-links-panel': comp_footer_links_panel,
'event-panel': comp_events,
'vip-club-cta': compVipCta,
'media-tabs': MEDIATABS
// 'pwa-button': comp_pwa_btn,
},
data: function () {
return vueData;
},
methods: {
playSound (sound) {
BAWK.play(sound);
},
onEquipClicked: function () {
vueApp.switchToEquipUi();
BAWK.play('ui_equip');
},
showSignIn: function () {
extern.showSignInDialog();
vueApp.$refs.firebaseSignInPopup.show();
},
onSignInClicked: function () {
this.showSignIn();
},
onSignOutClicked: function () {
extern.signOut();
},
onResendEmailClicked: function () {
extern.sendFirebaseVerificationEmail();
vueApp.showGenericPopup('verify_email_sent', 'verify_email_instr', 'ok');
},
onBigHouseAdClosed: function () {
console.log('big house ad closed event received');
this.ui.houseAds.big = null;
this.urlParamSet = this.urlParams ? true : null;
// vueApp.showTitleScreenAd();
vueApp.shellShockUrlParamaterEvents();
},
onPlayerNameChanged: function (newName) {
console.log('play name event handler');
vueApp.setPlayerName(newName);
BAWK.play('ui_onchange');
},
onEggPlayClick() {
play: 'play game',
ga('send', 'event', vueData.googleAnalytics.cat.play, vueData.googleAnalytics.action.eggDollClick);
vueApp.$refs.homeScreen.$refs.playPanel.onPlayButtonClick();
},
api_incentivizedVideoRewardRequest() {
extern.api_incentivizedVideoRewardRequested();
},
onTwitchDropsClick() {
window.open(dynamicContentPrefix + 'twitch');
},
showNuggyPopup() {
vueApp.showChicknWinnerPopup();
},
playIncentivizedAd(e) {
if (!this.chicknWinnerReady || this.hasChwPlayClicked) {
e.preventDefault();
return;
}
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', 'click-home');
this.hasChwPlayClicked = true;
vueApp.loadNuggetVideo();
vueApp.chicknWinnerNotReady();
},
chwStopCycle() {
if (this.chwHomeTimer) {
clearInterval(this.chwHomeTimer);
this.chwHomeTimer = '';
this.chwHomeEl.classList.remove('.active');
}
},
chwShowCycle() {
this.chwHomeEl = document.querySelector('.chw-home-timer');
if (this.chwHomeEl) {
this.chwHomeTimer = setInterval(() => {
this.chwHomeEl.classList.toggle('active');
}, this.chwActiveTimer);
}
},
openUnblocked() {
if (crazyGamesActive) {
window.open('https://scrambled.world/unblocked');
}
else {
window.open("unblocked");
}
}
},
computed: {
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '');
},
twitchDropsBtnImgSrs() {
if (this.twitchLinked) {
return '../img/events/twitch-drops-btn-linked.png';
}
return '../img/events/twitch-drops-btn-link-now.png';
},
remainingMsg() {
if (this.isChicknWinnerError) {
return this.loc.chw_error_text;
}
if (this.chicknWinnerDailyLimitReached && this.chicknWinnerCounter > 0) {
return this.loc.chw_daily_limit_msg;
}
if (this.chicknWinnerReady) {
if (this.chicknWinnerCounter === 0) {
return this.loc.chw_ready_msg;
} else {
return this.loc.chw_cooldown_msg;
}
} else {
return this.loc.chw_time_until;
}
},
progressBarWrapClass() {
if (this.chicknWinnerReady) {
return 'chw-progress-bar-wrap-complete';
}
},
playAdText() {
if (this.chicknWinnerReady && this.chicknWinnerCounter === 0) {
return this.loc.chw_btn_free_reward;
} else {
return this.loc.chw_btn_free_reward;
}
},
chwClass() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'grid-column-1-eq';
} else {
if (this.chicknWinnerReady) {
return 'grid-column-1-eq';
} else {
return 'grid-column-1-2';
}
}
},
chwHomeTimerCls() {
//{'chw-home-screen-max-watched': chicknWinnerDailyLimitReached}
if (this.chicknWinnerDailyLimitReached) {
return 'chw-home-screen-max-watched';
} else {
if (this.chicknWinnerReady) {
return 'is-ready active';
} else {
return 'not-ready';
}
}
},
chwChickSrc() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'img/chicken-nugget/chickLoop_daily_limit.svg';
} else {
if (!this.chicknWinnerReady) {
return 'img/chicken-nugget/chickLoop_sleep.svg';
} else {
return 'img/chicken-nugget/chickLoop_speak.svg';
}
}
},
chwShowTimer() {
if (this.chicknWinnerDailyLimitReached) {
// this.chwStopCycle();
return false;
} else {
if (this.chicknWinnerReady) {
this.chwShowCycle();
return false;
} else {
// this.chwStopCycle();
return true;
}
}
},
isTwitchLinked() {
if (this.twitchLinked) return '<i class="fas fa-check-circle text_twitch_yellow"></i>';
return '<i class="fas fa-times-circle text_grey"></i>';
}
}
};
</script><script id="equip-screen-template" type="text/x-template">
<div id="#equip_wrapper">
<div id="mainHead">
<account-panel id="account_panel" ref="accountPanelEquip" :loc="loc" :eggs="eggs" :show-corner-buttons="ui.showCornerButtons" :ui="ui" :show-bottom="false" :is-anonymous="isAnonymous" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" :currentLangOptions="locLanguage" :is-twitch="twitchLinked"></account-panel>
</div>
<div id="equip_box" class="main-content">
<section id="equip_panel_left" class="equip_panel left_panel">
<!--<div class="equip_panelhead">
</div>-->
<div id="equip_sidebox" class="roundme_md">
<equipped-slots id="equip.equipped_slots" ref="equip.equipped_slots" :loc="loc" :primary-item="equip.equippedPrimary" :secondary-item="equip.equippedSecondary" :hat-item="equip.equippedHat" :stamp-item="equip.equippedStamp" :grenade-item="equip.equippedGrenade" @equipped-type-selected="onEquippedTypeSelected"></equipped-slots>
<color-select id="equip.equipped_slots" ref="colorSelect" :loc="loc" :is-upgrade="isUpgraded" :color-idx="equip.colorIdx" :extra-colors-locked="equip.extraColorsLocked" @color-changed="onColorChanged"></color-select>
</div>
<p align="center"><button @click="onRedeemClick" class="ss_button btn_blue1 btn_md bevel_blue">{{ loc.eq_redeem }}</button></p>
</section>
<!-- end.left_panel -->
<section id="equip_panel_middle" class="equip_panel middle_panel">
<div class="equip_panelhead panel_tabs">
<button class="ss_bigtab bevel_blue ss_marginright" :class="getButtonToggleClass(equip.equipModes.inventory)" @click="switchToInventory">{{ loc.eq_inventory }}</button>
<button class="ss_bigtab bevel_blue" :disabled="!accountSettled" :class="getButtonToggleClass(equip.equipModes.shop)" @click="switchToShop">{{ loc.eq_shop }}</i></button>
</div>
<item-type-selector id="item_type_selector" ref="item_type_selector" :selected-item-type="equip.selectedItemType" :show-special-items="equip.showSpecialItems" :in-shop="isInShop" @item-type-changed="onItemTypeChanged" @tagged-items-clicked="onTaggedItemsClicked" @premium-items-clicked="onPremiumItemsClicked"></item-type-selector>
<div id="equip_purchase_top" class="equip_purchase_top">
<price-tag id="price_tag" class="ss_marginright" v-if="equip.buyingItem" ref="price_tag" :loc="loc" :item="equip.buyingItem" @buy-item-clicked="onBuyItemClicked"></price-tag>
<physical-tag id="physical-tag" class="ss_marginright" v-if="equip.physicalUnlockPopup.item" ref="physical-tag" :loc="loc" :item="equip.physicalUnlockPopup.item" @buy-item-clicked="onBuyItemClicked"></physical-tag>
</div>
<div id="equip_weapon_panel">
<weapon-select-panel id="weapon_select" ref="weapon_select":current-class="classIdx" :loc="loc" @changed-class="onChangedClass"></weapon-select-panel>
<button class="ss_button btn_md btn_red bevel_red" @click="onBackClick"><i class="fas fa-backward"></i> {{ loc.back }}</button>
</div>
</section>
<!-- end .middle_panel -->
<section id="equip_panel_right" class="equip_panel right_panel">
<div id="equip_sidebox" class="roundme_md">
<item-grid id="item_grid" ref="item_grid" :loc="loc" :grid-class="getGridClass" :items="equip.showingItems" :selectedItem="equip.selectedItem" :category-loc-key="equip.categoryLocKey" :in-shop="isInShop" @item-selected="onItemSelected" @switch-to-shop="onSwitchToShopClicked"></item-grid>
<!--<house-ad-small id="banner-ad" v-show="!isInShop"></house-ad-small>-->
</div>
</section>
<!-- .right_panel-->
</div>
<!-- Popup: Buy Item -->
<small-popup id="buyItemPopup" ref="buyItemPopup" @popup-confirm="onBuyItemConfirm">
<template slot="header">{{ loc.p_buy_item_title }}</template>
<template slot="content">
<div>
<canvas id="buyItemCanvas" ref="buyItemCanvas" width="250" height="250"></canvas>
</div>
<div class="f_row f_center">
<img v-if="!isBuyingItemPrem" src="img/ico_goldenEgg.png" class="egg_icon"/>
<i v-else class="fas fa-dollar-sign"></i>
<h1>{{ (equip.buyingItem) ? equip.buyingItem.price : '' }}</h1>
</div>
</template>
<template slot="cancel">{{ loc.p_buy_item_cancel }}</template>
<template slot="confirm">{{ loc.p_buy_item_confirm }}</template>
</small-popup>
<!-- Popup: Redeem Code -->
<small-popup id="redeemCodePopup" ref="redeemCodePopup" :popup-model="equip.redeemCodePopup" @popup-confirm="onRedeemCodeConfirm">
<template slot="header">{{ loc.p_redeem_code_title }}</template>
<template slot="content">
<div class="error_text shadow_red" v-show="equip.redeemCodePopup.showInvalidCodeMsg">{{ loc.p_redeem_code_no_code }}</div>
<p><input type="text" class="ss_field ss_margintop ss_marginbottom text-center width_lg" v-model="equip.redeemCodePopup.code" v-bind:placeholder="loc.p_redeem_code_enter"></p>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
<!-- Popup: Physical Unlock -->
<small-popup id="physicalUnlockPopup" ref="physicalUnlockPopup" :popup-model="equip.physicalUnlockPopup" @popup-confirm="onPhysicalUnlockConfirm">
<template slot="header">{{ loc.p_physical_unlock_title }}</template>
<template slot="content">
<div v-if="(equip.physicalUnlockPopup.item !== null)">
<div>
<item :item="equip.physicalUnlockPopup.item" :isSelected="false" :show-item-only="true"></item>
<div class="f_row f_center">
<img src="img/ico_goldenEgg.png" class="egg_icon"/>
<h1>{{ loc.p_buy_special_price }}</h1>
</div>
</div>
<div class="popup_sm__item_desc">
{{ loc[equip.physicalUnlockPopup.item.item_data.physicalUnlockLocKey] }}
</div>
</div>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
<template slot="confirm">{{ loc.confirm }}</template>
</small-popup>
</div>
</script>
<script id="equipped-slots-template" type="text/x-template">
<div>
<h3 class="margins_sm">{{ loc.eq_equipped }}</h3>
<div id="equip_equippedslots">
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Primary)">
<item id="primary_item" ref="primary_item" v-if="primaryItem" :item="primaryItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!primaryItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_weaponPrimary.svg" alt="Primary equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Secondary)">
<item id="secondary_item" ref="secondary_item" v-if="secondaryItem" :item="secondaryItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!secondaryItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_weaponSecondary.svg" alt="Secondary equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Grenade)">
<item id="grenade_item" ref="grenade_item" v-if="grenadeItem" :item="grenadeItem" class="equip_icon" :equippedSlot="true"></item>
<div v-if="!grenadeItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_grenade.svg" alt="Grenade equip slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Hat)">
<item id="hat_item" ref="hat_item" v-if="hatItem" :item="hatItem" :equippedSlot="true"></item>
<div v-if="!hatItem" class="equip_icon equip_icon_hat equip_icon_no_item"><img src="img/inventory-icons/ico_hat.svg" alt="Hat item slot"></div>
</div>
<div class="equip_item roundme_lg clickme f_row f_center" @click="onClick(itemType.Stamp)">
<item id="stamp_item" ref="stamp_item" v-if="stampItem" :item="stampItem" :equippedSlot="true"></item>
<div v-if="!stampItem" class="equip_icon equip_icon_stamp equip_icon_no_item"><img src="img/inventory-icons/ico_stamp.svg" alt="Stamp item slot"></div>
</div>
</div>
</div>
</script>
<script>
var comp_equipped_slots = {
template: '#equipped-slots-template',
components: { 'item': comp_item },
props: ['loc', 'primaryItem', 'secondaryItem', 'hatItem', 'stampItem', 'grenadeItem'],
data: function () {
return {
itemType: ItemType
}
},
methods: {
onClick: function (itemType) {
this.$emit('equipped-type-selected', itemType);
}
},
computed: {
emptyHatClass: function () {
return (this.hatItem === null) ? 'equip_icon_hat' : '';
},
emptyStampClass: function () {
return (this.stampItem === null) ? 'equip_icon_stamp' : '';
}
}
};
</script><script id="color-select-template" type="text/x-template">
<div>
<h3 class="margins_sm">{{ loc.eq_color }}</h3>
<div id="equip_free_colors" class="text-center">
<svg v-for="(c, index) in freeColors" class="eggIcon equip_color" :style="{ color: c }" :class="isSelectedClass(index)" @click="onClick(index)"><use xlink:href="#icon-egg"></use></svg>
</div>
<div id="equip_paid_colors" class="text-center ss_marginbottom_lg">
<svg v-for="(c, index) in paidColors" class="eggIcon equip_color" :style="{ color: c }" :class="isSelectedClass(index + freeColors.length)" @click="onClick(index + freeColors.length)"><use :xlink:href="getExtraColorEggIcon"></use></svg>
</div>
</div>
</script>
<script>
var comp_color_select = {
template: '#color-select-template',
props: ['loc', 'colorIdx', 'extraColorsLocked', 'isUpgrade'],
data: function () {
return {
freeColors: freeColors,
paidColors: paidColors
}
},
methods: {
isSelectedClass: function (idx) {
return (idx === this.colorIdx) ? 'selected' : ''
},
onClick: function (idx) {
if (idx >= freeColors.length && this.extraColorsLocked === true) {
vueApp.showSubStorePopup();
// BAWK.play('ui_chicken');
return;
}
this.$emit('color-changed', idx);
},
},
computed: {
getExtraColorEggIcon() {
return (this.extraColorsLocked === true && !this.isUpgrade) ? '#icon-egg-locked' : '#icon-egg';
},
}
};
</script><script id="item-timer-template" type="text/x-template">
<div>
<div id="equip_timerem" class="box_blue3 roundme_sm shadow_blue4">
<i class="fas fa-hourglass-start"></i> 9{{ loc.eq_day }}<span class="blink">:</span>12{{ loc.eq_hour }}
<br>{{ loc.eq_remaining }}
</div>
</div>
</script>
<script>
var comp_item_timer = {
template: '#item-timer-template',
props: ['loc']
};
</script><script id="price-tag-template" type="text/x-template">
<div id="equip_purchase_items" v-if="isNoPrice" class="equip_purchase_items">
<div id="equip_pricetag" class="equip_pricetag shadow_blue2">
<img src="img/pricetag_left.png" class="equip_pricetag__endpiece">
<div class="equip_pricetag__tag equip_pricetag__is_buy_tag">
<img v-if="!isPremium" src="img/ico_goldenEgg.png">
<i v-else class="fas fa-dollar-sign"></i>
{{ item.price }}
</div>
<img src="img/pricetag_right.png" class="equip_pricetag__endpiece">
</div>
<button style="pointer-events: all" class="ss_button btn_yolk bevel_yolk is_purchase_btn" @click="onBuyClick">{{ loc.eq_buy }}</button>
</div>
</script>
<script>
var comp_price_tag = {
template: '#price-tag-template',
props: ['loc', 'item'],
methods: {
onBuyClick: function () {
if (this.isPremium) {
return vueApp.showPopupEggStoreSingle(this.item.sku);
}
this.$emit('buy-item-clicked', this.item);
}
},
computed: {
isPremium() {
return this.item.unlock === 'premium';
},
isNoPrice() {
return this.item.price < 1000000000;
}
}
};
</script><script id="physical-tag-template" type="text/x-template">
<div id="equip_get_physical_item" class="equip_purchase_items">
<div id="equip_pricetag" class="equip_pricetag shadow_blue2">
<img src="img/pricetag_left.png">
<div class="equip_pricetag__tag equip_pricetag__is_special_tag">
<img src="img/ico_goldenEgg.png" class="ss_marginright">{{ loc.p_buy_special_price }}
</div>
<img src="img/pricetag_right.png">
</div>
<button class="ss_button btn_yolk bevel_yolk is_special_get_btn" @click="onBuyClick">{{ loc.p_chicken_goldbutton }}</button>
</div>
</script>
<script>
var comp_physical_tag = {
template: '#physical-tag-template',
props: ['loc', 'item'],
methods: {
onBuyClick: function () {
this.$emit('buy-item-clicked', this.item);
}
}
};
</script><script id="item-type-selector-template" type="text/x-template">
<div>
<div id="equip_itemtype" class="equip_panelhead">
<img src="img/inventory-icons/ico_weaponPrimary.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Primary)" @click="onItemTypeClick(itemType.Primary)">
<img src="img/inventory-icons/ico_weaponSecondary.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Secondary)" @click="onItemTypeClick(itemType.Secondary)">
<img src="img/inventory-icons/ico_grenade.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Grenade)" @click="onItemTypeClick(itemType.Grenade)">
<img src="img/inventory-icons/ico_hat.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Hat)" @click="onItemTypeClick(itemType.Hat)">
<img src="img/inventory-icons/ico_stamp.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass(itemType.Stamp)" @click="onItemTypeClick(itemType.Stamp)">
<i class="ico_itemtype premium-item-type clickme roundme_lg fas fa-gem" :class="getSelectedClass('premium')" @click="onPremiumTypeClick"></i>
<img src="img/inventory-icons/ico_specialItem.svg" class="ico_itemtype clickme roundme_lg" :class="getSelectedClass('tagged')" @click="onTaggedTypeClick">
</div>
</div>
</script>
<script>
var comp_item_type_selector = {
template: '#item-type-selector-template',
props: ['showSpecialItems', 'selectedItemType', 'inShop'],
data: function () {
return {
itemType: ItemType,
showingTagged: false
}
},
methods: {
onItemTypeClick: function (itemType) {
this.$emit('item-type-changed', itemType);
},
onTaggedTypeClick: function (e) {
if (!this.showSpecialItems) {
return;
}
this.$emit('tagged-items-clicked');
},
onPremiumTypeClick() {
this.$emit('premium-items-clicked');
},
getSelectedClass: function (itemType) {
let noTags = itemType === 'tagged' && !this.showSpecialItems ? 'no-tags' : '';
return (itemType === this.selectedItemType) ? 'selected ' + noTags : '' + noTags;
}
}
};
</script><script id="item-grid-template" type="text/x-template">
<div>
<div id="item_mask"></div>
<h3 v-if="accountSettled" class="margins_sm">{{ loc[categoryLocKey] }}</h3>
<div v-if="accountSettled" id="equip_grid" :class="gridClass">
<item v-for="i in items" :loc="loc" :item="i" :key="i.id" :isSelected="isSelected(i)" @item-selected="onItemSelected"></item>
<div v-show="!inShop" class="store_item roundme_lg '.$is_hi.' '.$is_na.' clickme morestuff bevel_green" @click="onSwitchToShopClick"></div>
<div v-show="inShop && !hiddenPremItemCheck" class="store_item roundme_lg '.$is_hi.' '.$is_na.' soldout">
<div class="soldout_head shadow_bluebig5" v-html="loc.eq_sold_out_head"></div>
<div class="soldout_text" v-html="loc.eq_sold_out_text"></div>
</div>
</div>
<div id="items-account-not-loaded" v-show="!accountSettled" class="text-center">
<h3>{{loc.signin_auth_title}}</h3>
<p>{{loc.signin_auth_msg}}</p>
</div>
</div>
</script>
<script>
var comp_item_grid = {
template: '#item-grid-template',
components: { 'item': comp_item },
props: ['items', 'selectedItem', 'gridClass', 'categoryLocKey', 'inShop'],
data() {
return vueData;
},
methods: {
onItemSelected: function (selectedItem) {
this.$emit('item-selected', selectedItem);
},
isSelected: function (item) {
if (!hasValue(this.selectedItem)) {
return false;
}
return (this.selectedItem.id === item.id);
},
onSwitchToShopClick: function () {
this.$emit('switch-to-shop');
BAWK.play('ui_playconfirm');
},
isPremItemInStore() {
let hasItem = false;
for (let i = 0; i < this.items.length; i++) {
const item = this.items[i];
const isItem = vueApp.premiumShopItems.find(i => i.isActive && i.itemId.id === item.id);
if (hasValue(isItem)) {
hasItem = true;
break;
}
}
return hasItem;
}
},
computed: {
categoryName: function () {
if (!hasValue(this.selectedItem)) {
return null;
}
return this.loc['item_type_' + this.selectedItem.item_type_id];
},
hiddenPremItemCheck() {
if (this.items.some(i => i.unlock === 'purchase') || this.items.length !== 0) return true;
if (this.items.some(i => i.unlock === 'premium')) return this.isPremItemInStore();
return false;
}
}
};
</script>
<script>
var comp_equip_screen = {
template: '#equip-screen-template',
components: {
'account-panel': comp_account_panel,
'equipped-slots': comp_equipped_slots,
'color-select': comp_color_select,
'item-timer': comp_item_timer,
'price-tag': comp_price_tag,
'physical-tag': comp_physical_tag,
'item-type-selector': comp_item_type_selector,
'item-grid': comp_item_grid,
'house-ad-small': comp_house_ad_small,
'weapon-select-panel': comp_weapon_select_panel,
'item': comp_item,
// 'account-panel': comp_account_panel,
'house-ad-small': comp_house_ad_small
},
data: function () {
return vueData;
},
equippedItems: {},
methods: {
setup: function (itemType) {
if (!itemType) { itemType = ItemType.Primary; }
this.updateEquippedItems();
this.poseEquippedItems();
if (itemType === 'tagged') {
this.populateItemGridWithTagged(this.equip.specialItemsTag);
} else {
this.populateItemGridWithType(itemType);
}
this.selectEquippedItemForType();
},
updateEquippedItems: function () {
this.$options.equippedItems = extern.getEquippedItems();
this.equip.equippedHat = this.$options.equippedItems[ItemType.Hat];
this.equip.equippedStamp = this.$options.equippedItems[ItemType.Stamp];
this.equip.equippedGrenade = this.$options.equippedItems[ItemType.Grenade];
this.equip.equippedPrimary = this.$options.equippedItems[ItemType.Primary];
this.equip.equippedSecondary = this.$options.equippedItems[ItemType.Secondary];
},
poseEquippedItems: function () {
this.posingHat = this.equip.equippedHat;
this.posingStamp = this.equip.equippedStamp;
switch (this.equip.showingWeaponType) {
case ItemType.Primary:
this.posingWeapon = this.equip.equippedPrimary;
this.posingGrenade = null;
break;
case ItemType.Secondary:
this.posingWeapon = this.equip.equippedSecondary;
this.posingGrenade = null;
break;
case ItemType.Grenade:
this.posingGrenade = this.equip.equippedGrenade;
break;
}
this.workItBaby();
},
selectEquippedItemForType: function () {
switch (this.equip.selectedItemType) {
case ItemType.Hat: this.equip.selectedItem = this.equip.equippedHat; break;
case ItemType.Stamp: this.equip.selectedItem = this.equip.equippedStamp; break;
case ItemType.Primary: this.equip.selectedItem = this.equip.equippedPrimary; break;
case ItemType.Secondary: this.equip.selectedItem = this.equip.equippedSecondary; break;
case ItemType.Grenade: this.equip.selectedItem = this.equip.equippedGrenade; break;
}
},
populateItemGridWithType: function (itemType) {
this.equip.selectedItemType = itemType;
var items = extern.getItemsOfType(itemType);
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_{0}{1}'.format(itemType, ((itemType === ItemType.Primary) ? '_' + this.classIdx : ''));
},
populateItemGridWithTagged: function (tag) {
var items = extern.getTaggedItems(tag);
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_5';
},
populateItemGrid: function (items) {
if (this.equip.mode === vueData.equip.equipModes.inventory) {
items = items.filter(i => {
return extern.isItemOwned(i) || (i.is_available && i.unlock === "default");
});
}
else {
items = items.filter(i => {
// return (i.is_available || extern.account.isSubscriber) && !extern.isItemOwned(i) && i.unlock !== "default" && i.unlock !== 'manual';
return i.is_available && !extern.isItemOwned(i) && i.unlock !== "default";
})
}
this.equip.showingItems = items;
},
workItBaby: function () {
extern.poseWithItem(ItemType.Hat, this.posingHat);
extern.poseWithItem(ItemType.Stamp, this.posingStamp);
extern.poseWithItem(this.posingWeapon.item_type_id, this.posingWeapon);
if (this.posingGrenade) extern.poseWithItem(this.posingGrenade.item_type_id, this.posingGrenade);
},
onBackClick: function () {
extern.saveEquipment();
this.equip.showingWeaponType = ItemType.Primary;
this.poseEquippedItems();
if (!extern.inGame) {
vueApp.showTitleScreenAd();
vueApp.switchToHomeUi();
} else {
extern.closeEquipInGame();
vueApp.switchToGameUi();
vueApp.showGameMenu();
vueApp.showRespawnDisplayAd();
}
BAWK.play('ui_popupclose');
},
onItemTypeChanged: function (itemType) {
this.switchItemType(itemType);
},
switchItemType: function (itemType) {
if (itemType !== this.equip.selectedItemType) {
if (itemType === ItemType.Primary || itemType === ItemType.Secondary || itemType == ItemType.Grenade) {
this.equip.showingWeaponType = itemType;
}
this.poseEquippedItems();
this.populateItemGridWithType(itemType);
if (this.equip.mode === this.equip.equipModes.inventory) {
this.selectEquippedItemForType();
} else {
this.selectFirstItemInShop();
}
}
if (!this.isInShop) {
this.hideItemForSale();
this.hideItemForSpecial();
}
BAWK.play('ui_click');
},
onTaggedItemsClicked: function () {
BAWK.play('ui_click');
if (this.equip.selectedItemType === 'tagged') {
return;
}
this.showTaggedItems(this.equip.specialItemsTag);
this.selectFirstItemInShop();
},
onPremiumItemsClicked() {
BAWK.play('ui_click');
if (this.equip.selectedItemType === 'premium') {
return;
}
this.showPremiumItems();
this.selectFirstItemInShop();
},
showPremiumItems() {
this.equip.selectedItemType = 'premium';
var items = extern.getPremiumItems();
this.populateItemGrid(items);
this.equip.categoryLocKey = 'item_type_7';
},
showTaggedItems: function (tag) {
this.equip.selectedItemType = 'tagged';
if (this.equip.mode === this.equip.equipModes.inventory && !this.ownsTaggedItems(this.equip.specialItemsTag)) {
this.equip.mode = this.equip.equipModes.shop;
vueApp.conditionalAnonWarningCall();
}
this.populateItemGridWithTagged(tag);
},
showSelectedTagItems(tag) {
this.equip.selectedItemType = 'tagged';
// if (this.equip.mode === this.equip.equipModes.inventory) {
// this.equip.mode = this.equip.equipModes.shop;
// }
this.populateItemGridWithTagged(tag);
},
switchToInventory: function () {
if (this.equip.selectedItemType === 'tagged' && this.equip.mode === this.equip.equipModes.shop) {
if (!this.ownsTaggedItems(this.equip.specialItemsTag)) {
this.switchItemType(ItemType.Primary);
}
}
this.equip.mode = this.equip.equipModes.inventory;
this.hideItemForSale();
this.hideItemForSpecial();
this.poseEquippedItems();
this.showItemsAfterEquipModeSwitch();
this.selectEquippedItemForType();
BAWK.play('ui_toggletab');
// vueApp.histPushState({game: this.ui.screens.equip}, 'Shellshockers equipment inventory', '?equip=inventory');
},
ownsTaggedItems: function (tag) {
return extern.getTaggedItems(tag).filter(i => {
return extern.isItemOwned(i);
}).length > 0;
},
selectFirstItemInShop: function () {
if (this.isInShop && this.equip.showingItems.length > 0) {
this.selectItem(this.equip.showingItems[0]);
}
},
switchToShop: function () {
if (!this.accountSettled) {
return;
}
this.equip.mode = this.equip.equipModes.shop;
this.showItemsAfterEquipModeSwitch();
this.selectFirstItemInShop();
vueApp.conditionalAnonWarningCall();
BAWK.play('ui_toggletab');
// vueApp.histPushState({game: this.ui.screens.equip}, 'Shellshockers equipment shop', '?equip=shop');
},
showItemsAfterEquipModeSwitch: function () {
if (this.equip.selectedItemType === 'tagged') {
this.showTaggedItems(this.equip.specialItemsTag)
} else if (this.equip.selectedItemType === 'premium') {
this.showPremiumItems();
} else {
this.populateItemGridWithType(this.equip.selectedItemType);
}
},
onEquippedTypeSelected: function (itemType) {
this.equip.selectedItemType = itemType;
if (
this.equip.selectedItemType === ItemType.Primary ||
this.equip.selectedItemType === ItemType.Secondary ||
this.equip.selectedItemType === ItemType.Grenade
) {
this.equip.showingWeaponType = itemType;
}
this.switchToInventory();
},
onChangedClass: function () {
this.hideItemForSale();
this.hideItemForSpecial();
if (this.posingGrenade) {
this.posingGrenade = null;
this.onEquippedTypeSelected(ItemType.Primary);
}
if (this.equip.selectedItemType !== ItemType.Primary) {
this.onEquippedTypeSelected(ItemType.Primary);
}
this.updateEquippedItems();
this.poseEquippedItems();
this.populateItemGridWithType(this.equip.selectedItemType);
if (extern.inGame && this.ui.showScreen !== this.ui.screens.equip) {
this.equip.showingWeaponType = ItemType.Primary;
this.poseEquippedItems();
extern.closeEquipInGame();
}
},
autoSelectItem: function (item) {
if (extern.isItemOwned(item)) {
this.switchToInventory();
} else {
this.switchToShop();
}
this.switchItemType(item.item_type_id);
this.selectItem(item);
},
onItemSelected: function (item) {
this.selectItem(item);
},
isPremItemInStore(item) {
let hasItem = false;
const isItem = this.premiumShopItems.find(i => i.isActive && i.itemId.id === item.id);
if (hasValue(isItem)) {
hasItem = true;
}
return hasItem;
},
selectItem: function (item) {
var selectingSame = hasValue(this.equip.selectedItem) && this.equip.selectedItem.id === item.id;
var selectedId = selectingSame ? this.equip.selectedItem.id : null;
var isWeapon = (item.item_type_id === ItemType.Primary || item.item_type_id === ItemType.Secondary);
BAWK.play('ui_click');
if (selectingSame) {
if (this.isInShop) {
// Revert to equipped weapon
item = this.$options[this.equip.selectedItem.item_type_id];
} else {
// Take off hat or stamp
if (!isWeapon) {
item = null;
extern.removeItemType(this.equip.selectedItem.item_type_id);
}
}
}
if (this.isInShop) {
if ( item && item.hasOwnProperty('unlock') && item.unlock === 'premium' && !this.isPremItemInStore(item)) {
// Revert to equipped weapon
item = this.$options[this.equip.selectedItem.item_type_id];
}
}
// Take off any items being tried on
this.poseEquippedItems();
this.equip.selectedItem = item;
extern.tryEquipItem(item);
this.updateEquippedItems();
if (hasValue(item)) {
this.poseWithItem(item);
if (this.isInShop) {
switch (item.unlock) {
case "physical":
console.log('purchasing physical item');
if ( !selectingSame ) {
this.offerItemForSpecial(item)
this.hideItemForSale();
} else {
this.hideItemForSpecial();
}
// this.$refs.physicalUnlockPopup.toggle();
break;
case "purchase":
case "premium":
if (!selectingSame) {
this.offerItemForSale(item);
this.hideItemForSpecial();
} else {
this.hideItemForSale();
}
break;
}
}
} else {
this.poseEquippedItems();
this.hideItemForSale();
this.hideItemForSpecial();
}
},
poseWithItem: function (item) {
switch (item.item_type_id) {
case ItemType.Hat: this.posingHat = item; break;
case ItemType.Stamp: this.posingStamp = item; break;
case ItemType.Grenade: this.posingGrenade = item; break;
case ItemType.Primary:
case ItemType.Secondary: this.posingWeapon = item; break;
}
this.workItBaby();
},
getButtonToggleClass: function (equipMode) {
return (equipMode === this.equip.mode) ? 'btn_toggleon' : 'btn_toggleoff';
},
offerItemForSpecial: function(item) {
return this.equip.physicalUnlockPopup.item = item;
},
hideItemForSpecial: function() {
this.equip.physicalUnlockPopup.item = null;
},
offerItemForSale: function (item) {
this.equip.buyingItem = item;
},
hideItemForSale: function () {
this.equip.buyingItem = null;
// this.equip.physicalUnlockPopup.item = null
},
onBuyItemClicked: function () {
// If item is buying item show buyItemPopup or show physicalUnlockPopup
this.equip.buyingItem ? this.$refs.buyItemPopup.toggle() : this.$refs.physicalUnlockPopup.toggle();
this.equip.buyingItem ? extern.renderItemToCanvas(this.equip.buyingItem, this.$refs.buyItemCanvas) : null;
BAWK.play('ui_popupopen');
},
onBuyItemConfirm: function () {
if (this.equip.buyingItem.unlock === 'premium') {
extern.buyProductForMoney(this.equip.buyingItem.sku);
return;
} else {
extern.api_buy(this.equip.buyingItem, this.boughtItemSuccess, this.boughtItemFailed);
}
BAWK.play('ui_playconfirm');
},
boughtItemSuccess: function () {
this.equip.selectedItem = this.equip.buyingItem;
ga('send', 'event', {
eventCategory: this.googleAnalytics.cat.itemShop,
eventAction: this.googleAnalytics.action.shopItemPopupBuy,
eventLabel: this.equip.buyingItem.name,
eventValue: this.equip.selectedItem.price
});
var itemType = this.equip.selectedItem.item_type_id;
if (itemType === ItemType.Primary || itemType === ItemType.Secondary || itemType == ItemType.Grenade) {
this.equip.showingWeaponType = itemType;
}
this.hideItemForSale();
this.setup(this.equip.selectedItemType);
this.updateEquippedItems();
this.poseEquippedItems();
this.selectEquippedItemForType();
},
boughtItemFailed: function () {
vueApp.showGenericPopup('p_buy_error_title', 'p_buy_error_content', 'ok');
BAWK.play('ui_reset');
},
onRedeemClick: function () {
this.$refs.redeemCodePopup.code = '';
this.$refs.redeemCodePopup.toggle();
BAWK.play('ui_popupopen');
},
onRedeemCodeConfirm: function () {
if (this.equip.redeemCodePopup.code.toUpperCase() === 'D3LL0RKC1R') {
this.giveStuffPopup.eggOrg = false;
this.giveStuffPopup.rickroll = true;
vueApp.showGiveStuffPopup('p_give_stuff_title');
} else {
this.giveStuffPopup.rickroll = false;
this.giveStuffPopup.eggOrg = false;
extern.api_redeem(this.equip.redeemCodePopup.code, this.redeemCodeSuccess, this.redeemCodeFailed);
}
BAWK.play('ui_playconfirm');
},
redeemCodeSuccess: function (eggs, items) {
this.populateItemGridWithType(this.equip.selectedItemType);
this.giveStuffPopup.eggs = eggs;
this.giveStuffPopup.items = items;
vueApp.showGiveStuffPopup('p_give_stuff_title', eggs, items);
let itemString = '';
this.giveStuffPopup.items.forEach(item => itemString += item.name);
ga('send', 'event', {
eventCategory: this.googleAnalytics.cat.redeem,
eventAction: this.googleAnalytics.action.redeemed,
eventLabel: `${itemString ? itemString : ''} ${this.giveStuffPopup.eggs ? this.giveStuffPopup.eggs + 'eggs' : ''}`
});
},
redeemCodeFailed: function () {
vueApp.showGenericPopup('p_redeem_error_title', 'p_redeem_error_content', 'ok');
BAWK.play('ui_reset');
},
onPhysicalUnlockConfirm: function () {
window.open(this.equip.physicalUnlockPopup.item.item_data.physicalItemStoreURL, '_blank');
},
onColorChanged: function (colorIdx) {
this.equip.colorIdx = colorIdx;
extern.setShellColor(this.equip.colorIdx);
BAWK.play('ui_onchange');
},
onSwitchToShopClicked: function () {
this.switchToShop();
}
},
computed: {
isInShop: function () {
return (this.equip.mode === this.equip.equipModes.shop);
},
getGridClass: function () {
return this.isInShop ? '' : 'equip_grid_short';
},
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '');
},
isBuyingItemPrem() {
if (!this.equip.buyingItem) {
return;
}
return this.equip.buyingItem.unlock === 'premium';
}
}
};
</script><script id="game-screen-template" type="text/x-template">
<div>
<event-panel :show-soon="false" :show-ui="ui.showCornerButtons"></event-panel>
<account-panel id="game_account_panel" ref="accountPanelGame" :loc="loc" :eggs="eggs" :show-bottom="false" :show-corner-buttons="ui.showCornerButtons" :ui="ui" :isEggStoreSale="isEggStoreSaleItem" :is-subscriber="isSubscriber" :currentLangOptions="locLanguage" :is-twitch="twitchLinked"></account-panel>
<div id="chickenBadge" ref="chickenBadge" style="display: none;"><img :src="upgradeBadgeUrl"></div>
<!-- Scope -->
<div id="scopeBorder">
<div id="maskleft"></div>
<div id="maskmiddle"></div>
<div id="maskright"></div>
</div>
<!-- Best Streak -->
<div id="best_streak_container">
<h1 v-show="(((doubleEggWeekend || doubleEggWeekendSoon) && !ui.showCornerButtons) || (!doubleEggWeekend && !doubleEggWeekendSoon))" id="bestStreak">x0</h1>
</div>
<div v-show="announcementMessage" id="announcement_message">{{ announcementMessage }}</div>
<div id="shellStreakContainer">
<h1 id="shellStreakCaption"></h1>
<h1 id="shellStreakMessage" class="disappear"></h1>
</div>
<!-- Team Scores -->
<div id="teamScores">
<div id="teamScore2" class="teamScore red inactive">
<div id="teamScoreNum2" class="number">0</div>
<div class="teamLetter red" style="color: #f00;">R</div>
</div>
<div id="teamScore1" class="teamScore blue inactive">
<div id="teamScoreNum1" class="number">0</div>
<div class="teamLetter blue" style="color: #0af;">B</div>
</div>
<!--<div>
<img src="img/spatulaIcon.png" style="width: 3em; transform: rotate(60deg)">
</div>-->
</div>
<!-- Capture Icon -->
<div id="captureIconContainer">
<div id="captureInsideContainer">
<div id="captureIconCaption">20M</div>
<div id="captureRingBackground"></div>
<div id="captureRingContainer">
<div id="captureRing"></div>
</div>
<svg id="captureIcon" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" />
</svg>
</div>
</div>
<!-- Reticle -->
<div id="reticleContainer">
<div id="dotReticle"></div>
<div id="crosshairContainer">
<div id="crosshair0" class="crosshair normal"></div>
<div id="crosshair1" class="crosshair normal"></div>
<div id="crosshair2" class="crosshair normal"></div>
<div id="crosshair3" class="crosshair normal"></div>
</div>
<div id="shotReticleContainer">
<div id="shotBracket0" class="shotReticle border normal"></div>
<div id="shotBracket1" class="shotReticle border normal"></div>
<div id="shotBracket2" class="shotReticle fill normal"></div>
<div id="shotBracket3" class="shotReticle fill normal"></div>
</div>
<div id="readyBrackets">
<div class="readyBracket"></div>
<div class="readyBracket"></div>
<div class="readyBracket"></div>
<div class="readyBracket"></div>
</div>
</div>
<!-- Capture Zone progress -->
<div id="captureContainer">
<div class="captureScoreContainer">
<svg class="captureCrown" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" fill="var(--ss-team-red-light)" />
</svg>
<div id="captureScoreRed" class="captureScore">0/5</div>
</div>
<div id="captureCenter">
<div id="captureBarContainer">
<div id="captureBar"></div>
</div>
<div id="captureBarText"></div>
</div>
<div class="captureScoreContainer">
<svg class="captureCrown" viewBox="0 0 53.6 36">
<use href="img/kotc/crown.svg#crown" fill="var(--ss-team-blue-light)" />
</svg>
<div id="captureScoreBlue" class="captureScore">0/5</div>
</div>
</div>
<!-- Big Message Bar -->
<div id="bigMessageContainer" style="display: none">
<div id="bigMessageBar">
<div id="bigMessage"></div>
<div id="bigMessageCaption"></div>
</div>
</div>
<!-- Weapon -->
<div id="weaponBox">
<div id="grenades">
<img id="grenade3" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
<img id="grenade2" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
<img id="grenade1" class="grenade" src="img/ico_grenadeEmpty.png%3Fv=1"/>
</div>
<h2 id="weaponName"></h2>
<h2 id="ammo" class="shadow_grey"></h2>
</div>
<!-- Health -->
<div id="healthContainer">
<svg class="healthSvg">
<circle id="healthBar" class="healthBar" cx="50%" cy="50%" r="2.15em" />
<circle class="healthYolk" cx="50%" cy="50%" r="1.35em" />
</svg>
<div id="healthHp">100</div>
</div>
<!-- Hard Boiled -->
<div id="hardBoiledContainer">
<div id="hardBoiledShieldContainer">
<img class="hardBoiledShield" src="img/hardBoiledEmpty.png">
<img class="hardBoiledShield" id="hardBoiledShieldFill" src="img/hardBoiledFilled.png">
</div>
<div id="hardBoiledValue">100</div>
</div>
<!-- EggBreaker Shellstreak -->
<div id="eggBreakerContainer" class="off">
<img id="eggBreakerIcon" src="img/ico_eggBreaker.png" />
<div id="eggBreakerTimer">15</div>
</div>
<!-- Spatula -->
<img id="spatulaPlayer" src="img/spatulaIcon.png" />
<!-- Grenade throw power -->
<div id="grenadeThrowContainer">
<div id="grenadeThrow"></div>
</div>
<!-- Kill -->
<div id="killBox" class="shadow_grey">
<!-- <h3>{{ loc.ui_game_youkilled }}</h3> -->
<div v-html="killedMessage"></div>
<!-- <h2 id="KILLED_NAME"></h2> -->
<h3 id="KILL_STREAK"></h3>
</div>
<!-- Death -->
<div id="deathBox">
<div v-html="killedByMessage"></div>
</div>
<!-- Game messages -->
<div id="gameMessage"></div>
<!-- Chat -->
<div id="chatOut" class="chat roundme_sm"></div>
<input id="chatIn" class="chat roundme_sm" maxlength=64 tabindex=-1 v-bind:placeholder="loc.ingame_press_tab_to_exit" onkeydown="extern.onChatKeyDown(event)"></input>
<!-- Kill ticker -->
<div id="killTicker" class="chat"></div>
<!-- Spectator controls -->
<div id="spectate">
{{ loc.ui_game_spectating }}
</div>
<div id="serverAndMapInfo" class="shadow_grey"></div>
<!-- Ingame UI Stuff -->
<div id="inGameUI">
<div id="readouts" class="shadow_grey">
{{ loc.ui_game_fps }}: <div id="FPS"></div><br>
{{ loc.ui_game_ping }}: <div id="ping"></div>
</div>
<!-- Corner icon buttons -->
<!--
<div id="corner" style="float: right; margin-top: 0.5em;">
<div id="currentBalanceContainer" style="display: none; position: relative; left: -1em; top: 0.15em;">
<span id="currentBalance" style="display: inline-block; font-size: 1.7em; position: relative; top: -0.25em; left: -0.1em; color: white;"></span>
boopdiddyboop<img src="img/egg_icon.png" style="width: 1.6em; height: 2em;" />
</div>
<div id="cornerButtons" style="display: none; margin-bottom: 0.5em; text-align: right; float: right;">
<-<img id="homeButton" style="display: none; margin-right: 0.5em;" title="Home" class="icon" src="img/home.png?v=1" onclick="extern.showMainMenuConfirm()" />
<img id="friendsButton" style="display: none; margin-right: 0.5em;" title="Invite friends" class="icon" src="img/friends.png?v=1" onclick="extern.inviteFriends()" />
<img style="margin-right: 0.5em;" title="Feedback" class="icon" src="img/feedback.png?v=1" onclick="extern.showFeedbackForm()" />
<img style="margin-right: 0.5em;" title="Settings" class="icon" src="img/settings.png?v=1" onclick="extern.openSettingsMenu()" />
<img class="icon" title="Toggle fullscreen" src="img/fullScreen.png?v=1" onclick="extern.toggleFullscreen()" /> ->
</div>
</div>
-->
</div>
<!-- Popup: Mute/Boot Player -->
<small-popup id="playerActionsPopup" ref="playerActionsPopup" @popup-cancel="onPlayerActionsCancel" @popup-closed="onPlayerActionsCancel" :hide-confirm="true">
<template slot="header">{{ playerActionsPopup.playerName }}</template>
<template slot="content">
<div v-if="playerActionsPopup.vipMember" class="vip-member-wraper display-grid grid-align-items-center grid-column-1-2 ss_marginbottom_xl">
<figure class="player-action-vip-img center_h">
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Vip member icon" class="center_h">
</figure>
<div>
<h6 class="roundme_sm shadow_blue4 ss_margintop ss_marginbottom">{{loc.ui_game_playeractions_vip_member}}</h6>
<button v-if="!isSubscriber" class="ss_button btn_pink bevel_pink fullwidth" @click="openVipPopup">{{loc.ui_game_playeractions_join_vip}}</button>
</div>
</div>
<!-- .vip-member-wraper -->
<p>{{ loc.ui_game_playeractions_header }}</p>
<button v-if="playerActionsPopup.social" class="ss_button btn_medium btn_yolk bevel_yolk fullwidth" @click="onClickCreator(playerActionsPopup.social.url)"><i class="fab" :class="playerSocial"></i> {{loc.ui_game_playeractions_creator}}</button>
<h4 class="ss_button btn_medium btn_blue bevel_blue" v-on:click="onMuteClicked">{{ muteButtonLabel }}</h4>
<h4 class="ss_button btn_medium btn_yolk bevel_yolk" v-if="playerActionsPopup.isGameOwner" v-on:click="onBootClicked">{{ loc.ui_game_playeractions_boot }}</h4>
</template>
<template slot="cancel">{{ loc.cancel }}</template>
</small-popup>
<!-- Popup: Switch Team -->
<small-popup id="switchTeamPopup" ref="switchTeamPopup" @popup-cancel="onSwitchTeamCancel" :overlay-close="false" @popup-closed="onSwitchTeamCancel" @popup-confirm="onSwitchTeamConfirm">
<template slot="header">{{ loc.p_switch_team_title }}</template>
<template slot="content">
<h4 class="roundme_sm" :class="newTeamColorCss">{{ newTeamName }} <i class="fa fa-flag"></i></h4>
<p>{{ loc.p_switch_team_text }}</p>
</template>
<template slot="cancel">{{ loc.no }}</template>
<template slot="confirm">{{ loc.yes }}</template>
</small-popup>
<!-- Popup: Share Link -->
<small-popup id="shareLinkPopup" ref="shareLinkPopup" :popup-model="game.shareLinkPopup" @popup-confirm="onShareLinkConfirm" @popup-closed="onShareLinkClosed">
<template slot="header">{{ loc.p_sharelink_title }}</template>
<template slot="content">
<p>{{ loc.p_sharelink_text }}</p>
<p><input ref="shareLinkUrl" type="text" class="ss_field ss_margintop ss_marginbottom fullwidth" v-model="game.shareLinkPopup.url" @focus="$event.target.select()"></p>
</template>
<template slot="cancel">{{ loc.close }}</template>
<template slot="confirm">{{ loc.p_sharelink_copylink }}</template>
</small-popup>
<!-- Popup: Leave Game Confirm -->
<small-popup id="leaveGameConfirmPopup" ref="leaveGameConfirmPopup" :overlay-close="false" :hide-close="true" @popup-confirm="onLeaveGameConfirm" @popup-cancel="onLeaveGameCancel">
<template slot="header">{{ loc.leave_game_title }}</template>
<template slot="content">
<p>{{ loc.leave_game_text }}</p>
</template>
<template slot="cancel">{{ loc.no }}</template>
<template slot="confirm">{{ loc.yes }}</template>
</small-popup>
<div class="player__container">
<!-- Player List -->
<div id="playerSlot" class="playerSlot" style="display: none">
<div>
<span></span> <!-- Name -->
<span></span> <!-- Score -->
</div>
<div style="display: block;"></div> <!-- Icons -->
</div>
<div id="playerList"></div>
</div>
<!-- end .player__container -->
<div id="inGameScaler">
<div class="pause-popup--container">
<!-- Popup: Pause -->
<large-popup id="pausePopup" ref="pausePopup" hide-close="true" :overlay-close="false" :overlay-class="ui.overlayClass.inGame">
<template slot="content">
<div class="box_blue2 roundme_sm">
<div id="pausePopupInnards" class="roundme_sm f_row">
<div id="pauseButtons" class="f_col pause-btn-group">
<button @click="onHomeClicked" class="ss_button btn_blue bevel_blue"><i class="fa fa-home"></i> {{ loc.p_pause_home }}</button>
<button @click="onEquipClicked()" class="ss_button btn_blue bevel_blue"><i class="fas fa-star"></i> {{ loc.p_pause_equipment }}</button>
<button v-if="!delayTheCracking && !isRespawning" class="ss_button btn_red bevel_red btn_sm" disabled="disabled"><i class="fas fa-eye"></i> {{ loc.ui_game_get_ready }}</button>
<button v-if="delayTheCracking" v-show="!isRespawning" @click="onSpectateClicked()" class="ss_button btn_blue bevel_blue btn_sm" :disabled="isRespawning"><i class="fas fa-eye"></i> {{ loc.p_pause_spectate }}</button>
<music-widget ref="gameScreenMusic" :loc="loc" :settings-ui="settingsUi" :settings="true" :volumeSlider="false" :show="isPaused && showMusicWidget"></music-widget>
</div>
<!-- #pauseButtons -->
<div id="popupTipDay" class="roundme_sm flex-auto">
<div v-if="isPoki && pokiRewardReady" class="poki-reward-container">
<button class="ss_button btn_blue bevel_blue btn_reward pure-wiggle" @click="earnInGameReward"><img src="img/ico_goldenEgg.png" class="egg_icon">Watch Video for 100 Golden Eggs!</button>
</div>
<div v-show="!isPoki && firebaseId" id="chw-progress-wrapper" class="chw-progress-wrapper box_relative">
<!-- incentivized-mini-game -->
<img class="box_aboslute chw-progress-img chw-chick" :src="chwChickSrc">
<div class="chw-progress-bar-wrap roundme_sm box_relative btn_blue bevel_blue" :class="progressBarWrapClass" @click="playIncentivizedAd">
<p class="chw-progress-bar-msg box_aboslute centered nospace text-center fullwidth chw-msg chw-p-msg">
{{ progressMsg }}
<!-- <span class="chw-countdown-wrap" :class="chwShowCountdown">
<span class="chw-minutes"></span><span class="chw-seconds"></span>
</span> -->
</p>
<div class="chw-progress-bar-inner" @click="playIncentivizedAd">
</div>
</div>
<img class="box_aboslute chw-eggs chw-progress-img" src="img/egg_pack_small.png" alt="">
</div>
<!-- #chw-progress-wrapper end -->
<!-- .poki-reward-container -->
<div id="btn_horizontal" class="pause-popup--btn-group">
<header class="weapon-select weapon-select--title pause-bg roundme_sm">
<h1>{{loc.p_weapon_title}}</h1>
</header>
<div class="pause-bg roundme_sm">
<weapon-select-panel ref="weaponSelect" id="weapon_select" :loc="loc" :current-class="classIdx" @changed-class="pauseWeaponSelect"></weapon-select-panel>
</div>
<!-- .pause-bg -->
</div>
<!-- .pause-popup--btn-group -->
<div id="game-play-switch" class="paused-game-cotrols roundme_sm f_row">
<div v-if="delayTheCracking" class="switch-teams-btn">
<button v-show="isTeamGame" @click="onSwitchTeamClicked" class="ss_button btn__team_switch" :class="teamColorCss"><i class="fa fa-flag"></i> {{ teamName }}</button>
</div>
<!-- .switch-teams-btn -->
<div class="pause-popup--btn-group f-grow-full">
<button v-if="!delayTheCracking && !isRespawning" class="btn_big btn_wfull ss_button btn_red bevel_red" disabled="disabled">{{ loc.ui_game_get_ready }}</button>
<button v-if="delayTheCracking" class="btn_big btn_wfull ss_button btn_red bevel_red" v-show="isRespawning" :disabled="isRespawning">{{ game.respawnTime }}</button>
<button v-if="delayTheCracking" v-show="!isRespawning" @click="onPlayClicked()" class="btn-respawn btn_big btn_wfull ss_button btn_yolk bevel_yolk" :disabled="isRespawning"><i class="fa fa-play"></i> {{ loc.p_pause_play }}</span></button>
<!-- .pause-popup--btn-group -->
</div>
<!-- .w-shrinkauto -->
</div>
<!-- #game-play-switch -->
</div>
<!-- #popupTipDay -->
</div>
<!-- #pausePopupInnards -->
</div>
</template>
</large-popup>
<div class="respawn-container respawn-two" v-show="isPaused">
<display-ad :hidden="hideAds" id="shellshockers_respawn_banner_2_ad" ref="respawnTwoDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawnTwo" adSize="300x250"></display-ad>
</div>
<div class="respawn-container respawn-one" v-show="isPaused">
<!-- <display-ad :hidden="hideAds" id="shellshockers_respawn_banner_ad" ref="respawnDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawn" adSize="728x90"></display-ad> -->
<display-ad :hidden="hideAds" id="shellshockers_respawn_banner-new_ad" ref="respawnDisplayAd" class="pauseFiller" :ignoreSize="false" :adUnit="adUnits.display.respawnThree" adSize="728x90"></display-ad>
</div>
</div>
<!-- .pause-popup--container -->
</div>
<!-- end #inGameScaler -->
<div class="in-game-widgets">
<music-widget ref="musicWidgetinGame" :loc="loc" :settings-ui="settingsUi" :show="showIngameWidget"></music-widget>
</div>
{{showIngameWidget}}
</div>
</script>
<script>
var comp_game_screen = {
template: '#game-screen-template',
components: {
'account-panel': comp_account_panel,
// 'event-panel': comp_events,
'weapon-select-panel': comp_weapon_select_panel,
// 'music-widget': comp_music_widget,
'event-panel': comp_events,
'weapon-select-panel': comp_weapon_select_panel,
},
props: ['kname', 'kdname'],
data: function () {
return vueData;
},
created: function () {
this.isPoki = pokiActive;
},
methods: {
placeBannerAdTagForGame: function (tagEl) {
this.$refs.pauseAdPlacement.appendChild(tagEl);
},
showGameMenu: function () {
// this.game.tipIdx = this.loc.tip_ofthe_day
// ? Math.randomInt(0, this.loc.tip_ofthe_day.length)
// : 0;
this.game.gameType = extern.gameType;
vueApp.showRespawnDisplayAd();
this.$refs.pausePopup.show();
this.isPaused = true;
vueApp.isPaused = true;
setTimeout(() => vueApp.disableRespawnButton(false), 500);
vueData.ui.showCornerButtons = true;
vueApp.gameUiAddClassForNoScroll();
addEventListener('gamepadbuttondown', this.onControllerButton);
this.crazyAdsRespawn();
extern.chicknWinnerOnPause();
vueApp.hideShareLinkPopup();
},
delayGameMenuPlayButtons() {
setTimeout(() => {
this.delayTheCracking = true;
}, 3000);
},
hideGameMenu: function () {
if (!extern.inGame) {
return;
}
this.$refs.pausePopup.hide();
// this.$refs.respawnDisplayAd.hide();
// this.$refs.respawnTwoDisplayAd.hide();
if (crazyGamesActive) crazysdk.clearAllBanners(); // Per CG's request
this.isPaused = false;
vueApp.isPaused = false;
vueApp.gameUiAddClassForNoScroll();
removeEventListener('gamepadbuttondown', this.onControllerButton);
},
onHomeClicked: function () {
this.gaSend('home');
this.hideGameMenu();
this.$refs.leaveGameConfirmPopup.show();
BAWK.play('ui_click');
},
onLeaveGameConfirm: function () {
this.leaveGame();
this.delayTheCracking = false;
},
onLeaveGameCancel: function () {
this.showGameMenu();
},
leaveGame: function () {
// clientGame.js manipulates chickenBadge element directly to hide/show it
vueApp.disablePlayButton(false);
this.$refs.chickenBadge.style.display = 'none';
vueApp.showSpinner();
document.body.style.overflow = 'visible';
window.scrollY = 0;
this.hidePopupsIfGameCloses();
extern.leaveGame(this.afterLeftGame);
vueData.ui.showCornerButtons = true;
// OneSignal elements are not part of the Vue app
var oneSignalBell = document.getElementById('onesignal-bell-container');
if (oneSignalBell) {
oneSignalBell.style.display = 'inline-block';
}
},
hidePopupsIfGameCloses: function() {
const gamePopups = vueApp.$refs.gameScreen.$children;
if (Array.isArray(gamePopups)) {
gamePopups.forEach( gamePopup => {;
if ( gamePopup.isShowing === true && gamePopup.$el.id !== 'pausePopup' ) {
gamePopup.close();
console.log(`Closing ${gamePopup.$el.id}`);
}
});
}
},
afterLeftGame: function () {
vueApp.hideSpinner();
vueApp.showTitleScreenAd();
vueApp.switchToHomeUi();
},
onHelpClicked: function () {
this.hideGameMenu();
vueApp.showHelpPopup();
BAWK.play('ui_popupopen');
},
onShareLinkClicked: function () {
extern.inviteFriends();
BAWK.play('ui_popupopen');
},
onSettingsClicked: function () {
this.hideGameMenu();
vueApp.showSettingsPopup();
BAWK.play('ui_popupopen');
},
onShareLinkConfirm: function () {
extern.copyFriendCode(this.$refs.shareLinkUrl);
},
onShareLinkClosed: function () {
this.showGameMenu();
},
onEquipClicked: function () {
this.game.pauseScreen.wasGameInventoryOpen = true;
this.game.pauseScreen.classChanged = false;
this.gaSend('inventory');
vueApp.switchToEquipUi();
BAWK.play('ui_equip');
},
onSwitchTeamClicked: function () {
this.hideGameMenu();
BAWK.play('ui_popupopen');
this.$refs.switchTeamPopup.show();
},
onSwitchTeamCancel: function () {
this.showGameMenu();
},
onSwitchTeamConfirm: function () {
extern.switchTeam();
},
onControllerButton: function (e) {
switch (e.detail) {
case '9':
if (document.hasFocus() && !this.isRespawning && this.delayTheCracking) {
this.onPlayClicked();
}
break;
case '4':
case '6':
case '14':
vueData.classIdx = Math.max(0, vueData.classIdx - 1);
this.$refs.weaponSelect.selectClass(vueData.classIdx);
break;
case '5':
case '7':
case '15':
vueData.classIdx = Math.min(6, vueData.classIdx + 1);
this.$refs.weaponSelect.selectClass(vueData.classIdx);
break;
}
},
gaSendOnClassChange() {
if (!this.game.pauseScreen.wasGameInventoryOpen && this.game.pauseScreen.classChanged) {
ga('send', 'event', 'respawn-popup', 'classClick', Object.keys(CharClass).find(key => CharClass[key] === vueApp.classIdx));
}
// reset for good measure
this.game.pauseScreen.wasGameInventoryOpen = false;
this.game.pauseScreen.classChanged = false;
},
onPlayClicked: function () {
vueApp.disableRespawnButton(true);
vueData.ui.showCornerButtons = false;
extern.respawn();
this.isPaused = false;
BAWK.play('ui_playconfirm');
this.gaSendOnClassChange();
},
onSpectateClicked: function () {
this.gaSend('spectate');
this.hideGameMenu();
vueData.ui.showCornerButtons = false;
extern.enterSpectatorMode();
BAWK.play('ui_playconfirm');
},
showPlayerActionsPopup: function () {
this.hideGameMenu();
this.$refs.playerActionsPopup.show();
},
onPlayerActionsCancel: function () {
this.showGameMenu();
},
onMuteClicked: function () {
this.$refs.playerActionsPopup.hide();
this.playerActionsPopup.muteFunc();
},
onBootClicked: function () {
this.$refs.playerActionsPopup.hide();
this.playerActionsPopup.bootFunc();
},
resizeBannerAdTagForGame: function() {
const pauseAdPlacement = document.getElementById('pauseAdPlacement');
const rect = document.getElementById('pausePopup').getBoundingClientRect();
pauseAdPlacement.style.top = (rect.height).toString() + 'px';
},
earnInGameReward() {
this.hideGameMenu();
vueApp.setDarkOverlay(true);
this.pokiRewardReady = false;
this.isPokiNewRewardTimer = false;
extern.api_inGameReward(this.inGameRewardSuccessCallback, this.inGameRewardFailedCallback, this.rewardReachedDailyLimits);
extern.setVolume(0);
},
inGameRewardSuccessCallback() {
extern.pokiRewardedBreak(this.inGameRewardIsGranted, this.inGameRewardFailedCallback);
},
inGameRewardIsGranted(rewardValue) {
console.log('inGameRewardSuccessCallback');
this.isPokiNewRewardTimer = true;
vueApp.showGiveStuffPopup('reward_title', rewardValue, '');
ga('send', 'event', 'Poki', 'Rewarded Video', 'Reward Success', this.pokiRewNum);
this.pokiRewNum ++;
},
inGameRewardFailedCallback() {
vueApp.showGenericPopup('p_redeem_error_title', 'in_game_reward_try_again', 'ok');
this.isPokiNewRewardTimer = false;
ga('send', 'event', 'Poki', 'Rewarded Video', 'Failed');
},
rewardReachedDailyLimits() {
vueApp.showGenericPopup('in_game_reward_title', 'in_game_reward_try_again', 'ok');
this.isPokiNewRewardTimer = false;
localStore.setItem('inGameRewardLimitDate', Date.now());
extern.setVolume();
ga('send', 'event', 'Poki', 'Rewarded Video', 'Reached Daily Limit');
},
pokiTimers(value, milliseconds) {
let pokiSetTimer;
if (value === false) {
clearTimeout(pokiSetTimer);
console.log('cancelTimer');
return;
}
pokiSetTimer = setTimeout(() => this.pokiRewardReady = true, milliseconds);
},
pauseWeaponSelect() {
this.game.pauseScreen.wasGameInventoryOpen = false;
this.game.pauseScreen.classChanged = true;
vueApp.$refs.equipScreen.onChangedClass();
},
songHasChanged() {
setTimeout(() => this.songChanged = false , 2000);
},
// So crazy games requires an array for multiple display ad calls on the same screen
crazyAdsRespawn() {
if (!crazyGamesActive && !testCrazy) return;
// Removing delay per CG's request. Refresh rate is restricted server-side
/*if (this.cGrespawnBannerTimeout) return;
this.cGrespawnBannerTimeout = setTimeout(() => {
clearTimeout(this.cGrespawnBannerTimeout);
this.cGrespawnBannerTimeout = null;
}, 20000);*/
this.cGrespawnBannerErrors = 0;
crazysdk.requestBanner([{
containerId: 'shellshockers_respawn_banner-new_ad',
size: '728x90',
},{
containerId: 'shellshockers_respawn_banner_2_ad',
size: '300x250',
}]);
},
onClickCreator(url) {
window.open(url, )
},
openVipPopup() {
this.$refs.playerActionsPopup.hide();
vueApp.showSubStorePopup();
},
gaSend(label) {
if (!label) return;
ga('send', 'event', 'respawn-popup', 'click', label);
},
playIncentivizedAd(e) {
if (!this.chicknWinnerReady || this.hasChwPlayClicked || this.isChicknWinnerError) {
e.preventDefault();
return;
}
vueApp.disableRespawnButton(true);
this.hasChwPlayClicked = true;
vueApp.loadNuggetVideo();
vueApp.chicknWinnerNotReady();
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', 'click-in-game');
}
},
computed: {
isRespawning: function () {
return this.game.respawnTime > 0;
},
isTeamGame: function () {
// Would be better to use the same enum as the client game code
return this.game.gameType !== 0;
},
teamColorCss: function () {
return this.game.team === this.ui.team.blue ? 'blueTeam btn_red bevel_red' : 'redTeam btn_blue bevel_blue';
},
teamName: function () {
return this.game.team === this.ui.team.blue ? this.loc.p_pause_joinred : this.loc.p_pause_joinblue;
},
newTeamColorCss: function () {
return this.game.team === this.ui.team.blue ? 'redTeam btn_red' : 'blueTeam btn_blue';
},
newTeamName: function () {
return this.game.team === this.ui.team.blue ? this.loc.team_red : this.loc.team_blue;
},
muteButtonLabel: function () {
return this.playerActionsPopup.muted ? this.loc.ui_game_playeractions_unmute : this.loc.ui_game_playeractions_mute;
},
showIngameWidget() {
if (!this.isPaused && this.songChanged) {
this.songHasChanged();
return true;
}
return false;
},
showMusicWidget() {
return this.ui.showScreen === 2;
},
isEggStoreSaleItem() {
return this.eggStoreItems.some( item => item['salePrice'] !== '' && this.ui.showCornerButtons);
},
upgradeBadgeUrl() {
return this.isSubscriber ? 'img/vip-club/vip-club-popup-emblem.png' : 'img/ico_chickenBadge.png';
},
playerSocial() {
return SOCIALMEDIA[this.playerActionsPopup.social.id];
},
progressMsg() {
if (this.isChicknWinnerError) {
return this.loc.chw_error_text;
}
if (this.chicknWinnerDailyLimitReached && this.chicknWinnerCounter > 0) {
return this.loc.chw_daily_limit_msg;
}
if (this.chicknWinnerReady) {
if (this.chicknWinnerCounter === 0) {
return this.loc.chw_ready_msg;
} else {
return this.loc.chw_cooldown_msg;
}
} else {
return this.loc.chw_free_eggs_coming;
}
},
progressBarWrapClass() {
if (this.isChicknWinnerError) {
return 'chw-progress-bar-wrap-error';
}
if (this.chicknWinnerReady) {
return 'chw-progress-bar-wrap-complete';
}
},
playAdText() {
if (this.chicknWinnerReady && this.chicknWinnerCounter === 0) {
return this.loc.chw_btn_free_reward;
} else {
return this.loc.chw_btn_watch_ad;
}
},
chwShowCountdown() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'hideme';
} else {
if (this.chicknWinnerReady) {
return 'hideme';
} else {
return 'display-inline';
}
}
},
chwChickSrc() {
if (this.chicknWinnerDailyLimitReached || this.isChicknWinnerError) {
return 'img/chicken-nugget/chickLoop_daily_limit.svg';
} else {
if (!this.chicknWinnerReady) {
return 'img/chicken-nugget/chickLoop_sleep.svg';
} else {
return 'img/chicken-nugget/chickLoop_speak.svg';
}
}
},
},
watch: {
isPokiGameLoad(value) {
this.pokiTimers(value, this.videoRewardTimers.initial);
// this.pokiTimers(value, 300);
},
isPokiNewRewardTimer(value) {
this.pokiTimers(value, this.videoRewardTimers.primary);
// this.pokiTimers(value, 300);
},
kname(val) {
this.killedByMessage = this.loc['ui_game_killedby'].format(val);
},
kdname(val) {
this.killedMessage = this.loc['ui_game_youkilled'].format(val);
},
}
};
</script>
<script id="vip-club-template" type="text/x-template">
<div class="vip-club fullwidth">
<div class="vip-club-log-content--outer roundme_sm display-grid grid-align-items-center grid-column-1-2 grid-gap-space-lg">
<header class="grid-span-2-start-1">
<!-- <h2><span class="text-orange">V</span>ery <span class="text-orange">I</span>mportant <span class="text-orange">P</span>oultry</h2> -->
<span class="sr-only">Very Important Poultry</span>
<img class="vip-club-water-mark display-block center_h" src="img/vip-club/very-important-poultry.png" alt="Very Important Poultry text image">
</header>
<div class="vip-club--logo">
<img src="img/vip-club/vip-club-popup-emblem.png">
</div>
<div class="vip-club--content">
<div class="subs-info">
<ul>
<li>{{loc.p_chicken_goldfeature1}}</li>
<li v-html="loc.p_chicken_goldfeature3"></li>
<li>{{loc.p_chicken_goldfeature2}}</li>
<li>{{loc.s_popup_feature_premium_items}}</li>
</ul>
<!-- <p class="more">{{loc.home_media_apply_now}}</p> -->
<button v-on:click="openVipPopup" class="margins_lg ss_button btn_sm btn_vip-button bevel_blue">{{loc.faq}}</button>
</div>
</div>
</div>
<div class="subscription-plans" :class="[hasPlan ? 'display-grid grid-column-1-2 grid-gap-space-lg' : '']">
<div class="vip-club-items--outer display-grid" :class="[hasPlan ? 'grid-column-1-eq grid-just-item-center' : 'grid-column-3-eq']">
<sub-item v-for="sub in subs" :key="sub.sku" :item="sub" :loc="loc" :upgrade-name="upgradeName" :is-subscriber="isSubscriber" :is-upgraded="isUpgraded" :account-set="accountSettled"></sub-item>
</div>
<div v-if="hasPlan" class="manage-subscription-wrapper">
<div v-if="hasPlan" class="plan-details text-center vip-club-log-content--outer roundme_sm">
<h5>{{loc.sRenewalDate}}:</h5>
<p v-if="expireDate" class="plan-expiry">{{ expireDate }}</p>
<p class="manage-details" v-html="manageInfo"></p>
<button class="ss_button btn_manage_sub btn_sm btn_yolk bevel_yolk btn_vip-button bevel_blue"" v-on:click="onManageClick">{{loc.sManageBtn}}</button>
</div>
</div>
</div>
</div>
</script>
<template id="comp-sub-item">
<div v-if="isActive" class="vip-item" :class="nameLowerCaseHyphens">
<div class="vip-item--inner centered">
<div class="subscription-details">
<header>
<h3>{{loc[name]}}</h3>
</header>
<p class="price-tag roundme_sm" v-html="priceTag"></p>
<button v-if="!hasSub" class="ss_button btn_sm btn_vip-button bevel_blue" v-on:click="subClick">
{{loc[buyBtnText]}}
</button>
</div>
</div>
<div v-if="flagText" class="vip-banner" :class="flagText">
<span>{{loc[flagText]}}</span>
</div>
<img aria-hidden="true" :src="img">
</div>
</template>
<script>
const comp_sub_item = {
template: '#comp-sub-item',
props: ['loc', 'item', 'upgradeName', 'isUpgraded', 'isSubscriber'],
data() {
return {
isCurrentSub: false,
hasSub: false,
hasUpgrade: false,
locName: '',
};
},
methods: {
subClick() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
BAWK.play('ui_click');
if (this.hasSub) {
extern.buyProductForMoney();
} else {
extern.buyProductForMoney(this.item.sku, true);
ga('send', 'event', 'subscriptions', 'click', this.locName);
}
}
},
computed: {
nameLowerCaseHyphens() {
this.locName = this.item.name.replace(' ', '-').toLowerCase().replace(' ', '-');
return this.locName;
},
name() {
return `s-${this.locName}-title`;
},
img() {
return `img/vip-club/vip-club-popup-item-${this.locName}-bg.png`;
},
priceTag() {
let price = this.item.salePrice ? this.item.salePrice : this.item.price,
priceWcents = `${(price / 100).toFixed(2)}`,
thePrice = priceWcents.split('.');
return `$${thePrice[0]}<span class="price-tag--cents">.${thePrice[1]}</span>`;
},
buyBtnText() {
if (this.isCurrentSub && this.hasUpgrade) {
return 's-btn-txt-change';
}
return 's-btn-txt-subscribe';
},
isActive() {
if (this.isCurrentSub && this.hasUpgrade) {
return true
} else if (this.hasSub && this.hasUpgrade) {
return false
} else {
return true
};
},
flagText() {
if (this.isCurrentSub && this.hasUpgrade) return 'p_egg_shop_purchased';
return this.item.flagText;
}
},
watch: {
upgradeName(val) {
},
isUpgraded(val) {
this.hasUpgrade = val;
this.hasSub = this.isSubscriber && this.hasUpgrade;
this.isCurrentSub = this.upgradeName === this.item.name && this.hasUpgrade;
}
}
};
</script>
<script>
var compVipClubTemplate = {
template: '#vip-club-template',
components: {
'sub-item': comp_sub_item,
},
data() {
return vueData;
},
props: ['loc', 'subs'],
methods: {
onManageClick() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
extern.buyProductForMoney();
},
openVipPopup() {
if (this.$parent.$el.id === 'shell-subscriptions') {
this.$parent.$parent.hide();
} else {
this.$parent.hide();
}
BAWK.play('ui_click');
vueApp.showVipPopup();
}
},
computed: {
hasPlan() {
return this.isSubscriber && this.isUpgraded;
},
expireDate() {
if (this.hasPlan) {
return new Date(extern.account.upgradeExpiryDate).toUTCString();
}
return;
},
planName() {
if (this.hasPlan) {
return 's-' + this.upgradeName.replace(' ', '-').toLowerCase().replace(' ', '-') + '-title';
}
return;
},
manageInfo() {
return this.loc.sManageInfo;
}
}
};
</script><script id="give-stuff-popup" type="text/x-template">
<!-- Popup: Give Stuff -->
<!-- <large-popup id="giveStuffPopup" ref="giveStuffPopup" :popup-model="giveStuffPopup" @popup-closed="onSharedPopupClosed" :class="giveStuffPopup.type"> -->
<large-popup id="giveStuffPopup" ref="giveStuffPopup" :popup-model="giveStuffPopup" :class="giveStuffPopup.type">
<template slot="content">
<div id="giveStuffPopup-content" class="giveStuffPopup-content" :class="{'fullwidth' : giveStuffPopup.type === 'twitchDrops'}">
<div v-if="giveStuffPopup.type === 'vip'" id="give-stuff-icon" class="give-stuff-icon">
<img src="img/vip-club/vip-club-popup-emblem.png" alt="Shell Shockers VIP">
</div>
<h3 v-if="giveStuffPopup.type !== 'twitchDrops'" :class="{'popup-title-vip' : giveStuffPopup.type === 'vip'}" id="popup_title" class="roundme_sm text-center">
{{ loc[giveStuffPopup.titleLoc] }}
</h3>
<h2 v-if="giveStuffPopup.type === 'twitchDrops'" id="popup_title" class="roundme_sm text-center title-shadow text-twitch-yellow">
{{ loc[giveStuffPopup.titleLoc] }}
</h2>
<p v-if="giveStuffPopup.type === 'twitchDrops'" class="text-center">{{ loc.give_stuff_twitch_sub_desc }}</p>
<div v-show="(giveStuffPopup.eggs)" class="f_row">
<div class="egg-give-stuff">
<img src="img/ico_goldenEgg.png" />
<h2>{{giveStuffPopup.eggs}}</h2>
</div>
</div>
<div v-show="giveStuffPopup.rickroll" class="f_row">
<img src="img/rickroll.gif" style="margin-bottom: 1em; height: 25em;" />
</div>
<div v-show="giveStuffPopup.eggOrg" class="f_row">
<img src="img/egg-org/eggOrg_timeTravel_splash800x600-min.png" style="margin-bottom: 1em;">
</div>
<div v-show="(giveStuffPopup.items && giveStuffPopup.items.length > 0)" class="items-container f_row grid-gap-1" :class="{'popup-items-vip' : giveStuffPopup.type === 'vip'}">
<item v-for="i in giveStuffPopup.items" :item="i" :key="i.id" :isSelected="false" :show-item-only="true"></item>
</div>
<p v-if="giveStuffPopup.type === 'twitchDrops'"></p>
</div>
<footer :class="{'text-center' : giveStuffPopup.type === 'twitchDrops'}">
<!-- <p v-if="giveStuffPopup.type === 'twitchDrops'" class="text-center">{{ loc.give_stuff_twitch_footer_desc }}</p> -->
<button class="ss_button width_xs text-center" :class="giveStuffPopup.type === 'twitchDrops' ? 'twitch-btn twitch-btn-purple' : 'btn_green bevel_green'" @click="onGiveStuffComplete">{{ loc.ok }}</button>
<button v-if="giveStuffPopup.type === 'twitchDrops'"class="ss_button twitch-btn twitch-btn-pink width_xs text-center" @click="onClickTwitchDropsMore">Get More!</button>
</footer>
</template>
<template slot="confirm">{{ loc.confirm }}</template>
</large-popup>
</script>
<script>
const GIVESTUFFPOPUP = {
template: '#give-stuff-popup',
components: {
'item': comp_item,
},
props: ['loc', 'giveStuffPopup'],
data: function () {
return {
languageCode: this.selectedLanguageCode,
eggBalance: 0,
vueData,
}
},
methods: {
onGiveStuffComplete: function () {
this.giveStuffPopup.eggOrg = false;
this.giveStuffPopup.rickroll = false;
this.$refs.giveStuffPopup.toggle();
},
onClickTwitchDropsMore() {
window.open(dynamicContentPrefix + 'twitch');
this.onGiveStuffComplete();
}
},
};
</script>
<script>
function startVue(languageCode, locData) {
vueData.extern = extern;
vueData.loc = locData;
vueApp = new Vue({
el: '#app',
components: {
'dark-overlay': comp_dark_overlay,
'light-overlay': comp_light_overlay,
'spinner-overlay': comp_spinner_overlay,
'gdpr': comp_gdpr,
'settings': comp_settings,
'help': comp_help,
'vip-help': vip_help,
'egg-store': comp_egg_store,
'subscription-store': compVipClubTemplate,
// 'subscription-store': comp_egg_store,
'item': comp_item,
'home-screen': comp_home_screen,
'equip-screen': comp_equip_screen,
'game-screen': comp_game_screen,
// 'gold-chicken-popup': comp_gold_chicken_popup,
'chicken-nugget-popup': comp_chickn_winner_popup,
'egg-store-item': comp_store_item,
'give-stuff-popup': GIVESTUFFPOPUP,
},
data: vueData,
createdTime: null,
mountedTime: null,
fullyRenderedTime: null,
multisizeAdTag: null,
created () {
console.log('Vue instance created');
createdTime = performance.now();
this.currentLanguageCode = languageCode;
this.urlParams = parsedUrl.query.open ? parsedUrl.query.open : null;
},
mounted () {
console.log('Vue instance mounted');
mountedTime = performance.now();
console.log('create -> mount time (ms): ' + (mountedTime - createdTime));
this.currentGameType = extern.gameType;
// Cannot modify data within the mounted hook, so wait until next tick
this.$nextTick(function () {
fullyRenderedTime = performance.now();
console.log('mounted -> fully rendered time (ms): ' + (fullyRenderedTime - mountedTime));
console.log('created -> fully rendered time (ms): ' + (fullyRenderedTime - createdTime));
this.ready = true;
// vueApp.getNuggetTimer();
//this.showSpinner('ui_game_loading', 'ui_game_waitforit');
// this.histPushState({game: this.ui.screens.home}, 'Shellshockers home', '?home');
//this.playMusic();
this.getLocLang();
extern.continueStartup();
this.changelog.current = changeLogData;
//this.fetchSponsors();
});
},
methods: {
getCanvas: function () {
return this.$refs.canvas;
},
playMusic: function () {
myAudio = new Audio('./sound/theme');
// Uncomment for looping.
// myAudio.addEventListener('ended', function() {
// this.currentTime = 0;
// this.play();
// }, false);
myAudio.volume = this.volume;
myAudio.play();
},
changeLanguage: function (languageCode) {
extern.getLanguageData(languageCode, this.setLocData);
},
setLocData: function (languageCode, newLocData) {
this.currentLanguageCode = getStoredString('languageSelected', null) ? localStore.getItem('languageSelected') : languageCode;
this.loc = newLocData;
},
setPlayerName: function (playerName) {
this.playerName = playerName.substring(0, 128);
},
showSpinner: function (headerLocKey, footerLocKey) {
this.$refs.spinnerOverlay.show(headerLocKey, footerLocKey);
},
showSpinnerLoadProgress: function (percent) {
this.$refs.spinnerOverlay.showSpinnerLoadProgress(percent);
},
hideSpinner: function () {
this.$refs.spinnerOverlay.hide();
},
onSettingsPopupOpened: function () {
this.$refs.settings.captureOriginalSettings();
},
onSettingsPopupSwitchTabMisc: function () {
this.$refs.settings.switchTab('misc_button');
},
onSettingsX: function () {
this.$refs.settings.applyOriginalSettings();
this.$refs.settings.cancelLanguageSelect();
},
onSettingsQuickSave() {
this.$refs.settings.quickSave();
},
onNoAnonPopupConfirm: function () {
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.denyAnonUserPopup, this.googleAnalytics.label.signInClick);
this.showFirebaseSignIn();
},
onSharedPopupClosed: function () {
// If in-game, show game menu after closing the popup
this.blackFridayBanner = false;
if (this.ui.showScreen === this.ui.screens.game && extern.inGame) {
this.showGameMenu();
}
},
onGiveStuffComplete: function () {
this.$refs.giveStuffPopup.toggle();
},
onPrivacyOptionsOpened: function () {
this.showPrivacyPopup();
},
/**
* Creates a generic popup that passes content 3 data options to slots on the genericPopup smallPopup
* @param titleLockKey mixed - popup header text
* @param contentLocKey mixed- popup content
* @param confirmLocKey mixed - popup button text
*/
showGenericPopup: function (titleLocKey, contentLocKey, confirmLocKey, hideBackgroundPopup) {
this.genericMessagePopup.titleLocKey = titleLocKey;
this.genericMessagePopup.contentLocKey = contentLocKey;
this.genericMessagePopup.confirmLocKey = confirmLocKey;
this.hidePausePopupIfGenericPopupOpen();
this.$refs.genericPopup.show();
// vueApp.setDarkOverlay();
},
hidePausePopupIfGenericPopupOpen: function() {
if (!this.$refs.gameScreen.$refs.pausePopup && $refs.gameScreen.$refs.pausePopup.isShowing === false) {
return;
}
return this.$refs.gameScreen.$refs.pausePopup.hide();
},
showOpenUrlPopup: function (url, titleLocKey, content, confirmLocKey, cancelLocKey) {
console.log('title: ' + this.loc[titleLocKey]);
console.log('confirm: ' + this.loc[confirmLocKey]);
console.log('cancel: ' + this.loc[cancelLocKey]);
this.openUrlPopup.url = url;
this.openUrlPopup.titleLocKey = titleLocKey;
this.openUrlPopup.content = content;
this.openUrlPopup.confirmLocKey = confirmLocKey;
this.openUrlPopup.cancelLocKey = cancelLocKey;
this.$refs.openUrlPopup.show();
},
onOpenUrlPopupConfirm: function () {
extern.openUrlAndGiveReward();
},
showUnsupportedPlatformPopup: function (contentLocKey) {
this.ui.showScreen = -1;
this.unsupportedPlatformPopup.contentLocKey = contentLocKey;
this.$refs.unsupportedPlatformPopup.show();
},
showMissingFeaturesPopup: function () {
this.ui.showScreen = -1;
this.$refs.missingFeaturesPopup.show();
},
showFirebaseSignIn: function () {
this.$refs.homeScreen.showSignIn();
},
hideFirebaseSignIn: function () {
this.$refs.firebaseSignInPopup.hide();
},
showCheckEmail: function () {
this.$refs.homeScreen.$refs.checkEmailPopup.show();
},
hideCheckEmail: function () {
this.$refs.homeScreen.$refs.checkEmailPopup.hide();
},
showResendEmail: function () {
this.$refs.homeScreen.$refs.resendEmailPopup.show();
},
hideResendEmail: function () {
this.$refs.homeScreen.$refs.resendEmailPopup.hide();
},
showChickenPopup: function () {
this.$refs.goldChickenPopup.show();
},
hideChickenPopup: function () {
this.$refs.goldChickenPopup.hide();
},
showHelpPopup: function () {
this.hideGameMenu();
this.$refs.helpPopup.show();
},
showVipPopup: function () {
this.hideGameMenu();
BAWK.play('ui_popupopen');
this.$refs.vipPopup.show();
},
showGetMobilePopup() {
this.$refs.mobileAdPopup.show();
},
showAttentionPopup: function () {
this.hideGameMenu();
this.$refs.anonWarningPopup.show();
},
hideHelpPopup: function () {
this.$refs.helpPopup.hide();
},
showSettingsPopup: function () {
this.hideGameMenu();
this.$refs.settingsPopup.show();
extern.settingsMenuOpened();
},
hideSettingsPopup: function () {
this.$refs.settingsPopup.hide();
},
showEggStorePopup: function () {
this.$nextTick(() => {
this.hideGameMenu();
this.$refs.eggStorePopup.show();
if (this.isSale) {
this.blackFridayBanner = true;
}
ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup, this.googleAnalytics.label.getMoreEggs);
});
},
showSubStorePopup: function () {
this.$nextTick(() => {
this.hideGameMenu();
this.$refs.subStorePopup.show();
BAWK.play('ui_popupopen');
// ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup, this.googleAnalytics.label.getMoreEggs);
});
},
vipEndedPopup() {
this.$refs.vipEnded.show();
BAWK.play('ui_popupopen');
},
showPopupEggStoreSingle(sku) {
if (!sku) {
console.log('No sku for popup');
return;
}
if (!this.premiumShopItems.some( i => i.sku === sku)) {
vueApp.showGenericPopup("uh_oh", "p_egg_shop_no_item_desc", "ok");
return;
}
this.eggStorePopupSku = sku;
this.$refs.popupEggStoreSingle.show();
},
hideEggStorePopup: function () {
this.$refs.eggStorePopup.hide();
},
showChangelogPopup: function () {
this.$refs.changelogPopup.show();
},
showHistoryChangelogPopup() {
fetch('./changelog/oldChangelog.json', {cache: "no-cache"})
.then(response => response.json())
.then(data => {
data.forEach(el => this.changelog.current.push(el));
});
this.changelog.showHistoryBtn = false;
},
hideChangelogPopup: function () {
this.$refs.changelogPopup.hide();
},
showGiveStuffPopup: function (titleLoc, eggs, items, type, callback) {
if (this.giveStuffPopup.eggOrg) {
ga('send', 'event', 'Egg Org', 'Code Cracked', 'redeemed');
}
type = type || '';
this.giveStuffPopup.titleLoc = titleLoc;
this.giveStuffPopup.eggs = eggs;
this.giveStuffPopup.items = items;
this.giveStuffPopup.type = type;
this.$refs.giveStuffPopup.$refs.giveStuffPopup.show();
if (callback) callback();
},
showEggOrgPopup() {
this.giveStuffPopup.eggOrg = true;
this.showGiveStuffPopup('p_give_stuff_title');
},
showShareLinkPopup: function (url) {
this.hideGameMenu();
this.game.shareLinkPopup.url = url;
this.$refs.gameScreen.$refs.shareLinkPopup.show();
},
hideShareLinkPopup() {
if (!this.$refs.gameScreen.$refs.shareLinkPopup.isShowing) {
return;
}
this.$refs.gameScreen.$refs.shareLinkPopup.hide();
},
showJoinPrivateGamePopup: function (code) {
this.$refs.homeScreen.$refs.playPanel.showJoinPrivateGamePopup(code);
},
showPrivateGamePopup() {
this.$refs.homeScreen.$refs.playPanel.$refs.createPrivateGamePopup.toggle();
},
switchToHomeUi: function () {
this.ui.showScreen = this.ui.screens.home;
// vueApp.showTitleScreenAd();
// this.histPushState({game: this.ui.screens.home}, 'Shellshockers home', '?home');
this.gameUiRemoveClassForNoScroll();
extern.chwRadialProgress();
},
switchToEquipUi: function () {
console.log('switchToEquipUi called');
this.ui.showScreen = this.ui.screens.equip;
this.$refs.equipScreen.setup();
this.$refs.equipScreen.switchToInventory();
if (extern.inGame) {
this.hideGameMenu();
extern.openEquipInGame();
}
else {
vueApp.hideTitleScreenAd();
}
},
switchToGameUi: function (isGameOwner) {
this.ui.showScreen = this.ui.screens.game;
this.game.isGameOwner = isGameOwner;
},
gameUiAddClassForNoScroll() {
let html = document.getElementsByTagName("html")[0];
html.classList.add('noScrollIngame');
},
gameUiRemoveClassForNoScroll() {
let html = document.getElementsByTagName("html")[0];
html.classList.remove('noScrollIngame');
},
switchToGameUiQuickPlay(isGameOwner) {
this.ui.showScreen = this.ui.screens.game;
this.game.isGameOwner = isGameOwner;
this.ui.showCornerButtons = false;
vueApp.hideTitleScreenAd();
this.gameUiAddClassForNoScroll();
},
showGameMenu: function () {
this.hideSpinner();
this.$refs.gameScreen.showGameMenu();
// this.histPushState({game: this.ui.screens.game}, 'Shellshockers game menu', '?game=menu');
},
hideGameMenu: function () {
this.$refs.gameScreen.hideGameMenu();
// this.histPushState({game: this.ui.screens.game}, 'Shellshockers in game', '?game=play');
},
onMiniGameCompleted: function () {
this.$refs.homeScreen.onMiniGameCompleted();
},
setShellColor: function (colorIdx) {
this.equip.colorIdx = colorIdx;
},
setAccountUpgraded: function (upgraded, endDate) {
this.isUpgraded = upgraded;
this.equip.extraColorsLocked = !this.isUpgraded;
this.nugStart = endDate;
},
setDarkOverlay: function (visible, overlayClass) {
this.$refs.darkOverlay.show = visible;
this.$refs.darkOverlay.overlayClass = overlayClass;
},
setLightOverlay: function (visible, overlayClass) {
this.$refs.lightOverlay.show = visible;
this.$refs.darkOverlay.overlayClass = overlayClass;
},
authCompleted: function () {
this.accountSettled = true;
if (vueApp.$refs.firebaseSignInPopup.isShowing) this.hideFirebaseSignIn();
},
showItemOnEquipScreen: function (item) {
this.switchToEquipUi();
this.$refs.equipScreen.autoSelectItem(item);
},
showTaggedItemsOnEquipScreen: function (tag) {
this.switchToEquipUi();
this.$refs.equipScreen.showTaggedItems(tag);
},
showSelectedTaggedItemsOnEquipScreen: function (tag) {
this.switchToEquipUi();
this.$refs.equipScreen.showSelectedTagItems(tag);
},
useHouseAdSmall: function (smallHouseAd) {
this.ui.houseAds.small = smallHouseAd;
},
useHouseAdBig: function (bigHouseAd) {
this.ui.houseAds.big = bigHouseAd;
},
denyAnonUser: function () {
ga('send', 'event', vueApp.googleAnalytics.cat.playerStats, vueApp.googleAnalytics.action.denyAnonUserPopup);
if (extern.inGame) {
this.hideGameMenu();
}
this.$refs.noAnonPopup.show();
},
showGdprNotification: function () {
this.$refs.gdpr.show();
},
showPrivacyPopup: function () {
this.hideSettingsPopup();
this.$refs.privacyPopup.show();
},
hidePrivacyPopup: function () {
this.$refs.privacyPopup.hide();
this.showSettingsPopup();
},
ofAgeChanged: function () {
extern.setOfAge(this.isOfAge);
BAWK.play('ui_onchange');
},
targetedAdsChanged: function () {
extern.setTargetedAds(this.showTargetedAds);
BAWK.play('ui_onchange');
},
setPrivacySettings: function (ofAge, targetedAds) {
this.isOfAge = ofAge;
this.showTargetedAds = targetedAds;
},
gameJoined: function (gameType, team) {
this.game.gameType = gameType;
this.setTeam(team);
},
setTeam: function (team) {
if (hasValue(team)) {
this.game.team = team;
}
},
showGoldChickenPopup: function () {
this.$refs.goldChickenPopup.show();
},
hideGoldChickenPopup: function () {
this.$refs.goldChickenPopup.hide();
},
showChicknWinnerPopup: function () {
this.$refs.chicknWinner.show();
vueApp.$refs.chickenNugget.showAd();
// this.$refs.chickenNugget.loadMiniGame();
this.isBuyNugget = true;
console.log('showChicknWinnerPopup()');
},
hideChicknWinnerPopup: function () {
this.$refs.chicknWinner.hide();
this.$refs.chickenNugget.onGotWinner();
console.log('Hide nugget');
},
chicknWinnerIsReady() {
if (this.chicknWinnerDailyLimitReached) {
this.chicknWinnerNotReady();
return;
}
setTimeout(() => {
this.chicknWinnerReady = true;
this.hasChwPlayClicked = false;
ga('send', 'event', 'Chickn Winner', 'Free eggs btn', `ready-in-${(this.ui.showScreen === this.ui.screens.game) ? 'game' : 'home'}`);
}, 1000);
},
chicknWinnerNotReady() {
this.chicknWinnerReady = false;
this.hasChwPlayClicked = false;
},
chicknWinnerError() {
this.isChicknWinnerError = true;
},
chicknWinnerDailyLimit() {
this.chicknWinnerDailyLimitReached = true;
this.chicknWinnerNotReady();
},
loadNuggetVideo() {
this.hideGameMenu();
extern.checkStartChicknWinner(true);
BAWK.play('ui_playconfirm');
},
getNuggetTimer() {
return;
this.$refs.homeScreen.$refs.chickenPanel.setupNuggetTimer();
},
onMiniGameCompleted: function () {
this.$refs.chickenNugget.onMiniGameCompleted();
},
placeBannerAdTagForNugget: function (tagEl) {
this.$refs.chickenNugget.placeBannerAdTag(tagEl);
},
useSpecialItemsTag: function (tag) {
this.equip.specialItemsTag = tag;
this.equip.showSpecialItems = true;
},
disableSpecialItems: function () {
this.equip.showSpecialItems = false;
},
setUiSettings: function (settings) {
this.$refs.settings.setSettings(settings);
},
leaveGame: function () {
this.$refs.gameScreen.leaveGame();
},
showPlayerActionsPopup: function (slot) {
this.playerActionsPopup = slot;
this.$refs.gameScreen.showPlayerActionsPopup();
},
onSignInCancelClicked: function () {
vueApp.$refs.firebaseSignInPopup.hide();
BAWK.play('ui_popupclose');
},
anonWarningPopupCancel: function() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
this.urlParamSet = this.urlParams ? true : null;
this.shellShockUrlParamaterEvents();
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto, this.googleAnalytics.label.understood);
return anonWarnConfrimed === null && localStore.setItem('anonWarningConfirmed', true);
},
anonWarningPopupConfrim() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
anonWarnConfrimed === null && localStore.setItem('anonWarningConfirmed', true);
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto, this.googleAnalytics.label.signInClick);
extern.showSignInDialog();
this.urlParamSet = false;
vueApp.$refs.firebaseSignInPopup.show();
},
conditionalAnonWarningCall: function() {
let anonWarnConfrimed = localStore.getItem('anonWarningConfirmed');
if ( ! hasValue(anonWarnConfrimed) && this.isAnonymous) {
vueApp.showAttentionPopup();
ga('send', 'event', this.googleAnalytics.cat.playerStats, this.googleAnalytics.action.anonymousPopupOpenAuto);
}
},
needMoreEggsPopupCall: function() {
ga('send', 'event', this.googleAnalytics.cat.itemShop, this.googleAnalytics.action.shopItemNeedMoreEggsPopup);
this.$refs.needMoreEggsPopup.show();
},
/**
* Not 100 % certain this should live in vue but here it is.
* Add the ability to use url paramaters to trigger events in the game.
* e.g. shellshock.io/?open=eggStore&type=Hat&item=1111 will open the spiderman hat item.
* Called in the extern closure under gameApp.js => afterGameReady()
*/
shellShockUrlParamaterEvents() {
// VUE next tick https://vuejs.org/v2/api/#Vue-nextTick
this.$nextTick( ()=> {
this.doSsUlrParams();
});
},
doSsUlrParams() {
if ( ! this.urlParams) {
return;
}
console.log(hasValue(this.isAnonymous));
if (hasValue(this.ui.houseAds.big)) {
this.urlParamSet = false;
return;
} else if (this.isAnonymous && ! hasValue(localStore.getItem('anonWarningConfirmed'))) {
this.urlParamSet = false;
console.log('Almost there!');
this.conditionalAnonWarningCall();
return;
}
console.log('Passed Popup gate');
switch (this.urlParams) {
case 'eggStore' :
// Opens the purchase egg store popup
this.showEggStorePopup();
break;
case 'goldenChicken' :
// Opens the golden chicken popup
vueApp.$refs.goldChickenPopup.show();
break;
case 'twoTimesTheEggs' :
// Opens the chicken nugget video
extern.checkStartChicknWinner(true);
BAWK.play('ui_playconfirm');
break;
case 'itemShop' :
// Opens shop options
// /?open=itemShop
// /?open=itemShop&type=Hat/Stamp/Primary/Secondary/Grenade/Premium/Tagged
// /?open=itemShop&gunClass=Soldier/Soldier/Scrambler/Ranger/Eggsploder/Whipper/Crackshot/TriHard
// /?open=itemShop&item=1111 opens hat store and then selects item
// /?open=itemShop&item=1111&openBuyNow=1 opens hat store, selects item and then opens items popup
this.eggStoreUrlParams();
break;
case 'vipStore' :
vueApp.showSubStorePopup();
break;
case 'redeem' :
vueApp.switchToEquipUi();
BAWK.play('ui_popupopen');
this.$refs.equipScreen.$refs.redeemCodePopup.show();
if ('code' in parsedUrl.query) this.equip.redeemCodePopup.code = parsedUrl.query.code;
break;
case 'faq' :
this.showHelpPopup();
break;
case 'taggedItems' :
this.openSpecialTagItemsTab();
break;
case 'privateGame' :
this.showPrivateGamePopup();
break;
case 'kotcInstruction' :
this.showKotcInstrucPopup();
break;
default:
null;
};
},
eggStoreUrlParams() {
setTimeout(() => {
const ITEMIDPARAM = parsedUrl.query.hasOwnProperty('item') ? parsedUrl.query.item : '',
TYPEPARAM = parsedUrl.query.hasOwnProperty('type') ? parsedUrl.query.type : '',
GUNCLASS = parsedUrl.query.hasOwnProperty('gunClass') && CharClass.hasOwnProperty(parsedUrl.query.gunClass) ? parsedUrl.query.gunClass : '',
BUYNOWPOPUP = parsedUrl.query.hasOwnProperty('openBuyNow');
if (ITEMIDPARAM) {
const IDISNUMBER = parseInt(ITEMIDPARAM);
let item = extern.catalog.findItemById(IDISNUMBER);
if (!item.is_available) {
vueApp.showGenericPopup("uh_oh", "no_anon_title", "ok")
return;
}
this.switchToEquipUi();
this.$refs.equipScreen.autoSelectItem(item);
if (BUYNOWPOPUP === true) {
console.log('Will it open?');
vueApp.$refs.equipScreen.onBuyItemClicked();
return;
}
} else {
this.openEquipUISwitchToShop();
if (GUNCLASS) {
vueApp.$refs.equipScreen.switchItemType(ItemType['Primary']);
vueApp.$refs.equipScreen.$refs.weapon_select.selectClass(CharClass[GUNCLASS]);
console.log('Has GUN');
} else if (TYPEPARAM) {
console.log('OPEN item');
if (ItemType.hasOwnProperty(TYPEPARAM)) {
vueApp.$refs.equipScreen.switchItemType(ItemType[TYPEPARAM]);
} else {
if (TYPEPARAM === 'Premium') {
vueApp.$refs.equipScreen.onPremiumItemsClicked();
} else if (TYPEPARAM === 'Tagged') {
vueApp.$refs.equipScreen.onTaggedItemsClicked();
}
}
}
}
}, 45);
},
openSpecialTagItemsTab() {
let tag = parsedUrl.query.tag ? parsedUrl.query.tag : null;
vueApp.showSelectedTaggedItemsOnEquipScreen(tag);
},
openEquipUISwitchToShop() {
vueApp.switchToEquipUi();
vueApp.$refs.equipScreen.switchToShop();
},
delayInGamePlayButtons() {
vueApp.$refs.gameScreen.delayGameMenuPlayButtons();
},
//Call/hide display ads
hideRespawnDisplayAd() {
this.$refs.gameScreen.$refs.respawnDisplayAd.hide();
this.$refs.gameScreen.$refs.respawnTwoDisplayAd.hide();
},
showRespawnDisplayAd() {
this.$refs.gameScreen.$refs.respawnDisplayAd.show();
this.$refs.gameScreen.$refs.respawnTwoDisplayAd.show();
},
hideLoadingScreenAd() {
this.$refs.spinnerOverlay.$refs.loadingScreenDisplayAd.hide()
},
showLoadingScreenAd() {
this.$refs.spinnerOverlay.$refs.loadingScreenDisplayAd.show();
// this.histPushState({game: 3}, 'Shellshockers Loading display ad', '?loadingAd=true');
},
displayAdEventObject(event) {
let object = event;
this.displayAdObject = object.size[0];
},
showTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.show();
},
hideTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.hide();
},
toggleTitleScreenAd() {
this.$refs.homeScreen.$refs.titleScreenDisplayAd.toggleAd();
},
scrollToTop() {
let position =
document.body.scrollTop || document.documentElement.scrollTop,
scrollAnimation;
if (position) {
window.scrollBy(0, -Math.max(1, Math.floor(position / 10)));
scrollAnimation = setTimeout(this.scrollToTop, 10);
} else clearTimeout(scrollAnimation);
},
externPlayObject(playType, gameType, playerName, mapIdx, joinCode) {
return extern.play({playType, gameType, playerName, mapIdx, joinCode});
},
pleaseWaitPopup() {
vueApp.showGenericPopup("signin_auth_title", "signin_auth_msg");
},
isPlayingPoki() {
this.isPoki = true;
this.ready = true;
return;
},
histPushState(obj, title, param) {
return history.pushState(obj, title, param);
},
disablePlayButton(val) {
return document.querySelector('.play-button').disabled = val;
},
disableRespawnButton(val) {
return document.querySelector('.btn-respawn') ? document.querySelector('.btn-respawn').disabled = val : '';
},
disaplyAdEventObject(event) {
this.displayAdObject = event.size === null ? null : event.size[0];
},
adBlockerPopupToggle() {
return vueApp.$refs.adBlockerPopup.toggle();
},
musicPlayOnce() {
return setTimeout(() => this.$refs.gameScreen.$refs.gameScreenMusic.playOnce(), 2000);
},
musicPause() {
this.$refs.gameScreen.$refs.gameScreenMusic.pause();
},
musicVolumeControl(value) {
return;
this.settingsUi.adjusters.music[0].value = Number(value);
this.$refs.gameScreen.$refs.gameScreenMusic.loadVolume();
},
toggleMusic() {
this.$refs.gameScreen.$refs.gameScreenMusic.toggleMusic();
},
musicWidget(val) {
this.music.isMusic = val;
},
fetchSponsors() {
fetch(this.music.musicJson)
.then((response) => response.json())
.then((sponsors) => this.music.sponsors = sponsors)
.catch((error) => console.log('Sponsors fetch error', error));
},
pwaPopup() {
return this.$refs.pwaPopup.show();
},
pwaBtnClick() {
// Track the click
ga('send', 'event', 'pwa', 'button', 'click');
//close popup
this.$refs.pwaPopup.hide();
// Get the event
this.pwaDeferEvent = extern.getPwaEvent;
if (!this.pwaDeferEvent) {
return;
}
this.pwaDeferEvent.prompt();
this.pwaDeferEvent.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
ga('send', 'event', 'pwa', 'a2hs', choiceResult.outcome);
this.pwaDeferEvent = null;
});
this.pwaDeferEvent = '';
},
signOut() {
this.isUpgraded = false;
this.equip.extraColorsLocked = true;
this.isUpgraded = false;
this.upgradeName = '';
this.isSubscriber = false;
},
mediaTabsStartRotate() {
return this.$refs.homeScreen.$refs.mediaTabs.autoRotateTabs();
},
mediaTabsCancelRotate() {
return this.$refs.homeScreen.$refs.mediaTabs.cancelRotate(true);
},
showAdBlockerVideo() {
this.bannerHouseAd = extern.getHouseAd('bigBanner');
this.showAdBlockerVideoAd = true;
this.hideGameMenu();
this.$refs.adBlockerVideo.show();
},
hideAdBlockerVideo() {
this.$refs.adBlockerVideo.hide();
if (extern.inGame) {
this.showGameMenu();
}
this.bannerHouseAd = {};
this.showAdBlockerVideoAd = false;
},
showKotcInstrucPopup() {
this.$refs.kotcInstrucPopup.show();
},
kotcInstrucPopupHide() {
this.$refs.kotcInstrucPopup.hide();
},
onClickPlayKotcNow() {
this.externPlayObject(vueData.playTypes.joinPublic, 3, this.playerName, '', '');
this.kotcInstrucPopupHide();
},
onVipHelpClosed() {
this.onSharedPopupClosed();
this.showSubStorePopup();
},
getLocLang(val) {
let data = this.loc,
langSetup = {};
if (val) data = val;
const newLoc = Object.entries(data).filter(item => item[0].includes('locLang')).forEach(lang => langSetup[lang[0].split('_').pop('').split("-").pop('')] = lang[1]);
this.$nextTick(() => {
this.locLanguage = langSetup
});
},
onClickTwitchDropsMore() {
window.open(dynamicContentPrefix + 'twitch');
this.onGiveStuffComplete();
},
onPremiumItemsClicked() {
this.openEquipUISwitchToShop();
this.$refs.equipScreen.onPremiumItemsClicked();
}
},
computed: {
portalClass() {
return {
'playing-poki': this.isPoki,
'playing-crazy-games': crazyGamesActive,
'is-vip': this.isSubscriber && this.isUpgraded ? true : false,
}
},
bigBannerAdLink() {
return this.bigHouseAd.link
},
bigBannerAdImg() {
return dynamicContentPrefix + `data/img/art/${this.bigHouseAd.id}${this.bigHouseAd.imageExt}`;
}
},
watch : {
loc(val) {
this.getLocLang(val);
},
}
});
}
</script>
<script defer="" src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon="{"rayId":"719d075cbaa072b4","token":"b4cd973aeca34b509bef2ed0c9e0b720","version":"2021.12.0","si":100}" crossorigin="anonymous"></script>
<img src="https://ad-delivery.net/px.gif?ch=2" style="display: none !important; width: 1px !important; height: 1px !important;"><img src="https://ad.doubleclick.net/favicon.ico?ad=300x250&ad_box_=1&adnet=1&showad=1&size=250x250" style="display: none !important; width: 1px !important; height: 1px !important;"><img src="https://ad-delivery.net/px.gif?ch=1&e=0.04454433828587079" style="display: none !important; width: 1px !important; height: 1px !important;"><iframe height="0" width="0" style="display: none; visibility: hidden;"></iframe><div id="progress-container" style="position: fixed; top: 0px; left: 0px; height: 100vh; width: 100vw; z-index: 2000; background-image: var(--ss-lightoverlay);"><div id="progress-wrapper" class="load_screen" style="position: absolute; left: 50%; top: -6em; transform: translateX(-50%); background-image: none;"><img src="img/logo.svg" id="logo-svg" style="height: 16em;"><div id="progress-outer" style="position: relative; background: rgb(100, 50, 25); border-radius: 2em; height: 3.3em; width: 24em; margin-top: 2em;"><div style="width: 23em; height: 2.2em; background: white; padding: 0.5em; border-radius: 2em; margin: 0.3em 0.5em 0px;"><span id="progressBar" style="display: block; width: 20%; height: 100%; background: orange; border-radius: 2em; margin: 0px 0.3em 0.5em 0%; opacity: 1; transition: margin-left 500ms ease-in-out 0s;"></span></div></div></div><img src="img/BlueWizard-Logo-min.png" style="width: 16em; display: block; margin: 5em auto 0px; z-index: 2000; position: absolute; left: 50%; bottom: 8em; transform: translateX(-50%);"></div><script async="" type="text/javascript" data-cmp-ab="2" src="https://cdn.consentmanager.net/delivery/customdata/bV8xLndfMTM1NjYucl9HRFBSLmxfZW4uZF81MzI0LnhfMjIudi5wLnRfNTMyNC54dF8zMg.js"></script><iframe id="_hjSafeContext_1214820" title="_hjSafeContext" tabindex="-1" aria-hidden="true" src="about:blank" style="display: none !important; width: 1px !important; height: 1px !important; opacity: 0 !important; pointer-events: none !important;"></iframe><iframe name="googlefcPresent" style="display: none; width: 0px; height: 0px; border: none; z-index: -1000; left: -1000px; top: -1000px;"></iframe><style type="text/css">@keyframes cmp_pulse{0%{transform:scale(.9);box-shadow:0 0 0 0 rgba(255,211,65,.7)}70%{transform:scale(1);box-shadow:0 0 0 10px transparent}to{transform:scale(.9);box-shadow:0 0 0 0 transparent}}@keyframes cmp_pulse2{0%{transform:scale(.9);box-shadow:0 0 0 0 rgba(255,39,39,.8)}70%{transform:scale(1);box-shadow:0 0 0 10px transparent}to{transform:scale(.9);box-shadow:0 0 0 0 transparent}}.cmpstyleroot,.cmpstyleroot *{--x6pt:6pt;--x7pt:7pt;--x8pt:8pt;--x9pt:9pt;--x10pt:10pt;--x11pt:11pt;--x12pt:12pt;--clrBackground:#FFFFFF;--clrHeadline:#3B3B3B;--clrText:#5F5F5F;--clrTextSecondary:#CFCFCF;--clrButton:#3276AE;--clrButtonText:#FFFFFF;--clrLink:#666666;--clrHighlight:#FFFDCD}body div#cmpwrapper.cmpwrapper:empty,div#cmpwrapper.cmpwrapper,div#cmpwrapper.cmpwrapper:empty,div.cmpwrapper,div.cmpwrapper:empty{display:block!important}.cmpstyleroot.cmpboxwcag,.cmpstyleroot.cmpboxwcag *{--x6pt:0.5000rem;--x7pt:0.5834rem;--x8pt:0.6666rem;--x9pt:0.7500rem;--x10pt:0.8333rem;--x11pt:0.9166rem;--x12pt:1.0000rem}.cmpbox{position:fixed;font-family:Arial,sans-serif;background-color:var(--clrBackground);-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.75);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.75);box-shadow:0 0 5px 0 rgba(0,0,0,.75);box-sizing:border-box;transition-property:background-color,height,width,max-height,max-width,display,position,left,top,bottom,right,transform;transition-duration:.9s;transition-timing-function:ease;z-index:9999999;max-height:100vh;max-width:100vw;text-underline-position:under}.cmpbox.cmpnotransition{transition:none}.cmpbox IMG,.cmpbox SVG,.cmpbox img,.cmpbox svg,.cmpboxrecall IMG,.cmpboxrecall SVG,.cmpboxrecall img,.cmpboxrecall svg{display:inline-block!important}.cmpboxinner,.cmpboxinner2{height:100%;max-width:1400px;margin-left:auto;margin-right:auto}.cmpfullscreen .cmpboxinner{display:flex;flex-direction:column}.cmpbox0{bottom:0;right:0;width:600px}.cmpbox1{bottom:0;left:0;width:100%}.cmpbox2{bottom:0;-webkit-transform:translate(-50%,0);-moz-transform:translate(-50%,0);-ms-transform:translate(-50%,0);-o-transform:translate(-50%,0);transform:translate(-50%,0)}.cmpbox2,.cmpbox3,.cmpbox4{left:50%;width:600px}.cmpbox3{position:fixed;top:50%;-webkit-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.cmpbox4{top:0;-webkit-transform:translate(-50%,0);-moz-transform:translate(-50%,0);-ms-transform:translate(-50%,0);-o-transform:translate(-50%,0);transform:translate(-50%,0)}.cmpbox5,.cmpbox8.cmpfullscreen{top:0;left:0;width:100%}.cmpbox6,.cmpbox7{top:0;height:100%;max-width:300px}.cmpbox6{right:0}.cmpbox7{left:0}.cmpbox8{width:100%;position:relative!important;margin-left:auto;margin-right:auto}.cmpbox9{bottom:0;left:0;width:600px}.cmpbox10{top:0;left:0;width:600px}.cmpbox11{top:0;right:0;width:600px}.cmpbox8.cmpfullscreen{position:absolute!important}.cmpboxBG{position:fixed;left:0;top:0;width:100%;height:100%;background-color:#cfcfcf;opacity:.5;filter:alpha(opacity=50);z-index:8999999}.cmpbox *,.cmpbox>*{font-family:Arial,sans-serif;text-decoration:none;box-sizing:border-box;border:0 solid #fff;vertical-align:middle;transition-property:background-color,height,width,max-height,max-width,display,position;transition-duration:.9s;transition-timing-function:ease}.cmpboxh2,.cmpboxhl{font-size:var(--x12pt);color:var(--clrHeadline)}.cmpboxhl{vertical-align:baseline}.cmpboxh2{font-weight:400;opacity:.8;margin-bottom:.5em;margin-top:2em}.cmpboxh2,.cmpboxhl *,.cmpcookiesdescrboxcontent *{vertical-align:baseline}.cmpcornerbtn .cmpboxhl{max-width:calc(100% - 200px)}.cmpboxbtns{text-align:center;min-height:50px;flex-shrink:0}.cmpboxtxtdiv{z-index:33333;position:relative}.cmpboxtxt,.cmpcookieinfocontent p,.cmpcookiesdescrboxcontent p,.cmpprpsdescr{font-size:var(--x11pt);line-height:1.3em;color:var(--clrText);text-align:justify}.cmpboxbtn,.cmpboxbtn *,.cmpboxtxt,.cmpboxtxt *,.cmpmore *,.cmpprpsdescr,.cmpprpsdescr *{vertical-align:baseline}.cmpprpsdescr{margin-bottom:10px}.cmpprpshl{margin-top:15px;margin-bottom:5px}.cmpcompanyaddr,.cmpdpoinfo{margin-top:10px}.cmpboxbtn{font-size:var(--x11pt);margin:10px;-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.5);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.5);box-shadow:0 0 5px 0 rgba(0,0,0,.5);width:200px;max-width:100%;display:inline-block;text-align:center;position:relative;height:auto;padding:7px 0 7px 10px;border-radius:3px;line-height:normal}.cmpboxbtnyescustom2disabled,.cmpboxbtnyescustomdisabled{cursor:not-allowed!important;opacity:.5}.cmpboxbtn.cmpboxbtnsave{padding-left:0}.cmpbox1 .cmpboxcontent{display:inline-block;max-width:70%;padding-bottom:0}.cmpbox1 .cmpboxbtns{display:inline-block;min-width:30%;margin-top:40px;max-width:30%}.cmpbox5 .cmpboxcontent,.cmpbox8 .cmpboxcontent{display:inline-block;max-width:70%;padding-bottom:0}.cmpbox5 .cmpboxbtns,.cmpbox8 .cmpboxbtns{display:inline-block;min-width:30%;margin-top:40px;max-width:30%}.cmpfullscreen.cmpbox1 .cmpboxbtns,.cmpfullscreen.cmpbox5 .cmpboxbtns,.cmpfullscreen.cmpbox8 .cmpboxbtns{display:block;margin-top:10px;max-width:100%;width:100%}@media (max-width:1500px){.cmpbox1 .cmpboxcontent{max-width:calc(100% - 450px)}.cmpbox1 .cmpboxbtns{min-width:450px}.cmpbox5 .cmpboxcontent,.cmpbox8 .cmpboxcontent{max-width:calc(100% - 450px)}.cmpbox5 .cmpboxbtns,.cmpbox8 .cmpboxbtns{min-width:450px}}@media (max-width:1200px){.cmpbox1 .cmpboxcontent{max-width:calc(100% - 250px)}.cmpbox1 .cmpboxbtns{width:250px;min-width:250px}.cmpbox5 .cmpboxcontent,.cmpbox8 .cmpboxcontent{max-width:calc(100% - 250px)}.cmpbox5 .cmpboxbtns,.cmpbox8 .cmpboxbtns{width:250px;min-width:250px}.cmpfullscreen.cmpbox1 .cmpboxbtns,.cmpfullscreen.cmpbox5 .cmpboxbtns,.cmpfullscreen.cmpbox8 .cmpboxbtns{display:block;margin-top:10px;max-width:100%;width:100%}.cmpfullscreen .cmpboxbtn{display:inline-block;margin-bottom:10px}}@media (max-width:800px){.cmpbox1 .cmpboxcontent{max-width:100%;width:100%;display:block}.cmpbox1 .cmpboxbtns{margin-top:0}.cmpbox1 .cmpboxbtns,.cmpbox5 .cmpboxcontent,.cmpbox8 .cmpboxcontent{max-width:100%;width:100%;display:block}.cmpbox5 .cmpboxbtns,.cmpbox8 .cmpboxbtns{width:100%;display:block;max-width:100%;margin-top:0}.cmpfullscreen.cmpbox1 .cmpboxbtns,.cmpfullscreen.cmpbox5 .cmpboxbtns,.cmpfullscreen.cmpbox8 .cmpboxbtns{margin-top:10px}.cmpboxbtn{display:inline-block;margin:10px}}@media (max-width:600px){.cmpbox0,.cmpbox2,.cmpbox3,.cmpbox4{width:100%}}@media (max-width:400px){.cmpbox6,.cmpbox7{width:100%}}.cmpboxbtnno,A.cmpboxbtnno,A.cmpboxbtnno:link{background-color:var(--clrButton);color:var(--clrButtonText)}.cmpboxbtncustom,.cmpboxbtnsettings,A.cmpboxbtncustom,A.cmpboxbtncustom:link,A.cmpboxbtnsettings,A.cmpboxbtnsettings:link{background-color:var(--clrButton);color:var(--clrButtonText);padding-left:0}.cmpboxbtnaccept,.cmpboxbtnreject,.cmpboxbtnsave,.cmpboxbtnyes,A.cmpboxbtnaccept,A.cmpboxbtnaccept:link,A.cmpboxbtnreject,A.cmpboxbtnreject:link,A.cmpboxbtnsave,A.cmpboxbtnsave:link,A.cmpboxbtnyes,A.cmpboxbtnyes:link{background-color:var(--clrButton);color:var(--clrButtonText)}.cmpboxbtn,.cmpmorelink{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none;-moz-user-drag:none;-o-user-drag:none;user-drag:none}.cmpboxbtn SVG,.cmpboxbtn span,.cmpboxbtn svg{vertical-align:middle}.cmplogo{position:absolute}.cmplogo2,.cmplogo2 span{color:#666;line-height:2px}.cmplogo2{position:absolute;padding:2px;right:2px;bottom:0}.cmplogo2 span{text-decoration:none;margin-left:5px}.cmplogo2 A,.cmplogo2 A:link{display:inline-block;font-size:var(--x7pt);color:#575d80;text-decoration:none;line-height:2px}.cmplogo2,.cmplogo2 span,.cmplogo2.cmplogoXL,.cmplogo2.cmplogoXL A,.cmplogo2.cmplogoXL A:link,.cmplogo2.cmplogoXL span{font-size:var(--x7pt)}.cmplogo2.cmplogoXXL{background:rgba(0,0,0,.1);border-radius:15px;padding-left:10px;padding-right:10px;margin-bottom:2px;opacity:.4}.cmplogo2.cmplogoXXL:focus,.cmplogo2.cmplogoXXL:hover{opacity:1}.cmplogo2.cmplogoXXL,.cmplogo2.cmplogoXXL A,.cmplogo2.cmplogoXXL A:link,.cmplogo2.cmplogoXXL span{font-size:var(--x9pt)}.cmpdl2{width:16px;height:16px;border:0 solid #fff;padding:0;margin:0 2px 0 0}.cmplogo2h,.cmplogo2hx{vertical-align:middle}.cmplogo2h{display:none}.cmplogo2:focus .cmplogo2h,.cmplogo2:hover .cmplogo2h,A.cmpboxrecalllink:focus .cmpboxrecalltxt,A.cmpboxrecalllink:hover .cmpboxrecalltxt{display:inline}.cmplogo2 .cmplogo2h.cmplogo2hvis{display:inline!important}.cmplanguage{display:block;border-radius:5px;position:absolute;padding:6px 3px;text-align:left;left:3px;bottom:3px;font-size:var(--x7pt);line-height:2px;color:#666;transition:.4s all ease;border:1px solid transparent;cursor:pointer}.cmplanguage:focus,.cmplanguage:hover{background-color:#fffdcd;border:1px solid #ffd341;-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.25);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.25);box-shadow:0 0 5px 0 rgba(0,0,0,.25)}.cmplangicon{width:16px;height:auto;-webkit-filter:grayscale(60%);filter:grayscale(60%)}.cmplangiconiso{height:1em;line-height:1.25em;font-size:8pt;width:1.5em;display:inline-block;vertical-align:middle;text-align:center}.cmplanguageloc{line-height:1em;font-size:var(--x6pt);position:absolute;right:0;bottom:0;color:#000;border-radius:30px;background-color:rgba(255,255,255,.8);padding:2px;white-space:nowrap}.cmplangicon:focus,.cmplangicon:hover,.cmplanguage:focus .cmplangicon,.cmplanguage:hover .cmplangicon{-webkit-filter:grayscale(0%);filter:grayscale(0%)}.cmpaltlang,.cmpaltlangs{border-radius:5px;z-index:33334}.cmpaltlangs{position:absolute;bottom:-1px;left:-1px;background-color:#fffdcd;border:1px solid #ffd341;width:144px;-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.25);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.25);box-shadow:0 0 5px 0 rgba(0,0,0,.25)}.cmpaltlang{display:inline-block;padding:6px 3px;font-size:var(--x7pt);line-height:2px;color:#666;border:1px solid #f7e939;background-color:#ffffe3;margin:2px;cursor:pointer;position:relative}.cmpaltlang:focus,.cmpaltlang:hover{background-color:#fff;-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.25);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.25);box-shadow:0 0 5px 0 rgba(0,0,0,.25)}.cmpaltlangcurrent{display:block;cursor:pointer}.cmpaltlangcurrent>div{display:inline-block;position:relative;padding:6px 3px}.cmpmore{text-align:center;font-size:var(--x9pt);color:var(--clrLink);line-height:1em}.cmpmorelink,A.cmpmorelink,A.cmpmorelink:link{padding:10px;display:inline-block}.cmpimg{width:15px;height:15px;position:absolute;left:10px;top:0;border:0;margin-top:.6em}.cmpdl{max-height:50px;max-width:200px;border:0}.cmptblbox{height:calc(100% - 60px);overflow-y:auto;padding-right:5px;max-width:800px;min-height:100px;margin-right:auto;margin-left:auto;width:100%}.cmpbox:dir(rtl) .cmptblbox,.cmpbox[dir=rtl] .cmptblbox{padding-right:0;padding-left:5px}.cmpboxheadline{max-width:800px;margin-right:auto;margin-left:auto;width:100%;flex-shrink:0;vertical-align:baseline}.cmpboxnavi{width:200px;float:left}.cmpboxnaviitem{border:1px solid silver;border-radius:5px;padding:10px;margin-bottom:5px;cursor:pointer}.cmpbox[dir=rtl] .cmpboxnaviitem{padding-right:30px}.cmpboxnaviitem *{vertical-align:middle}.cmpboxnaviitem img{margin-right:5px}.cmpboxnaviitem .cmptogglelink{display:inline-block;text-align:center}.cmpbox:dir(rtl) .cmptblbox,.cmpbox[dir=rtl] .cmptblbox{margin-right:0;margin-left:5px}.cmpboxnaviitemactive{background-color:var(--clrHighlight)}.cmpboxdetails{float:left;width:calc(100% - 200px);padding-left:15px}.cmpcookienonavi .cmpboxdetails{float:none;width:100%;padding-left:0}@media (max-width:570px){.cmpboxnavi{width:100%;float:none}.cmpboxnaviitem{border:1px solid silver;border-radius:5px;padding:5px;margin-bottom:3px;font-size:var(--x10pt)}.cmpboxnaviitemactive{background-color:var(--clrHighlight)}.cmpboxdetails{float:none;width:100%;padding-left:0}}.cmptbl{border:0 solid #fff;width:100%}.cmptbl TH{font-size:var(--x10pt);font-weight:700;border-bottom:2px solid var(--clrTextSecondary);color:var(--clrText)}.cmpclose{position:absolute;right:2px;top:2px}.cmptbl Td{font-size:var(--x9pt);text-align:center;color:var(--clrText)}.cmpcookietbl Td,td.cmptdborder{border-bottom:1px solid silver}.cmpcookietbl Td{font-size:var(--x9pt);text-align:left;color:var(--clrText)}td.cmpvendname{text-align:right}.cmpimgsaveno,.cmpimgyesno,.cmpimgyesno svg,.cmptogglespan svg,.cmpwelcomeprpsbtn .cmpimgsaveno,.cmpwelcomeprpsbtn .cmpimgyesno{border:0 solid #fff;width:40px;height:20px;color:var(--clrTextSecondary)}.cmpboxwelcomeprps{text-align:left;display:flex;flex-wrap:wrap}.cmpwelcomeprpsbox{display:flex;flex-direction:column;position:relative;width:100%;cursor:pointer}.cmpwelcomeprpsboxinner{padding-right:28px}.cmpwelcomeprpsbox:after,.cmpwelcomeprpsbox:before{content:"";position:absolute;top:calc(1em - 4px);width:6px;border:1px solid var(--clrTextSecondary)}.cmpbox table caption,.cmpwelcomeprpsboxnoarrow:after,.cmpwelcomeprpsboxnoarrow:before,div.cmpexpandcontent{display:none}.cmpwelcomeprpsbox:hover::after,.cmpwelcomeprpsbox:hover::before,.cmpwelcomeprpsboxactive:hover::after,.cmpwelcomeprpsboxactive:hover::before{border:1px solid var(--clrText)}.cmpwelcomeprpsbox:before{transform:rotateZ(45deg);-webkit-transform:rotateZ(-45deg);right:10px}.cmpwelcomeprpsbox:after{transform:rotateZ(-45deg);-webkit-transform:rotateZ(45deg);right:15px}.cmpwelcomeprpsdescr,.cmpwelcomeprpsvendors{transition:all .5s ease;visibility:visible;opacity:1;height:auto;overflow:visible;width:100%}.cmpwelcomeprpsdescrinactive,.cmpwelcomeprpsvendorsinactive{visibility:hidden;opacity:0;height:0;overflow:hidden;margin:0!important;padding:0!important}.cmpwelcomeprpsboxactive:after,.cmpwelcomeprpsboxactive:before{content:"";position:absolute;top:calc(1em - 4px);width:6px;border:1px solid var(--clrTextSecondary)}.cmpwelcomeprpsboxactive:before{transform:rotateZ(45deg);-webkit-transform:rotateZ(45deg);right:11px}.cmpwelcomeprpsboxactive:after{transform:rotateZ(-45deg);-webkit-transform:rotateZ(-45deg);right:15px}.cmpwelcomeprps{column-span:none;display:inline-flex;margin-bottom:5px;width:240px;text-align:left;margin-right:15px;align-items:center}.cmpwelcomeprpsbox .cmpwelcomeprps{width:100%}.cmpbox:dir(rtl) .cmpwelcomeprps,.cmpbox[dir=rtl] .cmpwelcomeprps{margin-right:0;margin-left:15px}.cmpwelcomeprpsbtn{display:inline;margin-right:5px;flex-shrink:0}.cmpbox:dir(rtl) .cmpwelcomeprpsbtn,.cmpbox[dir=rtl] .cmpwelcomeprpsbtn{margin-right:0;margin-left:5px}.cmpwelcomeprpstxt{display:inline;padding-top:2px;cursor:pointer;vertical-align:baseline}.cmpcarouselexpanded .cmpboxnavi.cmpcarouselexpandnavi .cmpboxnaviitem,.cmpwelcomeprpstxt.cmpwelcomeprpstxtnopointer{cursor:auto}.cmpbox.cmpfullscreen{width:100%;height:100%;transform:none!important;left:0;top:0;max-width:unset;max-height:unset}TD.cmpallprps,TD.cmpallvend,TH.cmpallprps,TH.cmpallvend{background-color:var(--clrHighlight)}TD.cmpcenter,TH.cmpcenter{text-align:center}TD.cmpsmallborder,TH.cmpsmallborder{border-bottom:1px solid var(--clrTextSecondary)}.cmpboxtxt svg,.cmppurposeicon svg{width:16px;height:16px}.cmpcolorcodingtxt{font-size:var(--x10pt);color:#333;padding:5px;line-height:1.2em}.cmpvendorpurposes svg{fill:#333;width:14px;height:14px}.cmpcolorcodingtxtconsent{color:#333;font-weight:700}.cmpvendorlegintpurposes svg{fill:#b4b4b4;width:14px;height:14px}.cmpcolorcodingtxtlegint{color:#b4b4b4;font-weight:700}.cmpvendorfeatures svg{fill:#5781ad;width:14px;height:14px}.cmpcolorcodingtxtfeatures{color:#5781ad;font-weight:700}.cmpboxrecall,.cmpboxrecall *{line-height:1.5em;vertical-align:middle}.cmpboxrecall{position:fixed;bottom:10px;left:10px;border-radius:30px;padding:3px;z-index:7999999}.cmpboxrecall *{font-size:var(--x9pt)}.cmpboxrecalltxt{display:none;font-family:Arial,sans-serif;padding-right:10px}.cmpbox:dir(rtl) .cmpboxrecalltxt,.cmpbox[dir=rtl] .cmpboxrecalltxt{padding-right:0;padding-left:10px}A.cmpboxrecalllink,A.cmpboxrecalllink:active,A.cmpboxrecalllink:focus,A.cmpboxrecalllink:hover,A.cmpboxrecalllink:link,A.cmpboxrecalllink:visited{display:block;height:20px;color:#0b9ac5;text-decoration:none}.cmpboxrecall{background-color:#f7fcff;-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.25);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.25);box-shadow:0 0 5px 0 rgba(0,0,0,.25)}@media print{.cmpboxrecall{display:none!important}}.cmprecallwarning,.cmprecallwarning2{box-shadow:0 0 0 0 rgba(255,39,39,.8);transform:scale(1);padding:20px}.cmprecallwarning{background-color:rgba(255,237,176,.86)!important;animation:cmp_pulse 2s infinite;border-radius:100px}.cmprecallwarning A.cmpboxrecalllink{height:100%}.cmprecallwarning:hover{background-color:#ffedb0!important}.cmprecallwarning2{background-color:#fff!important;animation:cmp_pulse2 1s infinite;margin-bottom:100px}.cmprecallwarning2:hover{background-color:#f4e1a8!important}.cmprecallwarning2 .cmpboxrecalllink{display:inline-block!important;width:30px!important;height:30px!important}.cmprecallwarningA{background-color:#fff3f3!important;padding:30px;animation:cmp_pulse2 1s infinite}.cmprecallwarningB{background-color:#ff9898!important;padding:30px;animation:cmp_pulse2 3s infinite}.cmptdchoice{width:100px}.cmponofftext{display:block;font-size:var(--x8pt);color:var(--clrText)}.cmppurposedescription{position:absolute;left:calc(50% - 400px);top:25%;background-color:var(--clrBackground);margin-left:auto;margin-right:auto;padding:20px;box-shadow:0 0 15px 0 rgba(0,0,0,.25);width:800px;max-width:75%;max-height:75%;overflow-y:auto}@media (max-width:820px){.cmppurposedescription{left:12%;top:12%}}.cmppurposedescrboxhl,.cmppurposedescrtext{font-size:var(--x11pt);color:var(--clrHeadline)}.cmppurposedescrtext{line-height:1.2em;color:var(--clrText);text-align:justify}.cmpageverifybox{max-width:300px;margin-left:auto;margin-right:auto}.cmpageverifybox SELECT.cmpageverify{display:inline-block;padding:3px;line-height:2em;font-size:var(--x11pt);border:0 solid #fff;margin:0 0 5px}.cmpageverifybox SELECT.cmpageverifyday,.cmpageverifybox SELECT.cmpageverifymonth{margin-left:10px}.cmpageverifytype1 SELECT.cmpageverify,.cmpageverifytype4 SELECT.cmpageverify{display:inline-block;width:100%}.cmpageverifytype2 SELECT.cmpageverify{display:inline-block;width:calc(50% - 10px)}.cmpageverifytype3 SELECT.cmpageverify{display:inline-block;width:calc(33% - 20px)}.cmpageverifybox INPUT.cmpagewrong,.cmpageverifybox SELECT.cmpagewrong{background-color:#f6592c;color:#fff}.cmpageverifyagetxt,.cmpageverifydaytxt,.cmpageverifymonthtxt,.cmpageverifyyeartxt{font-size:smaller}INPUT.cmpageverifyage,INPUT.cmpageverifyday,INPUT.cmpageverifymonth,INPUT.cmpageverifyyear{border:1px solid var(--clrTextSecondary);padding-left:.5rem;padding-right:.5rem;text-align:center;margin-left:2px;margin-right:2px;border-radius:2px}INPUT.cmpageverifyyear{width:5rem}INPUT.cmpageverifyage,INPUT.cmpageverifyday,INPUT.cmpageverifymonth{width:3rem}.cmpcookieinfobox,.cmpcookiesdescrbox{height:100%}.cmpcookieinfobox .cmpboxdetails,.cmpcookiesdescrbox .cmpboxdetails{display:flex;flex-direction:column;height:100%}@media (max-height:926px) and (max-width:480px) and (orientation:portrait){.cmpcookieinfobox,.cmpcookiesdescrbox{display:flex;flex-direction:column}.cmpcookieinfobox .cmpboxdetails,.cmpcookiesdescrbox .cmpboxdetails{display:contents}}.cmpcookieinfocontent h4,.cmpcookiesdescrboxcontent h4,.cmpcookiesdescrboxh2,.cmpcookiesdescrboxhl{font-size:var(--x11pt);color:var(--clrHeadline)}.cmpcookiesdescrtable{flex-grow:10;overflow-y:auto}.cmpcookieinfobox .cmpcookiesdescrboxcontent,.cmpcookiesdescrbox .cmpcookiesdescrboxcontent{flex-grow:1;flex-shrink:1;overflow:auto}.cmpcookieinfobox .cmpboxbtnsmore,.cmpcookiesdescrbox .cmpboxbtnsmore{flex-grow:0;flex-shrink:0}@media (max-width:321px),(max-height:321px){.cmpbox{font-size-adjust:.38!important;line-height:1.05em!important;padding:5px!important}}@media (max-height:450px) and (max-width:450px){.cmpbox{max-height:100%!important;max-width:100%!important;height:100%!important;width:100%!important}.cmpboxinner{flex-direction:column!important}.cmpboxbtns{min-height:auto!important}.cmpboxbtn,.cmpboxbtns{max-width:100%!important}}@media (max-height:600px) and (min-width:926px){.cmpbox3{height:100%}.cmpbox3 .cmpboxinner{display:flex;flex-direction:column}.cmpbox3 .cmpboxinner .cmpboxcontent{overflow:auto}}@media (max-width:414px) and (max-height:736px),(max-width:736px) and (max-height:414px){.cmpbox{padding:10px!important}}.cmpbox6 .cmpboxinner,.cmpbox7 .cmpboxinner{display:flex;flex-direction:column}.cmpbox6 .cmpboxcontent,.cmpbox7 .cmpboxcontent{flex-grow:1;overflow:auto}@media (max-height:926px) and (max-width:480px) and (orientation:portrait){.cmpbox{width:100%;max-height:60%;min-height:300px;height:300px;overflow:auto!important;-webkit-overflow-scrolling:auto!important;padding:15px!important}.cmpboxinner{display:flex;flex-direction:column}.cmpboxcontent{flex-grow:1;overflow:auto;-webkit-overflow-scrolling:auto}.cmpboxbtns{flex-grow:1}.cmpbox.cmpfullscreen{max-height:100%!important;height:100%!important}.cmpboxbtn{margin:5px}A.cmpmorelink:link{padding:3px}.cmpwelcomeprps{width:100%}}@media (max-width:926px) and (max-height:480px) and (orientation:landscape){.cmpbox{width:100%;max-height:90%;min-height:150px;height:350px;overflow:auto!important;-webkit-overflow-scrolling:auto!important;padding:15px!important}.cmpboxinner{display:flex;flex-direction:row}.cmpboxcontent{flex-grow:1;overflow:auto;-webkit-overflow-scrolling:auto}.cmpboxbtns{flex-grow:1;flex-shrink:1;min-height:50px;max-width:250px!important;width:100%}.cmpfullscreen .cmpboxbtns{flex-shrink:0;max-width:100%!important;width:100%}.cmpboxbtn{margin:5px}.cmpbox.cmpfullscreen{max-height:100%!important;height:100%!important}A.cmpmorelink:link{padding:3px}.cmpcornerbtn .cmpboxbtns{padding-top:50px}}@media (max-width:650px) and (min-width:570px){.cmpboxCustomMenu1 .cmpcookieinfotable-wrapper{display:block}.cmpboxCustomMenu1 .cmpcookieinfotable-header{margin-bottom:10px;display:block;grid-template-columns:none}.cmpboxCustomMenu1 .cmpcookieinfotable-body{display:block;grid-template-columns:none}.cmpboxCustomMenu1 .cmpcookieinfotable-cell,.cmpboxCustomMenu1 .cmpcookieinfotable-cellHeader{display:block;width:100%;box-sizing:border-box}.cmpboxCustomMenu1 .cmpcookieinfotable-row{display:flex;flex-direction:column;margin-bottom:10px;padding:10px}}@media (max-width:520px){.cmpcookieinfotable-wrapper{display:block}.cmpcookieinfotable-header{margin-bottom:10px}.cmpcookieinfotable-body,.cmpcookieinfotable-header{display:block;grid-template-columns:none}.cmpcookieinfotable-cell,.cmpcookieinfotable-cellHeader{display:block;width:100%;box-sizing:border-box}.cmpcookieinfotable-row{display:flex;flex-direction:column;margin-bottom:10px;padding:10px}}.cmpcookieinfotable{width:100%}.cmpcookieinfotable td,.cmpcookieinfotable th{text-align:left}.cmpcookieinfotable_descr{font-size:smaller;padding-bottom:10px}.cmppurposebox2,.cmpvendorbox2{text-align:left!important;position:relative;padding-right:20px}.cmpbox:dir(rtl) .cmppurposebox2,.cmpbox:dir(rtl) .cmpvendorbox2,.cmpbox[dir=rtl] .cmppurposebox2,.cmpbox[dir=rtl] .cmpvendorbox2{padding-right:0;padding-left:20px}.cmpvendorinfohl{font-weight:700;margin-top:15px}.cmpdatacategory{background-color:rgba(0,0,0,.2);padding:3px;border-radius:5px;margin-right:5px;line-height:2em}.cmplazypreviewiframe{position:relative;overflow:hidden;box-sizing:border-box;font-family:Arial,sans-serif;background-repeat:no-repeat;background-position:center;background-size:cover}.cmplazypreviewiframe *,.cmplazypreviewiframe>*{font-family:Arial,sans-serif;text-decoration:none;box-sizing:border-box;border:0 solid #fff;vertical-align:middle}.cmplazypreviewmsg{margin:0;position:absolute;top:50%;-ms-transform:translateY(-50%);transform:translateY(-50%);background-color:rgba(255,255,255,.95);width:100%;padding:20px}.cmplazypreviewmsg *{font-size:var(--x11pt);color:#242424}.cmplazypreviewmsginner{max-width:90%;width:640px;margin-left:auto;margin-right:auto}.cmplazyhl{font-weight:700}.cmplazybtn,.cmplazycb{text-align:center}.cmplazycb{font-size:var(--x10pt)}.cmphelpicon,.cmpsubvendoricon{width:16px;height:16px;max-width:16px;max-height:16px;margin-right:2px;margin-left:4px}.cmpsubvendoricon{width:14px;height:14px;max-width:14px;max-height:14px}.cmpbox:dir(rtl) .cmphelpicon,.cmpbox[dir=rtl] .cmphelpicon{margin-right:4px;margin-left:2px}.cmphelpicon path,.cmpsubvendoricon path{fill:#666}.cmpvendoricon{width:16px;height:16px;max-width:16px;max-height:16px;padding:0;margin:0 2px 0 4px}.cmpvendboxclose,A.cmpvendboxclose,A.cmpvendboxclose:link{position:absolute;right:5px;top:5px}.cmpvendboxclose svg{width:16px;height:16px;fill:#666}.cmplisticon{width:14px;height:14px;margin-top:3px;margin-right:5px;flex-shrink:0}.cmpbox:dir(rtl) .cmplisticon,.cmpbox[dir=rtl] .cmplisticon{margin-right:0;margin-left:5px}.cmpcarousel{display:flex;flex-direction:column;overflow:hidden}.cmpboxnavi.cmpcarouselexpandnavi,.cmpboxnavi.cmpcarouselnavi{width:100%;float:none}.cmpcarouselcontent{padding:15px}.cmpboxdetailscarousel{float:none;width:100%;padding:0}@media (max-width:926px) and (max-height:480px) and (orientation:landscape){.cmpboxdetailscarousel{display:block;overflow-y:auto}.cmpcarouselexpandnavi,.cmpcarouselnavi{overflow:auto}}.cmpcarouselnavi .cmpboxnaviitem{position:relative}.cmpcarouselnavi .cmpboxnaviitem:after,.cmpcarouselnavi .cmpboxnaviitem:before{content:"";position:absolute;top:calc(50% - 2px);width:6px;border:1px solid var(--clrText)}.cmpcarouselnavi .cmpboxnaviitem:before{transform:rotateZ(45deg);-webkit-transform:rotateZ(-45deg);right:10px}.cmpcarouselnavi .cmpboxnaviitem:after{transform:rotateZ(-45deg);-webkit-transform:rotateZ(45deg);right:15px}.cmpcarouselnavi .cmpboxnaviitemactive:after,.cmpcarouselnavi .cmpboxnaviitemactive:before{content:"";position:absolute;top:calc(50% - 2px);width:6px;border:1px solid var(--clrTextSecondary)}.cmpcarouselnavi .cmpboxnaviitemactive:before{transform:rotateZ(45deg);-webkit-transform:rotateZ(45deg);right:10px}.cmpcarouselnavi .cmpboxnaviitemactive:after{transform:rotateZ(-45deg);-webkit-transform:rotateZ(-45deg);right:15px}@media print{.cmpbox{display:none!important;visibility:hidden!important}}.cmpboxcontentpass .cmpmore{color:#666}.cmpcontentpasslogin{flex:0 0 auto!important}.cmpcontentpassloginlogo{margin-right:.4em!important;margin-left:.75em!important;margin-bottom:-.1em!important;height:.9em!important}.cmpcontentpassboxmiddle,.cmpcontentpassboxmiddle2{display:flex}.cmpcontentpassboxleft{width:50%;margin-right:30px}.cmpcontentpassboxright,.cmpwelectboxright{width:50%;margin-left:30px}.cmpcontentpassboxmiddle.cmpcontentpass.cmpwelect .cmpcontentpassboxleft,.cmpcontentpassboxmiddle.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.cmpcontentpassboxmiddle.cmpcontentpass.cmpwelect .cmpwelectboxright,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxleft,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpwelectboxright{width:calc(33% - 20px)}.cmpcontentpassboxmiddle.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxright{margin-left:0}.cmpcontentpassboxbottom,.contentpassboxstyle2 .cmpcontentpassboxleft+.cmpcontentpassboxright,.contentpassboxstyle2 .cmpcontentpassboxleft+.cmpwelectboxright,.contentpassboxstyle3 .cmpcontentpassboxleft+.cmpcontentpassboxright,.contentpassboxstyle3 .cmpcontentpassboxleft+.cmpwelectboxright{margin-top:60px}.cmpcontentpassboxbottom2{margin-bottom:60px}.contentpassboxstyle2,.contentpassboxstyle3{display:flex;flex-direction:row}.contentpassboxstyle2 .cmpcontentpassboxbottom2,.contentpassboxstyle3 .cmpcontentpassboxbottom2{margin-bottom:0}.contentpassboxstyle2 .cmpcontentpassboxmiddle2{width:calc(50% - 30px);margin-right:30px;display:flex;flex-direction:column}.contentpassboxstyle2 .cmpcontentpassboxbottom,.contentpassboxstyle3 .cmpcontentpassboxmiddle2{width:calc(50% - 30px);margin-left:30px;display:flex;flex-direction:column}.contentpassboxstyle2 .cmpcontentpassboxbottom{margin-top:0}.contentpassboxstyle3 .cmpcontentpassboxbottom2{width:calc(50% - 30px);margin-top:0;margin-right:30px;display:flex;flex-direction:column}.contentpassboxstyle2 .cmpcontentpassboxleft,.contentpassboxstyle2 .cmpcontentpassboxright,.contentpassboxstyle2 .cmpwelectboxright,.contentpassboxstyle3 .cmpcontentpassboxleft,.contentpassboxstyle3 .cmpcontentpassboxright,.contentpassboxstyle3 .cmpwelectboxright{width:100%!important;margin:0}.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxleft,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpwelectboxright,.cmpcontentpassboxmiddle3.cmpcontentpass.cmpwelect .cmpcontentpassboxleft,.cmpcontentpassboxmiddle3.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.cmpcontentpassboxmiddle3.cmpcontentpass.cmpwelect .cmpwelectboxright{margin-top:30px}.contentpassboxstyle1 .cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxleft,.contentpassboxstyle1 .cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpcontentpassboxright,.contentpassboxstyle1 .cmpcontentpassboxmiddle2.cmpcontentpass.cmpwelect .cmpwelectboxright,.contentpassboxstyle2 .cmpcontentpassboxleft,.contentpassboxstyle3 .cmpcontentpassboxleft{margin-top:0!important}.cmpcontentpassloginlogo{width:.9em}.cmpcontentpasssignuplogo,.cmpwelectlogo{width:.9em;height:.9em;margin-right:10px}.cmpwelectiframe{width:100%;height:640px;max-height:80vh;border:0 solid #fff;background-color:transparent}@media (max-height:926px) and (max-width:480px) and (orientation:portrait),(max-height:480px) and (max-width:926px) and (orientation:landscape){.cmpcontentpassbox.contentpassboxstyle2,.cmpcontentpassbox.contentpassboxstyle3{display:block!important}.cmpcontentpassbox.contentpassboxstyle2 .cmpcontentpassboxmiddle,.cmpcontentpassbox.contentpassboxstyle2 .cmpcontentpassboxmiddle2,.cmpcontentpassbox.contentpassboxstyle3 .cmpcontentpassboxmiddle,.cmpcontentpassbox.contentpassboxstyle3 .cmpcontentpassboxmiddle2,.cmpcontentpassboxmiddle,.cmpcontentpassboxmiddle2{display:block!important;margin-right:0!important;margin-left:0!important;width:100%!important}.cmpcontentpassboxleft{width:100%!important;margin-right:0!important;margin-top:30px}.cmpcontentpassboxright{width:100%!important;margin-left:0!important;margin-top:30px}.cmpcontentpassbox .cmpcontentpassboxmiddle .cmpcontentpassboxbottom,.cmpcontentpassbox .cmpcontentpassboxmiddle .cmpcontentpassboxbottom2,.cmpcontentpassbox .cmpcontentpassboxmiddle2 .cmpcontentpassboxbottom,.cmpcontentpassbox .cmpcontentpassboxmiddle2 .cmpcontentpassboxbottom2,.cmpcontentpassboxbottom,.cmpcontentpassboxbottom2{display:block!important;width:100%!important;margin-top:30px!important;margin-left:0!important;margin-right:0!important}.cmpwelectboxright{width:100%!important;margin-left:0!important;margin-top:30px}.cmpboxcontentpass .cmpboxinner{display:flex!important;flex-direction:column!important}}.cmpvendortogglebox{display:flex}.cmpvendortoggleboxd{display:flex;padding-right:20px}.cmppurposetoggleboxd>span,.cmpvendortoggleboxd>span{align-self:center;padding-right:10px}.cmppurposetoggleboxd>a,.cmpvendortoggleboxd>a{align-self:center}.cmppurposetoggleboxd .cmponofftext,.cmpvendortoggleboxd .cmponofftext{display:inline}.cmppurposetogglebox{display:flex}.cmppurposetoggleboxd{display:flex;padding-right:20px}.cmpexplicitconsentbtn{padding:3px 8px;font-size:var(--x9pt);-webkit-box-shadow:0 0 5px 0 rgba(0,0,0,.5);-moz-box-shadow:0 0 5px 0 rgba(0,0,0,.5);box-shadow:0 0 5px 0 rgba(0,0,0,.5);border-radius:3px}span.cmptooltiplink{display:inline-block;position:relative;border-bottom:1px dotted var(--clrText);color:inherit}.cmptooltip{min-width:220px;max-width:400px;position:absolute;background-color:#fff;top:calc(100% + 10px);left:50%;transform:translate(-50%,0);padding:3px;border-radius:3px;z-index:99999999;border:1px solid var(--clrTextSecondary);box-shadow:0 1px 8px rgba(0,0,0,.2);visibility:hidden;opacity:0;transition:opacity .8s}span.cmptooltiplink:active .cmptooltip,span.cmptooltiplink:focus .cmptooltip,span.cmptooltiplink:hover .cmptooltip{visibility:visible;opacity:1}i.cmptooltiparrow{position:absolute;bottom:100%;left:50%;margin-left:-12px;width:24px;height:12px;overflow:hidden}i.cmptooltiparrow::after{content:"";position:absolute;width:12px;height:12px;left:50%;transform:translate(-50%,50%) rotate(45deg);background-color:var(--clrBackground);border:1px solid var(--clrTextSecondary);box-shadow:0 1px 8px rgba(0,0,0,.1)}.cmpboxbtnnocorner{z-index:99999}.cmpboxbtncustomcorner svg,.cmpboxbtnnocorner svg,.cmpboxbtnsavecorner svg,.cmpboxbtnyescorner svg{fill:currentColor}.cmpboxcookieicon{display:block;float:right;width:200px;margin-top:50px}.cmpboxcookieicon svg,.cmpboxcookieiconsilhouette svg.cmpcookieiconsilhouette{width:100%;height:auto}.cmpboxcookieiconsilhouette{position:absolute;right:0;top:0;width:50%;z-index:-3;max-height:100%;overflow:hidden}.cmpboxcookieiconsilhouette .silhouetteFill{fill:var(--clrButton);opacity:.1}@media (max-height:926px) and (max-width:480px) and (orientation:portrait){.cmpboxcookieicon{width:100px}}.cmpsliderbox{transition:all .8s ease;position:relative;z-index:0}.cmpsliderpanel,.cmpsliderpointer{position:absolute;top:.6em;left:0;margin-left:45px;border-radius:30px;width:1px;background-color:var(--clrButton)}.cmpsliderpointer{transition:all .8s ease;padding-left:14px;padding-top:14px;height:1px;z-index:10}.cmpsliderpanel{padding-left:5px;height:100%;opacity:.1;z-index:1}.cmpsliderpanel.cmpsliderpanelActive{height:0;opacity:.8;top:calc(.6em + 4px);z-index:2}.cmpsliderstationouter{position:relative}.cmpsliderstation{position:absolute;top:.7em;left:0;margin-left:45px;border-radius:30px;padding-left:12px;padding-top:12px;width:1px;height:1px;background-color:var(--clrButton);opacity:.5;z-index:3}.cmpslideritemActive .cmpsliderstation{opacity:.8;z-index:4}.cmpslideritem{margin-left:90px;margin-bottom:10px;padding:5px;border-radius:5px;cursor:pointer}.cmpslideritem .cmpsliderhl,.cmpslideritem .cmpslidertxt{opacity:.8}.cmpslideritemActive .cmpsliderhl,.cmpslideritemActive .cmpslidertxt{opacity:1}.cmpslideritem,.cmpslideritemouterActive{position:relative}.cmpslideritem:last-of-type{margin-bottom:0}.cmpsliderhl{color:var(--clrHeadline);font-size:var(--x11pt);font-weight:700}.cmpslidertxt{color:var(--clrText)}.cmpslidercenter{-webkit-transform:translate(-50%,0);-moz-transform:translate(-50%,0);-ms-transform:translate(-50%,0);-o-transform:translate(-50%,0);transform:translate(-50%,0)}.cmplastupdate{display:block;position:absolute;padding:6px 3px;text-align:right;left:32px;bottom:3px;font-size:var(--x7pt);line-height:2px;color:var(--clrText);opacity:.5}.cmplastupdate:hover{opacity:1}.cmpboxtxtdivpurposeicon{display:inline-block}svg.cmpexternallinkicon,svg.cmpicon,svg.cmpicosvgfill,svg.cmppurposeicon,svg.cmptcficon{fill:currentColor;height:1em;width:1em;margin-right:.5em}svg.cmpexternallinkicon,svg.cmptcficon{margin-left:.5em}.cmpbox u{text-decoration:underline!important}.cmpfadein{opacity:0;transition-property:opacity;transition-duration:.9s;transition-timing-function:ease}.cmpflyin{left:-600px!important;right:600px!important}.cmpflyinR{left:calc(100vw + 600px)!important;right:calc(-100vw - 600px)!important}.cmpflyinT{top:-600px!important;bottom:calc(100vh + 1200px)!important}.cmpflyinB{top:calc(100vh + 600px)!important;bottom:calc(-100vh - 1200px)!important}.cmpflyin2,.cmpflyin3{transition-property:left,right;transition-duration:1.9s;transition-timing-function:ease}.cmpflyin3{transition-property:top,bottom}.cmppolicybox{display:flex;flex-direction:column;height:100%}.cmppolicybox .cmppolicycontent{flex-grow:1;flex-shrink:1;overflow:auto}.cmppolicybox .cmpboxbtnsmore{flex-grow:0;flex-shrink:0}.cmpadchoiceslearnmorelink,.cmpadchoicesoolink{display:flex;align-items:center;justify-content:center;width:100%}.cmpadchoicesoolink{color:var(--clrButtonText);background-color:var(--clrButton);font-weight:700;margin:0 0 10px}.cmpadchoiceslearnmorelink{color:var(--clrButton);background-color:var(--clrButtonText);margin:0}.cmpqrcontent,.cmpqrcontentalternative{text-align:center}.cmpqrcontent canvas,.cmpqrcontent img{border:5px solid #fff;border-radius:5px}.cmpqrouter{position:relative}.cmpqrspinner{width:100%;height:140px;align-items:center;justify-content:center;position:absolute;bottom:-70px;right:-120px}.cmpqrspinner .cmploadingspinner{width:60px;height:60px}.cmpqrspinner .cmploadingspinner div{border:6px solid var(--clrHeadline);border-color:var(--clrHeadline) transparent transparent transparent}.cmpboxdsaouter{max-width:800px;margin-left:auto;margin-right:auto}.cmpboxdsaaddetailouter,.cmpboxdsaaddetailoutersingle{border:1px solid silver;border-radius:5px;margin-bottom:50px}.cmpboxdsaaddetailouter{display:flex}.cmpboxdsaaddetail,.cmpboxdsaaddetailimg{padding:30px}.cmpboxdsaaddetailouter .cmpboxdsaaddetail,.cmpboxdsaaddetailouter .cmpboxdsaaddetailimg{width:100%}.cmpboxdsaaddetailimg{align-self:center;text-align:center}.cmpboxdsaaddetailimg img{max-width:100%;max-height:100%;width:100%}.cmpboxdsaaddetailline{margin-bottom:15px}.cmpboxdsaaddetailhl{color:var(--clrHeadline);font-weight:700;font-size:var(--x11pt)}.cmpboxdsaaddetailname{color:var(--clrText);font-size:var(--x8pt);opacity:.8;margin-bottom:.5em}.cmpboxdsaaddetaildescr,.cmpboxdsaaddetaildescritem{color:var(--clrText);font-size:var(--x10pt)}.cmpboxdsaaddetaildescrimg{text-align:center}.cmpboxdsaaddetaildescrimg img{width:100%;max-width:380px;max-height:600px}.cmpboxdsaaddetaildescritem{padding-left:2.5em;margin-left:.5em;padding-bottom:10px;padding-top:5px;background-repeat:no-repeat;background-size:24px;background-position:0 5px}.cmpboxDSA .cmpboxinner{overflow-y:auto}.cmpboxDSA .cmpclose,.cmpclose svg{fill:var(--clrHeadline);width:20px;height:20px;display:block}.cmpboxDSA .cmpboxh2 img{vertical-align:text-bottom;height:1.2em;margin-right:.5em}.cmpboxDSA .cmpboxdsaaddetaildescr .cmpboxbtn.cmpboxbtnyes{margin-left:0}.cmpboxdsaview{height:1.3em;margin-left:.5em}@media (max-height:926px) and (max-width:480px) and (orientation:portrait){.cmpboxdsaaddetailouter{display:block}.cmpboxdsaaddetaildescrimg img{max-width:100%}}@keyframes cmploadingspinner{0%{transform:rotate(0deg)}to{transform:rotate(360deg)}}@keyframes cmploadingspinner21{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes cmploadingspinner23{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes cmploadingspinner22{0%{transform:translate(0,0)}to{transform:translate(24px,0)}}.skippmsg,.skippmsg *{--clrBackground:#FFFFFF;--clrHeadline:#3B3B3B;--clrText:#5F5F5F;--clrTextSecondary:#CFCFCF;--clrButton:#3276AE;--clrButtonText:#FFFFFF;--clrLink:#666666;--clrHighlight:#FFFDCD}.cmpspinnercenter{text-align:center!important}.cmploadingspinner{display:inline-block;position:relative;width:120px;height:120px;border-radius:50%;overflow:hidden}.cmploadingspinner div{box-sizing:border-box;display:block;position:absolute;width:100%;height:100%;border:12px solid var(--clrButton);border-radius:50%;animation:cmploadingspinner 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:var(--clrButton) transparent transparent transparent}.cmploadingspinner div:nth-child(1){animation-delay:-.45s}.cmploadingspinner div:nth-child(2){animation-delay:-.3s}.cmploadingspinner div:nth-child(3){animation-delay:-.15s}.cmploadingspinner2{display:inline-block;position:relative;width:80px;height:80px}.cmploadingspinner2 div{position:absolute;top:33px;width:13px;height:13px;border-radius:50%;background:var(--clrButton);animation-timing-function:cubic-bezier(0,1,1,0)}.cmploadingspinner2 div:nth-child(1){left:8px;animation:cmploadingspinner21 .6s infinite}.cmploadingspinner2 div:nth-child(2),.cmploadingspinner2 div:nth-child(3){left:8px;animation:cmploadingspinner22 .6s infinite}.cmploadingspinner2 div:nth-child(3){left:32px}.cmploadingspinner2 div:nth-child(4){left:56px;animation:cmploadingspinner23 .6s infinite}.cmpcookieinfotable-container{position:relative;width:100%;overflow-x:auto}.cmpcookieinfotable-wrapper{display:grid;width:100%}.cmpcookieinfotable-body,.cmpcookieinfotable-header{display:grid;grid-template-columns:repeat(7,1fr);border-bottom:1px solid var(--clrTextSecondary)}.cmpcookieinfotable-body{background-color:var(--clrBackground)}.cmpcookieinfotable-row{display:contents;margin-bottom:5px}.cmpcookieinfotable-cell,.cmpcookieinfotable-cellHeader{position:relative;padding:10px;border-bottom:1px solid var(--clrTextSecondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;text-align:left}.cmpcookieinfotable-cellHeader{font-weight:700}.cmpcookieinfotable-description{grid-column:1/-1;background-color:#f3f3f3;padding:15px;margin-top:10px;margin-bottom:10px;border-top:2px solid var(--clrTextSecondary);border-bottom:2px solid var(--clrTextSecondary)}
/*CLIENT CUSTOM CSS*/#cmpbox span {
pointer-events: auto;
}
.cmplogo {
display: block!important;
}
.cmpboxrecall {
display: none!important;
}
@media (max-height: 480px) and (max-width: 926px) and (orientation: landscape) {
.cmplogo {
top: auto!important;
bottom: 0;
}
}
.cmplogo IMG {
margin-top: -22px;
}
.cmpbox.cmpfullscreen {
overflow: auto;
max-height: 800px !important;
max-width: 800px !important;
transform: translate(-50%, -50%) !important;
left: 50%;
top: 50%;
}
@media (max-height: 926px) and (max-width: 480px) and (orientation: portrait) {
.cmpboxinner {
padding-top: 35px;
}
}
@media (max-height: 480px) and (max-width: 926px) and (orientation: landscape) {
.cmplogo {
top: 20px!important;
}
.cmpboxinner {
padding-top: 35px;
}
}.cmplogo {right: 20px; top: 20px;}
.cmpbox:dir(rtl) .cmplogo, .cmpbox[dir="rtl"] .cmplogo {left: 20px; top: 20px; right:auto;}@media (max-width: 570px){.cmplogo{ display: none !important;}}
@media (max-height: 926px) and (max-width: 480px) and (orientation: portrait){.cmplogo{display: none !important;}}
@media (max-width: 926px) and (max-height: 480px) and (orientation: landscape){.cmplogo{display: none !important;}} *.cmpboxhl{font-size:12pt;color:#5F5F5F;padding-bottom:10px;font-weight:bold;} *.cmpboxtxt, td.cmpvendname{font-size:11pt;color:#5F5F5F;}.cmpwelcomeprpstxt, .cmpwelcomeprpstxt A:link, .cmpwelcomeprpsbtn, .cmpwelcomeprpsbtn A:link, .cmpwelcomeprpsbtn span{font-size:11pt;color:#5F5F5F;} *.cmpboxtxt{padding-bottom:20px;}.cmpwelcomeprpstxt, .cmpwelcomeprpstxt A:link, .cmpwelcomeprpsbtn, .cmpwelcomeprpsbtn A:link, .cmpwelcomeprpsbtn span{font-size:11pt;color:#5F5F5F;}.cmpboxwelcomeprps{margin-bottom:20px;}.cmpmore{font-size:11pt;} .cmpsavemychoice, .cmpsavemychoice label{font-size:11pt;color:#5F5F5F;} .cmpmorelink, A.cmpmorelink, A.cmpmorelink:link, .cmpmore A, .cmpmore A:link{font-size:11pt;color:#5F5F5F;} .cmpsavemychoice, .cmpsavemychoice label{font-size:11pt;color:#5F5F5F;} *.cmpboxbtnyes, A.cmpboxbtnyes, A.cmpboxbtnyes:link{font-size:11pt;color:#FFFFFF;background-color:#229CCA;} *.cmpboxbtnno, A.cmpboxbtnno, A.cmpboxbtnno:link{font-size:11pt;color:#FFFFFF;background-color:#229CCA;} *.cmpboxbtnsave, A.cmpboxbtnsave, A.cmpboxbtnsave:link{font-size:11pt;color:#FFFFFF;background-color:#229CCA;} *.cmpboxbtncustom, A.cmpboxbtncustom, A.cmpboxbtncustom:link{font-size:11pt;color:#FFFFFF;background-color:#229CCA;} .cmpfullscreen *.cmpboxbtnyes, .cmpfullscreen A.cmpboxbtnyes, .cmpfullscreen A.cmpboxbtnyes:link{font-size:11pt;color:#FFFFFF;background-color:#229CCA;} .cmpfullscreen *.cmpboxbtnaccept, .cmpfullscreen A.cmpboxbtnaccept, .cmpfullscreen A.cmpboxbtnaccept:link{font-size:6px;color:#FFFFFF;background-color:#FFFFFF;} .cmpfullscreen *.cmpboxbtnreject, .cmpfullscreen A.cmpboxbtnreject, .cmpfullscreen A.cmpboxbtnreject:link{font-size:6px;color:#FFFFFF;background-color:#FFFFFF;} *.cmpexplicitconsentbtn, A.cmpexplicitconsentbtn, A.cmpexplicitconsentbtn:link, *.cmpexplicitconsentbtnon, A.cmpexplicitconsentbtnon, A.cmpexplicitconsentbtnon:link{color:#FFFFFF;background-color:#229CCA;} *.cmpexplicitconsentbtnoff, A.cmpexplicitconsentbtnoff, A.cmpexplicitconsentbtnoff:link{color:#FFFFFF;background-color:#229CCA;} .cmpfullscreen .cmpmorelink, .cmpfullscreen A.cmpmorelink, .cmpfullscreen A.cmpmorelink:link{font-size:11pt;color:#5F5F5F;} .cmpboxbtn{border-color:#FFFFFF;}*.cmpboxbtnyes svg{fill:currentColor;width:1em;height:1em;}*.cmpboxbtnno svg{fill:currentColor;width:1em;height:1em;}*.cmpboxbtnaccept svg{fill:currentColor;width:1em;height:1em;vertical-align: middle;}*.cmpboxbtnreject svg{fill:currentColor;width:1em;height:1em;vertical-align: middle;} *.cmpboxbtnyescustomchoices *.cmpimg, *.cmpboxbtnyescustomchoices svg{display:none !important;} *.cmpboxbtnyescustomchoices{padding-left:0px;} *.cmpbox{background-color:#FFFFFF;border-top:solid 12px #229CCA;border-right:solid 0px #FFFFFF;border-bottom:solid 5px #FFFFFF;border-left:solid 0px #FFFFFF;padding-top:40px;padding-right:40px;padding-bottom:40px;padding-left:40px;} *.cmpclose{display:none;} .cmpfullscreen *.cmpboxhl{font-size:12pt;color:#FFFFFF;font-weight:bold;} .cmpfullscreen *.cmpprpshl{font-size:12pt;color:#FFFFFF;font-weight:bold;} .cmpfullscreen *.cmpboxtxt, .cmpfullscreen, .cmpprpsdescr, td.cmpvendname, .cmpfullscreen A.cmpvendurl, .cmpfullscreen A.cmpvendurl:link{font-size:11pt;color:#FFFFFF;} .cmpfullscreen.cmpbox{background-color:#FFFFFF;} .cmpboxnaviitemactive, TD.cmpallvend, TH.cmpallvend, TD.cmpallprps, TH.cmpallprps{background-color:#FFFFFF;}@media (max-height: 926px) and (max-width: 480px) and (orientation: portrait) {.cmpbox{overflow:auto;max-width:100%; min-width:100%; }}@media (max-height: 480px) and (max-width: 926px) and (orientation: landscape) {.cmpbox{overflow:auto;max-height:100%; min-height:100%;}}.cmpbox{border-radius:3px;}.cmptogglespan svg{width:40px; height:20px;}.cmptogglespan svg .cmpsvggreenfill{fill:#5AB14B !important;} .cmptogglespan svg .cmpsvggreenstroke{stroke:#5AB14B !important;}.cmptogglespan svg .cmpsvgredfill{fill:#F64C4E !important;} .cmptogglespan svg .cmpsvgredstroke{stroke:#F64C4E !important;}.cmptogglespan svg .cmpsvgwhitefill{fill:#FFFFFF !important;} .cmptogglespan svg .cmpsvgwhitestroke{stroke:#FFFFFF !important;}.cmptogglespan svg .cmpsvgblackfill{fill:#111111 !important;} .cmptogglespan svg .cmpsvgblackstroke{stroke:#111111 !important;}.cmptogglespan svg .cmpsvggrayfill{fill:#777777 !important;} .cmptogglespan svg .cmpsvggraystroke{stroke:#777777 !important;}.cmptogglespan svg .cmpsvggray2fill{fill:#AAAAAA !important;} .cmptogglespan svg .cmpsvggray2stroke{stroke:#AAAAAA !important;}.cmptogglespan svg .cmpsvgsilverfill{fill:#E5E5E5 !important;} .cmptogglespan svg .cmpsvgsilverstroke{stroke:#E5E5E5 !important;}.cmptogglespan svg .cmpsvgsilver2fill{fill:#DDDDDD !important;} .cmptogglespan svg .cmpsvgsilver2stroke{stroke:#DDDDDD !important;}.cmpboxnaviitem{color: #5F5F5F !important;}.cmpboxnaviitemactive{color: #5F5F5F !important;}.cmpboxtxtcustomcoices{color: #5F5F5F !important;}.cmpprpsdescr{color: #5F5F5F !important;}.cmpprpshl{color: #5F5F5F !important;}.cmpvendname{color: #5F5F5F !important;}</style><iframe name="googlefcInactive" src="about:blank" style="display: none; width: 0px; height: 0px; border: none; z-index: -1000; left: -1000px; top: -1000px;"></iframe><iframe name="googlefcLoaded" src="about:blank" style="display: none; width: 0px; height: 0px; border: none; z-index: -1000; left: -1000px; top: -1000px;"></iframe></body></html>