{"id":835,"date":"2024-12-03T07:56:38","date_gmt":"2024-12-03T06:56:38","guid":{"rendered":"https:\/\/skinarttraining.com\/in\/?p=835"},"modified":"2024-12-04T14:00:32","modified_gmt":"2024-12-04T13:00:32","slug":"merry-christmas","status":"publish","type":"post","link":"https:\/\/skinarttraining.com\/in\/merry-christmas\/","title":{"rendered":"Merry Christmas"},"content":{"rendered":"    <section class=\"cisap\" id=\"cisap_ce07253a-7eb2-40d7-8e4f-7e60e42c2890\" data-base-url=\"https:\/\/skinarttraining.com\/videos\/sitevids\/\" data-folder=\"Skinart-Christmas-Message\" data-file-b64=\"U2tpbmFydC1DaHJpc3RtYXMtTWVzc2FnZS1tdWx0aS5tcDQ\" data-hls-local=\"https:\/\/skinarttraining.com\/wp-content\/mu-plugins\/videos\/hls.min.js\" data-hls-sd=\"https:\/\/skinarttraining.com\/videos\/sitevids\/Skinart-Christmas-Message\/master480.m3u8\" data-hls-hd=\"https:\/\/skinarttraining.com\/videos\/sitevids\/Skinart-Christmas-Message\/master720.m3u8\">\n        <div class=\"cisap__stage\">\n            <img class=\"cisap__thumb\" src=\"https:\/\/skinarttraining.com\/videos\/default.webp\" data-default-thumb=\"https:\/\/skinarttraining.com\/videos\/default.webp\" alt=\"Video preview\" loading=\"eager\" decoding=\"async\">\n            <button type=\"button\" class=\"cisap__play\" data-action=\"play\" aria-label=\"Play video\"><span class=\"cisap__playIcon\" aria-hidden=\"true\"><\/span><\/button>\n            <div class=\"cisap__mount\" data-id=\"mount\">\n                <video data-id=\"video\" controls playsinline preload=\"metadata\" controlsList=\"nodownload\" crossorigin=\"anonymous\" oncontextmenu=\"return false;\"><\/video>\n            <\/div>\n        <\/div>\n        <div class=\"cisap__controls\" aria-label=\"Video controls\">\n            <button type=\"button\" class=\"cisap__quality\" data-action=\"quality\" aria-label=\"Toggle quality\">SD<\/button>\n            <select class=\"cisap__select cisap__audio\" aria-label=\"Audio language\">\n                <option value=\"-1\">Default Audio<\/option>\n            <\/select>\n            <select class=\"cisap__select cisap__subs\" aria-label=\"Subtitle language\">\n                <option value=\"off\">Subtitles Off<\/option>\n            <\/select>\n        <\/div>\n    <\/section>\n        <style id=\"cis-all-player-css\">\n        .cisap{max-width:1200px;margin:24px auto;padding:16px;border-radius:16px;background:#1a2d2d;border:1px solid rgba(148,163,184,.28);box-shadow:0 18px 34px rgba(2,6,23,.28);color:#f8fafc}\n        .cisap__stage{position:relative;border-radius:14px;overflow:hidden;background:#000;aspect-ratio:16\/9}\n        .cisap__thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;z-index:1}\n        .cisap__play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;width:clamp(74px,12vw,100px);height:clamp(46px,7vw,60px);border:1px solid rgba(248,250,252,.5);border-radius:12px;margin:0;padding:0;background:rgba(15,23,42,.92);display:flex;align-items:center;justify-content:center;cursor:pointer}\n        .cisap__playIcon{width:0;height:0;border-top:10px solid transparent;border-bottom:10px solid transparent;border-left:16px solid #f8fafc;position:relative;left:2px}\n        .cisap__mount{position:absolute;inset:0;z-index:2}\n        .cisap__mount video{display:none;width:100%;height:100%;margin:0 auto;background:#000;border-radius:14px}\n        .cisap.is-loaded .cisap__thumb,.cisap.is-loaded .cisap__play{display:none}\n        .cisap.is-loaded .cisap__mount video{display:block}\n        .cisap__controls{margin-top:12px;display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap}\n        .cisap__quality{height:34px;border-radius:999px;border:1px solid rgba(148,163,184,.38);background:rgba(15,23,42,.92);color:#f8fafc;font-size:14px;line-height:1;cursor:pointer;padding:0 12px}\n        .cisap__select{height:34px;border:1px solid rgba(148,163,184,.45);background:rgba(15,23,42,.9);color:#f8fafc;border-radius:8px;padding:0 8px}\n        .cisap .cisap__audio,.cisap .cisap__subs{display:none}\n        .cisap.has-player .cisap__audio,.cisap.has-player .cisap__subs{display:inline-block}\n        .cisap video::cue{color:#fff!important;background:rgba(0,0,0,.82)!important;text-shadow:0 1px 2px rgba(0,0,0,.95)!important;font-size:16px!important}\n        .cisap__banner{margin-bottom:10px;padding:8px 10px;border-radius:10px;border:1px solid rgba(248,113,113,.55);background:rgba(127,29,29,.35);color:#fecaca;font-size:12px;line-height:1.4;display:none}\n        .cisap__banner.is-visible{display:block}\n        @media (max-width:780px){.cisap{margin:14px auto}.cisap__select,.cisap__quality{height:30px;font-size:12px}}\n    <\/style>\n    <script type=\"text\/javascript\" id=\"cis-all-player-js\" data-cfasync=\"false\">\n        (function(){\n            var DEBUG=false;\n            function A(x){return Array.prototype.slice.call(x||[])}\n            function q(root,sel){return root.querySelector(sel)}\n            function getCookie(name){try{var v='; '+document.cookie;var p=v.split('; '+name+'=');if(p.length===2){return p.pop().split(';').shift()}}catch(_e){}return ''}\n            function setCookie(name,value){try{document.cookie=String(name)+'='+encodeURIComponent(String(value||''))+'; path=\/; max-age=31536000; samesite=lax'}catch(_e){}}\n            function ensureHls(src,state){\n                if(window.Hls&&window.Hls.isSupported&&window.Hls.isSupported()){return Promise.resolve(true)}\n                if(state.hlsPromise){return state.hlsPromise}\n                state.hlsPromise=new Promise(function(resolve,reject){\n                    if(!src){resolve(false);return}\n                    var s=document.createElement('script'); \n                    s.src=src;\n                    s.defer=true;\n                    s.onload=function(){resolve(!!(window.Hls&&window.Hls.isSupported&&window.Hls.isSupported()))};\n                    s.onerror=function(){reject(new Error('Failed to load HLS library: '+src))};\n                    document.head.appendChild(s);\n                });\n                return state.hlsPromise;\n            }\n            function bootOne(root){\n                if(root.dataset.cisapBooted==='1'){return}\n                root.dataset.cisapBooted='1';\n                var base=(root.getAttribute('data-base-url')||'').replace(\/\\\/+$\/,'')+'\/';\n                var folder=root.getAttribute('data-folder')||'';\n                var file=root.getAttribute('data-file-b64')||'';\n                var hlsLocal=root.getAttribute('data-hls-local')||'';\n                var hlsSd=root.getAttribute('data-hls-sd')||'';\n                var hlsHd=root.getAttribute('data-hls-hd')||'';\n                var mount=q(root,'[data-id=\"mount\"]');\n                var video=q(root,'[data-id=\"video\"]');\n                var playBtn=q(root,'[data-action=\"play\"]');\n                var qualityBtn=q(root,'[data-action=\"quality\"]');\n                var thumb=q(root,'.cisap__thumb');\n                var audio=q(root,'.cisap__audio');\n                var subs=q(root,'.cisap__subs');\n                var state={hls:null,hlsPromise:null,manifestBlobUrl:'',cachedAudioTracks:[],customSubTrack:null,customSubLang:''};\n                var key='cisap_'+((location.pathname.split('\/').filter(Boolean)[0])||'root')+'_';\n                var qualityKey=key+'quality',subKey=key+'sub_lang',audioKey=key+'audio_track',audioLangKey=key+'audio_lang';\n                var quality=((localStorage.getItem(qualityKey)||getCookie(qualityKey)||'sd')==='hd')?'hd':'sd';\n                var subPref=(getCookie(subKey)||localStorage.getItem(subKey)||'en');\n                var audioPref=parseInt(localStorage.getItem(audioKey)||'-1',10);\n                var audioLangPref=(getCookie(audioLangKey)||localStorage.getItem(audioLangKey)||'en').toLowerCase();\n                var nativeHls=!!video.canPlayType('application\/vnd.apple.mpegurl');\n                var banner=null;\n                if(!base||!file||!mount||!video||!audio||!subs||!qualityBtn){return}\n                if(\/^\\d+$\/.test(subPref)){subPref='off'}\n                qualityBtn.textContent=quality.toUpperCase();\n                if(thumb){\n                    thumb.addEventListener('error',function(){\n                        var fallback=thumb.getAttribute('data-default-thumb')||'';\n                        if(fallback&&thumb.getAttribute('src')!==fallback){thumb.setAttribute('src',fallback)}\n                    });\n                }\n\n                function showError(msg){\n                    if(!DEBUG){return}\n                    if(!banner){banner=document.createElement('div');banner.className='cisap__banner';root.insertBefore(banner,root.firstChild)}\n                    banner.textContent=String(msg||'Player error');\n                    banner.classList.add('is-visible');\n                }\n                function clearError(){if(banner){banner.remove();banner=null}}\n                function folderBase(){return base+encodeURIComponent(folder).replace(\/%2F\/g,'\/')+'\/'}\n                function paths(){\n                    var b=folder?folderBase():base;\n                    return {mp4sd:b+'lowRes\/video.php?vid='+file,mp4hd:b+'highRes\/video.php?vid='+file,hlsSd:hlsSd,hlsHd:hlsHd,base:b};\n                }\n                function clearTracks(){A(video.querySelectorAll('track')).forEach(function(t){t.remove()})}\n                function subtitleTrackEls(){return A(video.querySelectorAll('track[kind=\"subtitles\"]'))}\n                function addTracks(){\n                    var p=paths();\n                    clearTracks();\n                    ['af','ar','bn','da','de','en','es','fa','fi','fr','he','hi','it','ja','ko','nl','no','pl','pt','ru','sv','ta','th','uk','vi','zh','zu'].forEach(function(lang){\n                        var t=document.createElement('track');\n                        t.kind='subtitles';\n                        t.srclang=lang;\n                        t.label=lang.toUpperCase();\n                        t.default=(subPref!=='off'&&subPref===lang);\n                        t.src=p.base+encodeURIComponent(folder)+'-'+encodeURIComponent(lang)+'.vtt';\n                        video.appendChild(t);\n                    });\n                }\n                function clearCustomSub(){\n                    if(state.customSubTrack){\n                        try{state.customSubTrack.mode='disabled'}catch(_e){}\n                        state.customSubTrack=null;\n                        state.customSubLang='';\n                    }\n                }\n                function tsToSec(s){var p=String(s||'').trim().replace(',', '.').split(':');if(p.length!==3){return NaN}return (parseFloat(p[0])*3600)+(parseFloat(p[1])*60)+parseFloat(p[2])}\n                function parseVtt(text){\n                    var lines=String(text||'').replace(\/\\r\/g,'').split('\\n');\n                    var cues=[];\n                    for(var i=0;i<lines.length;i++){\n                        var ln=lines[i].trim();\n                        if(!ln||ln==='WEBVTT'||\/^\\d+$\/.test(ln)){continue}\n                        if(ln.indexOf('-->')>-1){\n                            var t=ln.split('-->');\n                            var start=tsToSec(t[0]);\n                            var end=tsToSec((t[1]||'').trim().split(' ')[0]);\n                            if(!(start>=0&&end>start)){continue}\n                            var payload=[];\n                            for(var j=i+1;j<lines.length&&lines[j].trim()!=='';j++){payload.push(lines[j]);i=j}\n                            var txt=payload.join('\\n').trim();\n                            if(txt){cues.push({s:start,e:end,t:txt})}\n                        }\n                    }\n                    return cues;\n                }\n                function loadCustomSub(lang,url){\n                    if(!url||!window.fetch||!('VTTCue' in window)){return}\n                    fetch(url,{credentials:'same-origin',cache:'no-store'}).then(function(r){\n                        if(!r||!r.ok){throw new Error('subtitle fetch failed')}\n                        return r.text();\n                    }).then(function(vtt){\n                        var cues=parseVtt(vtt);\n                        if(!cues.length){throw new Error('subtitle cues empty')}\n                        clearCustomSub();\n                        var tr=video.addTextTrack('subtitles',lang.toUpperCase(),lang);\n                        for(var i=0;i<cues.length;i++){try{tr.addCue(new VTTCue(cues[i].s,cues[i].e,cues[i].t))}catch(_e){}}\n                        tr.mode='showing';\n                        state.customSubTrack=tr;\n                        state.customSubLang=lang;\n                    }).catch(function(){});\n                }\n                function applySubs(v){\n                    var wanted=String(v||'off').toLowerCase();\n                    var trackEls=subtitleTrackEls();\n                    var applied=false;\n                    var selectedSrc='';\n                    clearCustomSub();\n                    for(var i=0;i<trackEls.length;i++){\n                        var el=trackEls[i];\n                        var tt=el&&el.track?el.track:null;\n                        if(!tt){continue}\n                        var lang=(el.srclang||tt.language||'').toLowerCase();\n                        var on=(wanted!=='off'&&lang===wanted);\n                        if(on){\n                            tt.mode='hidden';\n                            tt.mode='showing';\n                            applied=true;\n                            selectedSrc=el.src||'';\n                        }else{\n                            tt.mode='disabled';\n                        }\n                    }\n                    var all=video.textTracks;\n                    for(var j=0;j<all.length;j++){\n                        var isSubtitle=((all[j].kind||'').toLowerCase()==='subtitles'||(all[j].kind||'').toLowerCase()==='captions');\n                        if(isSubtitle&&wanted==='off'){all[j].mode='disabled'}\n                    }\n                    setTimeout(function(){\n                        if(!applied||!selectedSrc){return}\n                        var tracks=subtitleTrackEls();\n                        for(var z=0;z<tracks.length;z++){\n                            var t=tracks[z].track;\n                            if(!t){continue}\n                            var l=(tracks[z].srclang||t.language||'').toLowerCase();\n                            if(l===wanted){\n                                var c=t.cues?t.cues.length:-1;\n                                if(c===0||c===-1){loadCustomSub(wanted,selectedSrc)}\n                                break;\n                            }\n                        }\n                    },300);\n                }\n                function fillSubs(){\n                    subs.innerHTML='';\n                    var o=document.createElement('option');\n                    o.value='off';\n                    o.textContent='Subtitles Off';\n                    subs.appendChild(o);\n                    var trackEls=subtitleTrackEls();\n                    trackEls.forEach(function(t){\n                        var x=document.createElement('option');\n                        x.value=(t.srclang||'').toLowerCase();\n                        x.textContent=t.label||((t.srclang||'').toUpperCase())||'Sub';\n                        subs.appendChild(x);\n                    });\n                    subs.disabled=trackEls.length===0;\n                    subs.value=(subs.querySelector('option[value=\"'+String(subPref).toLowerCase()+'\"]')?String(subPref).toLowerCase():'off');\n                    applySubs(subs.value);\n                }\n                function audioLabel(t,i){var a=t&&t.attrs?t.attrs:{};return (t&&t.name)||(t&&t.lang)||(a&&a.NAME)||(a&&a.LANGUAGE)||('Audio '+(i+1))}\n                function audioLangFromTrack(t,i){\n                    var a=t&&t.attrs?t.attrs:{};\n                    var raw=(t&&t.lang)||(a&&a.LANGUAGE)||(t&&t.name)||(a&&a.NAME)||'';\n                    raw=String(raw||'').toLowerCase();\n                    var m=raw.match(\/[a-z]{2,3}(?:-[a-z]{2})?\/i);\n                    return m?m[0].toLowerCase():'';\n                }\n                function activeAudioTracks(){if(state.hls&&state.hls.audioTracks&&state.hls.audioTracks.length){return state.hls.audioTracks}return state.cachedAudioTracks||[]}\n                function fillAudio(){\n                    audio.innerHTML='';\n                    var tracks=activeAudioTracks();\n                    if(tracks.length<=1){\n                        var baseOpt=document.createElement('option');\n                        baseOpt.value='-1';\n                        baseOpt.textContent='Default Audio';\n                        audio.appendChild(baseOpt);\n                        audio.disabled=true;\n                        audio.value='-1';\n                        return;\n                    }\n                    tracks.forEach(function(t,i){\n                        var o=document.createElement('option');\n                        o.value=String(i);\n                        o.textContent=audioLabel(t,i);\n                        audio.appendChild(o);\n                    });\n                    audio.disabled=false;\n                    var selected=-1;\n                    if(audioLangPref){\n                        for(var ai=0;ai<tracks.length;ai++){\n                            var alang=audioLangFromTrack(tracks[ai],ai);\n                            if(alang===audioLangPref||alang.indexOf(audioLangPref+'-')===0){selected=ai;break}\n                        }\n                    }\n                    if(selected<0&&Number.isFinite(audioPref)&&audioPref>=0&&audioPref<tracks.length){selected=audioPref}\n                    if(selected<0){selected=(state.hls&&state.hls.audioTrack>=0&&state.hls.audioTrack<tracks.length)?state.hls.audioTrack:0}\n                    if(state.hls){state.hls.audioTrack=selected}\n                    audio.value=String(selected);\n                    audioPref=selected;\n                    var selTrack=tracks[selected]||null;\n                    audioLangPref=audioLangFromTrack(selTrack,selected)||audioLangPref||'en';\n                    localStorage.setItem(audioLangKey,audioLangPref);\n                    setCookie(audioLangKey,audioLangPref);\n                }\n                function absUrl(baseDir,u){\n                    if(!u){return u}\n                    if(\/^(https?:)?\\\/\\\/\/i.test(u)||\/^data:\/i.test(u)||\/^blob:\/i.test(u)){return u}\n                    if(u.charAt(0)==='\/'){\n                        try{var o=new URL(baseDir);return o.protocol+'\/\/'+o.host+u}catch(_e){return u}\n                    }\n                    return baseDir+u.replace(\/^\\.?\\\/\/,'');\n                }\n                function parseAudioTrackLines(text){\n                    var out=[];\n                    String(text||'').split(\/\\r?\\n\/).forEach(function(ln){\n                        if(!\/^#EXT-X-MEDIA:TYPE=AUDIO\/i.test(ln)){return}\n                        var attrs={};\n                        ln.replace(\/([A-Z0-9-]+)=((\\\"[^\\\"]*\\\")|[^,]*)\/gi,function(_m,k,v){attrs[k]=String(v||'').replace(\/^\\\"|\\\"$\/g,'');return''});\n                        out.push({name:attrs.NAME||'',lang:attrs.LANGUAGE||'',attrs:attrs});\n                    });\n                    return out;\n                }\n                function normalizeMasterText(text,src){\n                    var raw=String(text||'');\n                    var lines=raw.split(\/\\r?\\n\/);\n                    var baseDir=String(src||'').replace(\/[^\\\/?#]*([?#].*)?$\/,'');\n                    var audio=[];\n                    var rest=[];\n                    var firstStream=-1;\n                    for(var i=0;i<lines.length;i++){\n                        var ln=lines[i];\n                        if(firstStream<0&&\/^#EXT-X-STREAM-INF\/i.test(ln)){firstStream=i}\n                        if(\/^#EXT-X-MEDIA:TYPE=AUDIO\/i.test(ln)){\n                            var m=ln.match(\/URI=\\\"([^\\\"]+)\\\"\/i);\n                            if(m&&m[1]){ln=ln.replace(\/URI=\\\"([^\\\"]+)\\\"\/i,'URI=\\\"'+absUrl(baseDir,m[1])+'\\\"')}\n                            audio.push(ln);\n                        }else{\n                            rest.push(ln);\n                        }\n                    }\n                    for(var x=0;x<rest.length;x++){\n                        var rl=rest[x];\n                        if(rl&&rl.charAt(0)!=='#'){rest[x]=absUrl(baseDir,rl)}\n                    }\n                    if(!audio.length||firstStream<0){\n                        var only=rest.join('\\n');\n                        return {text:only,changed:only!==raw,audioTracks:parseAudioTrackLines(only)};\n                    }\n                    var firstAudio=-1;\n                    for(var j=0;j<lines.length;j++){if(\/^#EXT-X-MEDIA:TYPE=AUDIO\/i.test(lines[j])){firstAudio=j;break}}\n                    if(firstAudio>=0&&firstAudio<firstStream){\n                        var unchanged=rest.join('\\n');\n                        return {text:unchanged,changed:unchanged!==raw,audioTracks:parseAudioTrackLines(unchanged)};\n                    }\n                    var streamPos=0;\n                    for(var k=0;k<rest.length;k++){if(\/^#EXT-X-STREAM-INF\/i.test(rest[k])){streamPos=k;break}}\n                    var out=rest.slice(0,streamPos).concat(audio).concat(rest.slice(streamPos));\n                    var outText=out.join('\\n');\n                    return {text:outText,changed:outText!==raw,audioTracks:parseAudioTrackLines(outText)};\n                }\n                function prepareHlsSource(src){\n                    if(!window.fetch){return Promise.resolve(src)}\n                    return fetch(src,{credentials:'same-origin',cache:'no-store'}).then(function(r){\n                        if(!r||!r.ok){return src}\n                        return r.text().then(function(txt){\n                            var n=normalizeMasterText(txt,src);\n                            state.cachedAudioTracks=n.audioTracks||[];\n                            if(!n.changed){return src}\n                            if(state.manifestBlobUrl){try{URL.revokeObjectURL(state.manifestBlobUrl)}catch(_e){}}\n                            state.manifestBlobUrl=URL.createObjectURL(new Blob([n.text],{type:'application\/vnd.apple.mpegurl'}));\n                            return state.manifestBlobUrl;\n                        });\n                    }).catch(function(){return src});\n                }\n                function destroyHls(){\n                    if(state.hls){try{state.hls.stopLoad()}catch(_e1){}try{state.hls.detachMedia()}catch(_e2){}try{state.hls.destroy()}catch(_e3){}state.hls=null}\n                    if(state.manifestBlobUrl){try{URL.revokeObjectURL(state.manifestBlobUrl)}catch(_e4){}state.manifestBlobUrl=''}\n                    state.cachedAudioTracks=[];\n                    clearCustomSub();\n                    clearTracks();\n                }\n                function playMp4(keep,auto){\n                    var p=paths();\n                    var src=quality==='hd' ? p.mp4hd : p.mp4sd;\n                    destroyHls();\n                    clearError();\n                    root.classList.add('is-loaded');\n                    root.classList.add('has-player');\n                    audio.innerHTML='<option value=\"-1\">Default Audio<\/option>';\n                    audio.disabled=true;\n                    subs.innerHTML='<option value=\"off\">Subtitles Off<\/option>';\n                    subs.disabled=true;\n                    video.src=src;\n                    video.load();\n                    video.addEventListener('loadedmetadata',function(){try{if(keep>0){video.currentTime=keep}}catch(_e){}if(auto){video.play().catch(function(){})}},{once:true});\n                }\n                function playHls(keep,auto){\n                    var p=paths();\n                    var src=quality==='hd' ? (p.hlsHd||p.hlsSd) : (p.hlsSd||p.hlsHd);\n                    if(!src){showError('HLS source is missing for this video.');return}\n                    ensureHls(hlsLocal,state).then(function(has){\n                        destroyHls();\n                        clearError();\n                        root.classList.add('is-loaded');\n                        root.classList.add('has-player');\n                        addTracks();\n                        if(!has&&nativeHls){video.src=src;video.load();fillAudio();fillSubs();video.addEventListener('loadedmetadata',function(){try{if(keep>0){video.currentTime=keep}}catch(_e){}if(auto){video.play().catch(function(){})}},{once:true});return}\n                        if(!has){showError('HLS player library is unavailable.');return}\n                        state.hls=new window.Hls({startLevel:-1,capLevelToPlayerSize:false});\n                        state.hls.attachMedia(video);\n                        state.hls.on(window.Hls.Events.MEDIA_ATTACHED,function(){\n                            prepareHlsSource(src).then(function(finalSrc){\n                                if(state.hls){state.hls.loadSource(finalSrc)}\n                            });\n                        });\n                        state.hls.on(window.Hls.Events.MANIFEST_PARSED,function(){\n                            fillAudio();\n                            fillSubs();\n                            try{if(keep>0){video.currentTime=keep}}catch(_e){}\n                            if(auto){video.play().catch(function(){})}\n                        });\n                        state.hls.on(window.Hls.Events.AUDIO_TRACKS_UPDATED,function(){fillAudio()});\n                        state.hls.on(window.Hls.Events.ERROR,function(_,data){\n                            if(data&&data.fatal){\n                                destroyHls();\n                                var detail=(data.details||data.type||'unknown');\n                                var code=(data.response&&data.response.code)?(' HTTP '+data.response.code):'';\n                                var frag=(data.url||data.frag&&data.frag.url||src||'');\n                                showError('HLS failed: '+detail+code+(frag?(' | '+frag):''));\n                            }\n                        })\n                    }).catch(function(err){\n                        showError('HLS setup failed: '+(err&&err.message?err.message:String(err)));\n                    })\n                }\n                function load(keep,auto){if(folder){playHls(keep||0,!!auto)}else{playMp4(keep||0,!!auto)}}\n\n                qualityBtn.addEventListener('click',function(){\n                    var keep=video.currentTime||0;\n                    var auto=!video.paused&&!video.ended&&video.readyState>2;\n                    quality=quality==='hd' ? 'sd' : 'hd';\n                    localStorage.setItem(qualityKey,quality);\n                    setCookie(qualityKey,quality);\n                    qualityBtn.textContent=quality.toUpperCase();\n                    if(root.classList.contains('is-loaded')){load(keep,auto)}\n                });\n                audio.addEventListener('change',function(){\n                    var i=parseInt(audio.value,10);\n                    audioPref=Number.isFinite(i)?i:-1;\n                    localStorage.setItem(audioKey,String(audioPref));\n                    var tracks=activeAudioTracks();\n                    var t=(Number.isFinite(i)&&i>=0&&i<tracks.length)?tracks[i]:null;\n                    audioLangPref=(audioLangFromTrack(t,i)||audioLangPref||'en').toLowerCase();\n                    localStorage.setItem(audioLangKey,audioLangPref);\n                    setCookie(audioLangKey,audioLangPref);\n                    if(state.hls&&Number.isFinite(i)&&i>=0){\n                        var keep=video.currentTime||0;\n                        state.hls.audioTrack=i;\n                        if(typeof state.hls.startLoad==='function'){try{state.hls.startLoad(-1)}catch(_e){}}\n                        setTimeout(function(){try{if(keep>0){video.currentTime=keep}video.play().catch(function(){})}catch(_e){}},80);\n                    }\n                });\n                subs.addEventListener('change',function(){\n                    subPref=subs.value;\n                    localStorage.setItem(subKey,subPref);\n                    setCookie(subKey,subPref);\n                    applySubs(subPref);\n                });\n                video.addEventListener('error',function(){showError('Video source could not be loaded.')});\n                if(playBtn){playBtn.addEventListener('click',function(){load(0,true)})}\n            }\n            function boot(){A(document.querySelectorAll('.cisap')).forEach(bootOne)}\n            if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',boot)}else{boot()}\n        })();\n    <\/script>\n    \n\n\n\n<p>To our Skinart family, students, and friends from all corners of the world\u2026<\/p>\n\n\n\n<p>As we wrap up another incredible year, we want to take a moment to thank each and every one of you. Whether you\u2019ve joined us in-person, online, or simply followed our journey \u2013 you are the reason we continue to thrive and grow.<\/p>\n\n\n\n<p>This year, we\u2019ve seen amazing creativity, dedication, and passion. Your talent and commitment have inspired us to push boundaries and continue offering top-tier training and support in tattooing, piercing, microblading, and more.<\/p>\n\n\n\n<p>To those who trusted us with their learning journey this year \u2013 thank you for letting us be a part of your dreams.<\/p>\n\n\n\n<p>As the holiday season approaches, we wish you peace, joy, and time to recharge for the year ahead. 2025 is going to be an exciting year, and we can\u2019t wait to share it with you!<\/p>\n\n\n\n<p>Merry Christmas and Happy Holidays from all of us at Skinart!<\/p>\n\n\n\n<p>Visit us anytime at <a href=\"https:\/\/skinarttraining.com\/\">https:\/\/skinarttraining.com\/<\/a> and don\u2019t forget to follow us on Facebook for updates, inspiration, and exciting announcements.<\/p>\n\n\n\n<p>Happy Holidays!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To our Skinart family, students, and friends from all corners of the world\u2026 As we wrap up another incredible year, we want to take a moment to thank each and every one of you. Whether you\u2019ve joined us in-person, online, or simply followed our journey \u2013 you are the reason we continue to thrive and&hellip;&nbsp;<a href=\"https:\/\/skinarttraining.com\/in\/merry-christmas\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">Merry Christmas<\/span><\/a><\/p>\n","protected":false},"author":4043,"featured_media":873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_themeisle_gutenberg_block_has_review":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[30],"tags":[],"class_list":["post-835","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-skinart-team"],"jetpack_featured_media_url":"https:\/\/skinarttraining.com\/in\/wp-content\/uploads\/sites\/14\/2024\/12\/MerryXmas.webp","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/posts\/835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/users\/4043"}],"replies":[{"embeddable":true,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/comments?post=835"}],"version-history":[{"count":5,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/posts\/835\/revisions"}],"predecessor-version":[{"id":847,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/posts\/835\/revisions\/847"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/media\/873"}],"wp:attachment":[{"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/media?parent=835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/categories?post=835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/skinarttraining.com\/in\/wp-json\/wp\/v2\/tags?post=835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}