chore: add kron and sdwan demo apps

This commit is contained in:
administrator 2026-05-17 18:46:40 +00:00
parent c75c3485af
commit b4e3696a3c
13 changed files with 271 additions and 0 deletions

2
kron/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules/
dev-dist/

1
kron/dist/assets/index-DDORw3oI.css vendored Normal file
View file

@ -0,0 +1 @@
:root{--bg: #0a0a0f;--surface: #12121a;--border: #1e1e2e;--text: #c8c8d4;--muted: #5a5a72;--green: #00e676;--red: #ff3b30;--amber: #ff9500;--blue: #0066ff;--radius: 12px;--font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--mono: "SF Mono", "Fira Code", "JetBrains Mono", "Courier New", monospace}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}html,body,#root{height:100%}body{background:var(--bg);color:var(--text);font-family:var(--font);-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;overflow:hidden}.app-container{height:100%;display:flex;flex-direction:column;max-width:480px;margin:0 auto}.location-screen{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px 24px;text-align:center}.loc-icon{font-size:40px;margin-bottom:8px}.loc-title{font-size:24px;font-weight:700;color:var(--text);letter-spacing:-.02em;margin-bottom:4px}.loc-sub{font-size:13px;color:var(--muted);margin-bottom:32px}.loc-list{width:100%;max-width:320px;display:flex;flex-direction:column;gap:10px}.loc-btn{display:flex;align-items:center;gap:12px;width:100%;padding:14px 16px;border-radius:12px;background:var(--surface);border:1px solid var(--border);color:var(--text);font-size:15px;font-weight:500;cursor:pointer;text-align:left;transition:border-color .2s,background .2s;font-family:var(--font)}.loc-btn:active{background:#1a1a2a;border-color:var(--blue);transform:scale(.98)}.loc-dot{width:8px;height:8px;border-radius:50%;background:var(--muted);flex-shrink:0}.loc-footer{margin-top:auto;font-size:9px;color:var(--muted);letter-spacing:.2em;padding-bottom:12px}.auth-panel{padding:10px 16px;background:var(--surface);border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px;flex-shrink:0}.location-group{flex:1;min-width:0}.auth-label{font-size:9px;color:var(--muted);text-transform:uppercase;letter-spacing:.12em;margin-bottom:2px;font-weight:600}.loc-display{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:var(--text)}.loc-display .loc-dot{background:var(--green)}.otp-box{flex-shrink:0;width:120px;background:var(--bg);border:1px solid var(--border);border-radius:10px;padding:8px;text-align:center}.otp-label{font-size:7px;color:var(--muted);text-transform:uppercase;letter-spacing:.12em;font-weight:600;margin-bottom:3px}.otp-code{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--green);letter-spacing:.1em}.otp-timer{margin-top:5px;height:2px;background:var(--border);border-radius:2px;overflow:hidden}.otp-timer-bar{height:100%;background:var(--blue);border-radius:2px;transition:width 1s linear}.terminal-panel{flex:1;display:flex;flex-direction:column;background:#0d0d14;min-height:0}.terminal-header{display:flex;align-items:center;gap:6px;padding:7px 12px;background:#16161e;border-bottom:1px solid var(--border);flex-shrink:0}.terminal-dot{width:9px;height:9px;border-radius:50%}.terminal-title{margin-left:auto;font-size:9px;color:var(--muted);font-family:var(--mono)}.terminal-body{flex:1;overflow-y:auto;padding:12px;font-family:var(--mono);font-size:13px;line-height:1.6;-webkit-overflow-scrolling:touch}.t-line{white-space:pre-wrap;word-break:break-word;min-height:1.4em}.t-green{color:var(--green)}.t-red{color:var(--red)}.t-amber{color:var(--amber)}.t-prompt{color:var(--green);white-space:pre}.t-input{background:none;border:none;color:var(--text);font-family:var(--mono);font-size:13px;outline:none;caret-color:var(--green);flex:1;min-width:0}.t-input::placeholder{color:var(--muted);opacity:.5;font-size:11px}.t-line form{display:flex;align-items:center;gap:0}.cursor-blink{color:var(--green);animation:blink 1s step-end infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:0}}.matrix-canvas{position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;pointer-events:none}.access-banner{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:#000000f0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px;text-align:center;animation:fadeIn .6s ease}.access-icon{font-size:48px;margin-bottom:12px;animation:float 2s ease-in-out infinite}.access-title{font-size:24px;font-weight:700;color:var(--green);letter-spacing:.05em;margin-bottom:6px}.access-sub{font-size:12px;color:var(--muted);margin-bottom:24px}.access-detail{font-size:12px;color:var(--text);font-family:var(--mono);line-height:2;text-align:left;margin-bottom:32px}.reset-btn{padding:14px 40px;border-radius:10px;background:var(--green);color:#000;font-weight:700;font-size:15px;border:none;cursor:pointer;font-family:var(--font)}.reset-btn:active{transform:scale(.97)}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}

40
kron/dist/assets/index-Djs4PpQW.js vendored Normal file

File diff suppressed because one or more lines are too long

14
kron/dist/index.html vendored Normal file
View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="theme-color" content="#0a0a0f"><meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<title>Kron PAM Vault Break</title>
<script type="module" crossorigin src="/kron/assets/index-Djs4PpQW.js"></script>
<link rel="stylesheet" crossorigin href="/kron/assets/index-DDORw3oI.css">
<link rel="manifest" href="/kron/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/kron/registerSW.js"></script></head><body>
<div style="background:#0a0a0f; border-bottom:1px solid #1e1e2e; padding:5px 12px; font-size:12px;">
<a href="/" style="color:#5a5a72; text-decoration:none;">&larr; GITEX 2026 Hub</a>
</div>
<div id="root"></div>
</body></html>

1
kron/dist/manifest.webmanifest vendored Normal file
View file

@ -0,0 +1 @@
{"name":"Kron PAM Vault Break","short_name":"Kron Vault","description":"GITEX 2026 PAM security challenge","start_url":"/","display":"standalone","background_color":"#06060e","theme_color":"#06060e","lang":"en","scope":"/kron/","orientation":"portrait","icons":[{"src":"icon-192.png","sizes":"192x192","type":"image/png"},{"src":"icon-512.png","sizes":"512x512","type":"image/png"}]}

1
kron/dist/registerSW.js vendored Normal file
View file

@ -0,0 +1 @@
if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('/kron/sw.js', { scope: '/kron/' })})}

1
kron/dist/sw.js vendored Normal file
View file

@ -0,0 +1 @@
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didnt register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const l=e=>i(e,t),d={module:{uri:t},exports:o,require:l};s[t]=Promise.all(n.map(e=>d[e]||l(e))).then(e=>(r(...e),o))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"0ccfe96049cf135e9d3b1af97624b571"},{url:"index.html",revision:"6399a5aae2d506f7b9dcd626a16b4e00"},{url:"assets/index-Djs4PpQW.js",revision:null},{url:"assets/index-DDORw3oI.css",revision:null},{url:"manifest.webmanifest",revision:"dec3f83176afdc0af818b7d71a09b5d0"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});

1
kron/dist/workbox-9c191d2f.js vendored Normal file

File diff suppressed because one or more lines are too long

1
sdwan/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules/

179
sdwan/dist/assets/index-d6HUX9kC.js vendored Normal file
View file

@ -0,0 +1,179 @@
(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))a(i);new MutationObserver(i=>{for(const r of i)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&a(o)}).observe(document,{childList:!0,subtree:!0});function s(i){const r={};return i.integrity&&(r.integrity=i.integrity),i.referrerPolicy&&(r.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?r.credentials="include":i.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function a(i){if(i.ep)return;i.ep=!0;const r=s(i);fetch(i.href,r)}})();const N={mpls:20,internet:50,lte:60},E={mpls:.2,internet:.3,lte:.5};function P(e,t={}){return e.map(s=>{const a=t[s.id];return{...s,latencyMs:(a==null?void 0:a.latencyMs)??N[s.id]??100,packetLossPercent:(a==null?void 0:a.packetLossPercent)??E[s.id]??1}})}const C=100,x=1;function D(e){return e.latencyMs<=C&&e.packetLossPercent<=x}function W(e){return e.map(t=>({...t,isValid:D(t)}))}function O(e){return M(e.filter(t=>t.isValid))[0]}function R(e){return M(e)[0]}function M(e){return e.sort((t,s)=>{const a=t.packetLossPercent-s.packetLossPercent;return Math.abs(a)>.001?a:t.latencyMs-s.latencyMs})}function _(e){const{links:t,activeLinkId:s,degradationTicks:a}=e;if(t.filter(c=>c.isValid).length===0){const c=R(t);return{activeLinkId:c?c.id:null,systemState:"degraded",degradationTicks:a+1}}const r=O(t),o=t.find(c=>c.id===s);return!o||!o.isValid?{activeLinkId:r.id,systemState:"normal",degradationTicks:0}:{activeLinkId:o.id,systemState:"normal",degradationTicks:0}}const m=[{text:"What does SLA stand for in the context of SD-WAN?",options:["Service Level Agreement","Secure Link Access","System Latency Analysis","Serial Link Aggregation"],answer:0},{text:"What is the maximum acceptable latency threshold in this application?",options:["50 ms","80 ms","100 ms","150 ms"],answer:2},{text:"What is the maximum acceptable packet loss percentage per the SLA?",options:["0.5%","1%","2%","5%"],answer:1},{text:"How many WAN links does the SD-WAN Traffic Master simulate?",options:["2","3","4","5"],answer:1},{text:"Which WAN link type is the default primary path in the simulation?",options:["LTE","Internet","MPLS","Satellite"],answer:2},{text:"What happens when ALL links violate SLA thresholds?",options:["The application crashes","Traffic is silently dropped","The system enters Degraded Mode","All links are automatically reset"],answer:2},{text:"What is the full meaning of SD-WAN?",options:["Software-Defined Wide Area Network","Secure Digital Wireless Access Network","System-Defined Wide Access Node","Software-Driven Wide Application Network"],answer:0},{text:"MPLS, Internet and LTE are responsible for which type of SD-WAN tunnels?",options:["Underlay","Overlay","BIOS","Secure VPN"],answer:0},{text:"Which company powers this SD-WAN Traffic Master application?",options:["ARUBA","Juniper","Sechpoint","All of the above"],answer:2},{text:"What is the role of Business Intent Overlay in SD-WAN?",options:["Defines network policies based on business requirements and applications","Manages physical hardware connections","Encrypts data packets between endpoints","Monitors device CPU usage"],answer:0}];function S(){return m.length}const y=60;function A(){return{screen:"instructions",userName:"",currentQuestion:0,answers:[],timeRemaining:30,timerId:null,active:!1,attemptCount:0}}function F(e){return m[e]}function Q(e){let t=0;for(let s=0;s<m.length;s++)e[s]===m[s].answer&&t++;return{correct:t,total:m.length,percentage:Math.round(t/m.length*100)}}const $={mpls:"#8B5CF6",lte:"#EF4444",internet:"#F59E0B"};function T(e,t,s){return e<=t?"good":e<=s?"warn":"bad"}function B(e){return T(e,80,100)}function H(e){return T(e,.5,1)}function b(e){const{links:t,activeLinkId:s,systemState:a}=e;document.getElementById("app").innerHTML=`
${U(a)}
${V()}
${a==="degraded"?Y():""}
${K(t,s)}
${J(t,s,a)}
${Z()}
`,G(e)}function U(e){return`
<header class="header">
<div>
<h1>HPE Aruba SD-WAN Traffic Master</h1>
<p class="header-subtitle">Real-time network traffic management simulation</p>
<p class="header-powered">Powered by Sechpoint</p>
<div class="header-thresholds">
<span class="threshold-badge">Latency &le; 100 ms</span>
<span class="threshold-badge">Packet Loss &le; 1%</span>
</div>
</div>
<div class="header-badges">
${e==="normal"?'<span class="badge badge-normal">Normal</span>':'<span class="badge badge-degraded">Degraded Mode</span>'}
</div>
</header>`}function V(){return`
<div class="controls">
<button class="quiz-btn" data-action="start-quiz">🧠 Take Quiz</button>
</div>`}function Y(){return`
<div class="degraded-warning">
<h3> Degraded Mode All links violate SLA thresholds</h3>
<p>The best available link is kept active, but network performance is degraded. Monitor traffic closely.</p>
</div>`}function K(e,t){return`<div class="link-cards">${e.map(a=>j(a,t)).join("")}</div>`}function j(e,t){const s=e.id===t;return`
<div class="${["link-card",s?"active-link":"",!e.isValid&&!s?"blocked":""].filter(Boolean).join(" ")}" data-link-id="${e.id}">
${s?'<span class="active-badge">Active</span>':""}
<div class="link-header">
<span class="link-dot" style="background:${e.color}"></span>
<span class="link-name">${e.name}</span>
<span class="link-status ${e.isValid?"status-healthy":"status-blocked"}">
${e.isValid?"Healthy":"Blocked"}
</span>
</div>
${q("Latency",`${e.latencyMs} ms`,"100 ms",e.latencyMs,150,B(e.latencyMs),e.latencyMs>100?" ⚠":"",e.id,"latencyMs")}
${q("Packet Loss",`${e.packetLossPercent.toFixed(2)}%`,"1.00%",e.packetLossPercent,5,H(e.packetLossPercent),e.packetLossPercent>1?" ⚠":"",e.id,"packetLossPercent")}
</div>`}function q(e,t,s,a,i,r,o,c,u){const l=Math.min(a/i*100,100);return`
<div class="metric">
<div class="metric-label">
<span>${e}</span>
<span class="metric-value ${r}">${t}${o}</span>
</div>
<div class="metric-bar">
<div class="metric-bar-fill ${r}" style="width:${l}%"></div>
</div>
<div class="metric-limit">SLA limit: ${s}</div>
<div class="metric-slider">
<input
type="range"
min="0"
max="${u==="latencyMs"?150:5}"
step="${u==="latencyMs"?1:.01}"
value="${a}"
data-link-id="${c}"
data-field="${u}"
/>
<label class="slider-label">${t}</label>
</div>
</div>`}function J(e,t,s){const a=t?e.find(c=>c.id===t):null,i=a?a.name:"",r="",o=a?`background:${$[a.id]}22;color:${$[a.id]};`:"background:#374151;color:#9ca3af;";return`
<div class="path-section">
<h3>Active Path ${s==="degraded"?'<span class="badge badge-degraded" style="margin-left:8px">Degraded</span>':""}</h3>
<div class="path-visual">
<div class="path-endpoint">
<span class="path-endpoint-icon">&#x1F3E2;</span>
<span>Branch Office</span>
</div>
<div class="path-line"></div>
<div class="path-link-badge ${r}" style="${o}">
${i}
</div>
<div class="path-line"></div>
<div class="path-endpoint">
<span class="path-endpoint-icon">&#x2601;</span>
<span>Data Center</span>
</div>
</div>
</div>`}function Z(){return`
<div class="info-footer">
<p><strong>SLA Thresholds:</strong> Latency &le; 100 ms | Packet Loss &le; 1%</p>
<p><strong>Path Selection:</strong> Lowest packet loss &rarr; Lowest latency</p>
<p><strong>Auto Failover:</strong> Traffic automatically shifts when active link violates SLA</p>
<p><strong>Degraded Mode:</strong> When all links fail SLA, the best available link remains active</p>
</div>`}function G(e){document.querySelectorAll("[data-action]").forEach(t=>{t.addEventListener("click",()=>{t.dataset.action==="start-quiz"&&e.onStartQuiz&&e.onStartQuiz()})}),document.querySelectorAll(".metric-slider input").forEach(t=>{t.addEventListener("input",s=>{const a=s.target.dataset.linkId,i=s.target.dataset.field,r=i==="latencyMs"?parseInt(s.target.value,10):parseFloat(s.target.value);e.onUpdateMetric&&e.onUpdateMetric(a,i,r)})})}function X(e,t){var r,o,c,u;const s=document.querySelector(".quiz-overlay");s&&s.remove();const a=document.createElement("div");a.className="quiz-overlay";const i=document.createElement("div");switch(i.className="quiz-container",e.screen){case"instructions":i.innerHTML=ee();break;case"name":i.innerHTML=te();break;case"quiz":i.innerHTML=ne(e);break;case"results":i.innerHTML=se(e);break}if(a.appendChild(i),document.body.appendChild(a),e.screen==="instructions"){const l=i.querySelector(".btn-primary");l&&l.addEventListener("click",t.onProceedToName),(r=i.querySelector(".btn-secondary"))==null||r.addEventListener("click",t.onCloseQuiz)}if(e.screen==="name"){const l=i.querySelector(".name-field"),v=i.querySelector(".name-error"),f=i.querySelector(".btn-primary"),z=()=>{const h=l.value.trim();if(!h){v.classList.add("visible");return}v.classList.remove("visible"),t.onStartQuiz(h)};f==null||f.addEventListener("click",z),l==null||l.addEventListener("keydown",h=>{h.key==="Enter"&&z()}),(o=i.querySelector(".btn-secondary"))==null||o.addEventListener("click",t.onCloseQuiz)}e.screen==="quiz"&&i.querySelectorAll(".quiz-option").forEach(l=>{l.addEventListener("click",()=>{const v=parseInt(l.dataset.optionIndex,10);t.onAnswerQuestion(e.currentQuestion,v)})}),e.screen==="results"&&((c=i.querySelector(".btn-primary"))==null||c.addEventListener("click",t.onCloseQuiz),(u=i.querySelector(".btn-secondary"))==null||u.addEventListener("click",t.onRestartQuiz))}function ee(){return`
<div class="quiz-header">
<h2>SD-WAN Knowledge Quiz</h2>
<p>Test your understanding of the HPE Aruba SD-WAN Traffic Master</p>
</div>
<div class="quiz-body">
<div class="study-note">
<strong>Important:</strong> Please study the application dashboard carefully
before starting the quiz. Observe how the simulation works, understand the SLA
thresholds, failover behavior, and the different link types. You will have
<strong>30 seconds</strong> to answer each of the <strong>10 questions</strong>.
</div>
<div class="quiz-instructions">
<h3>What you need to know:</h3>
<ul>
<li>SLA thresholds for latency and packet loss</li>
<li>The three WAN link types and their roles</li>
<li>Automatic path selection and failover rules</li>
<li>Path selection and failover rules</li>
<li>What happens during Degraded Mode</li>
</ul>
</div>
</div>
<div class="quiz-footer quiz-actions">
<button class="btn-secondary">Cancel</button>
<button class="btn-primary">Next </button>
</div>
`}function te(){return`
<div class="quiz-header">
<h2>Enter Your Name</h2>
<p>Your results will be saved under this name</p>
</div>
<div class="quiz-body">
<input
class="name-field"
type="text"
placeholder="Type your name here..."
maxlength="40"
autocomplete="off"
/>
<div class="name-error">Please enter your name to continue.</div>
</div>
<div class="quiz-footer quiz-actions">
<button class="btn-secondary">Cancel</button>
<button class="btn-primary">Start Quiz</button>
</div>
`}function ne(e){const t=e._questionData;if(!t)return"";const s=e.currentQuestion+1,a=e._totalQuestions,i=e.currentQuestion/a*100,r=e.timeRemaining<=10?" urgent":"",o=["A","B","C","D"];return`
<div class="quiz-header">
<h2>Question ${s} of ${a}</h2>
<div class="quiz-name-badge">Player: ${e.userName}</div>
</div>
<div class="quiz-body">
<div class="quiz-progress">
<div class="quiz-progress-bar">
<div class="quiz-progress-fill" style="width:${i}%"></div>
</div>
<div class="quiz-timer${r}">${e.timeRemaining}s</div>
</div>
<div class="quiz-question-text">${t.text}</div>
<div class="quiz-options">
${t.options.map((c,u)=>`
<div class="quiz-option" data-option-index="${u}">
<span class="option-letter">${o[u]}</span>
<span>${c}</span>
</div>
`).join("")}
</div>
</div>
`}function se(e){const t=e._results;if(!t)return"";const s=t.percentage>=y,a=!s&&e.attemptCount<2;let i="",r="",o="";return s?(i="Congratulations! You passed the quiz.",r='<div class="quiz-prize">🎉 Come to the <strong>Sechpoint Technologies</strong> booth to claim your prize!</div>'):a?(i=`You scored below ${y}%. You have one more attempt.`,o='<p class="quiz-retry-note">Study the dashboard carefully and try again.</p>'):i=`You scored below ${y}%. No more attempts allowed.`,`
<div class="quiz-header">
<h2>Quiz Complete!</h2>
<div class="quiz-name-badge">${e.userName}</div>
</div>
<div class="quiz-body quiz-results">
<div class="quiz-score-circle ${s?"":"quiz-fail"}">
<span class="quiz-score-number">${t.percentage}%</span>
<span class="quiz-score-label">SCORE</span>
</div>
<p class="quiz-score-detail">
${t.correct} out of ${t.total} correct | Pass mark: ${y}% | Attempt ${e.attemptCount} of 2
</p>
<p class="quiz-feedback">${i}</p>
${r}
${o}
</div>
<div class="quiz-footer quiz-actions">
${a?'<button class="btn-secondary">Retake Quiz</button>':""}
<button class="btn-primary">Return to Dashboard</button>
</div>
`}const ie=[{id:"mpls",name:"MPLS",latencyMs:20,packetLossPercent:.2,color:"#8B5CF6"},{id:"lte",name:"LTE",latencyMs:60,packetLossPercent:.5,color:"#EF4444"},{id:"internet",name:"Internet",latencyMs:50,packetLossPercent:.3,color:"#F59E0B"}];let d={links:structuredClone(ie).map(e=>({...e,isValid:!0})),activeLinkId:"mpls",systemState:"normal",degradationTicks:0,tick:0,metricOverrides:{}},w=null;function I(){let e=P(d.links,d.metricOverrides);e=W(e);const t=_({...d,links:e});d={...d,links:e,activeLinkId:t.activeLinkId,systemState:t.systemState,degradationTicks:t.degradationTicks,tick:d.tick+1},b(k())}function k(){return{...d,onStartQuiz:ce,onUpdateMetric:ae}}function ae(e,t,s){d.metricOverrides={...d.metricOverrides,[e]:{...d.metricOverrides[e],[t]:s}},I()}function re(){w||(w=setInterval(I,1500))}let n=A();function p(){n.active&&requestAnimationFrame(()=>{n.active&&(n._questionData=F(n.currentQuestion),n._totalQuestions=S(),X(n,{onCloseQuiz:le,onProceedToName:()=>{n.screen="name",p()},onStartQuiz:e=>{n.userName=e,n.screen="quiz",n.currentQuestion=0,n.answers=[],n.timeRemaining=30,p(),g()},onAnswerQuestion:(e,t)=>{L(),n.answers[e]=t,n.currentQuestion<S()-1?(n.currentQuestion++,n.timeRemaining=30,p(),g()):(n.attemptCount++,n._results=Q(n.answers),n.screen="results",p())},onRestartQuiz:()=>{L();const e=n.userName,t=n.attemptCount;n=A(),n.active=!0,n.userName=e,n.attemptCount=t,n.screen="quiz",n.currentQuestion=0,n.answers=[],n.timeRemaining=30,p(),g()}}))})}function g(){L();let e=30;n.timeRemaining=e,n.timerId=setInterval(()=>{e--,n.timeRemaining=e,e<=0?(clearInterval(n.timerId),n.timerId=null,n.answers[n.currentQuestion]=-1,n.currentQuestion<S()-1?(n.currentQuestion++,n.timeRemaining=30,p(),g()):(n.attemptCount++,n._results=Q(n.answers),n.screen="results",p())):oe(e)},1e3)}function oe(e){const t=document.querySelector(".quiz-timer");t&&(t.textContent=`${e}s`,e<=10?t.classList.add("urgent"):t.classList.remove("urgent"))}function L(){n.timerId&&(clearInterval(n.timerId),n.timerId=null)}function ce(){n=A(),n.active=!0,n.screen="instructions",b(k()),p()}function le(){L(),n.active=!1;const e=document.querySelector(".quiz-overlay");e&&e.remove(),b(k())}b(k());re();

1
sdwan/dist/assets/index-wI-vnel9.css vendored Normal file

File diff suppressed because one or more lines are too long

9
sdwan/dist/favicon.svg vendored Normal file
View file

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" rx="6" fill="#0f172a"/>
<path d="M6 12 L16 6 L26 12 L26 20 L16 26 L6 20 Z" fill="none" stroke="#38bdf8" stroke-width="2"/>
<circle cx="16" cy="16" r="3" fill="#38bdf8"/>
<line x1="6" y1="12" x2="16" y2="16" stroke="#38bdf8" stroke-width="1.5" opacity="0.5"/>
<line x1="26" y1="12" x2="16" y2="16" stroke="#38bdf8" stroke-width="1.5" opacity="0.5"/>
<line x1="6" y1="20" x2="16" y2="16" stroke="#38bdf8" stroke-width="1.5" opacity="0.5"/>
<line x1="26" y1="20" x2="16" y2="16" stroke="#38bdf8" stroke-width="1.5" opacity="0.5"/>
</svg>

After

Width:  |  Height:  |  Size: 639 B

20
sdwan/dist/index.html vendored Normal file
View file

@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HPE Aruba SD-WAN Traffic Master</title>
<script type="module" crossorigin src="/sdwan/assets/index-d6HUX9kC.js"></script>
<link rel="stylesheet" crossorigin href="/sdwan/assets/index-wI-vnel9.css">
</head>
<body>
<div style="background:#f0f4f8; border-bottom:1px solid #e2e8f0; padding:6px 16px; font-size:13px;">
<a href="/" style="color:#64748b; text-decoration:none; display:inline-flex; align-items:center; gap:4px;">
&larr; GITEX 2026 Hub
</a>
</div>
<div id="app">
<!-- Populated by main.js -->
</div>
</body>
</html>