#serverBuddy {
position: fixed;
display: none;
right: 16px;
top: 50%;
transform: translateY(-50%);
z-index: 2147483000;
cursor: grab;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
opacity: 0.3;
transition: opacity 0.5s ease;
touch-action: none;
}
#serverBuddy.active {
opacity: 1;
}
#serverBuddy:hover {
opacity: 1;
}
#serverBuddy.dragging {
opacity: 1;
cursor: grabbing;
transition: none;
}
#serverBuddy img {
width: 96px;
height: 96px;
image-rendering: pixelated;
image-rendering: crisp-edges;
display: block;
border: none;
outline: none;
pointer-events: none;
-webkit-user-drag: none;
user-drag: none;
}
#serverBuddy.dizzy img {
animation: buddyShake 0.15s ease-in-out 6;
}
@keyframes buddyShake {
0% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(-4px, 2px) rotate(-8deg); }
50% { transform: translate(4px, -2px) rotate(8deg); }
75% { transform: translate(-2px, 1px) rotate(-4deg); }
100% { transform: translate(0, 0) rotate(0deg); }
}
#buddySpeech {
position: fixed;
right: 120px;
top: 50%;
transform: translateY(-50%) scale(0);
background: #fff;
color: #333;
padding: 12px 18px;
border-radius: 12px;
border: 2px solid #ccc;
font-family: 'Press Start 2P', 'Courier New', Courier, monospace;
font-size: 16px;
line-height: 1.8;
-webkit-font-smoothing: none;
-moz-osx-font-smoothing: unset;
font-smooth: never;
text-rendering: optimizeSpeed;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
white-space: normal;
max-width: 320px;
word-wrap: break-word;
z-index: 2147483001;
opacity: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
pointer-events: none;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
#buddySpeech.visible {
opacity: 1;
transform: translateY(-50%) scale(1);
}
#buddySpeech::after {
content: '';
position: absolute;
right: -8px;
top: 50%;
transform: translateY(-50%);
width: 0;
height: 0;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
border-left: 8px solid #ccc;
}
#buddySpeech.bubble-right::after {
right: auto;
left: -8px;
border-left: none;
border-right: 8px solid #ccc;
}

(function() {
var fontLink = document.createElement('link');
fontLink.rel = 'stylesheet';
fontLink.href = 'https://fonts.googleapis.com/css2?family=Press+Start+2P';
document.head.appendChild(fontLink);
/* === CONFIG === */
var SLEEP_SEC = 30;
var HAPPY_SEC = 4;
var ERROR_SEC = 6;
var LOAD_SEC = 5;
var FADE_SEC = 5;
var DIZZY_SEC = 4;
var CHAT_URL = '/Willkommen/Helikon';
var TOPIC_DELAY = 4;
var DRAG_THRESHOLD = 6;
var SHAKE_THRESHOLD = 5;
var SHAKE_WINDOW = 800;
var SHAKE_MIN_DIST = 15;
var STORAGE_KEY = 'serverBuddyPos';
/* === GIFS === */
var GIFS = new Array(5);
GIFS[0] = '/@api/deki/files/403/=buddy_idle.gif';
GIFS[1] = '/@api/deki/files/402/=buddy_sleeping.gif';
GIFS[2] = '/@api/deki/files/401/=buddy_happy.gif';
GIFS[3] = '/@api/deki/files/400/=buddy_error.gif';
GIFS[4] = '/@api/deki/files/399/=buddy_loading.gif';
var S_IDLE = 0, S_SLEEP = 1, S_HAPPY = 2, S_ERROR = 3, S_LOAD = 4, S_DIZZY = 5;
/* === SPEECH === */
var SPEECH = new Array(6);
SPEECH[0] = new Array('Bin ready!', 'Schieb mich rum!', 'Chatte mit mir!', 'Doppelklick = Chat!');
SPEECH[1] = new Array('zzz...', 'ZZzz...', '*schnarch*', 'oiiioiii...');
SPEECH[2] = new Array('So so!', 'Super!', 'Nice!', 'Toll!', 'Weiter so!');
SPEECH[3] = new Array('ALARM!', 'Oh nein!', 'Fehler!', 'Hilfe!');
SPEECH[4] = new Array('Moment...', 'Lade...', 'Gleich...', 'Bitte warten...');
SPEECH[5] = new Array('Aua mein Kopf!', 'Mir ist schwindlig!', 'Hoer auf zu schuetteln!', 'Alles dreht sich!', 'Ich seh Sterne...', 'Weniger schuetteln bitte!');
var HELLOS = new Array('Salue du!', '*kitzel*', '01001000 01101001', '*blinzel*', 'lass uns reden, doppelklick!', 'execute Order 66', 'Moin!');
/* === STATE === */
var curState = -1;
var lastAct = Date.now();
var sTimer = null;
var fadeTimer = null;
var leaving = false;
var pageError = false;
var preloading = false;
var msgTimer = null;
var clickCount = 0;
var clickTimer = null;
var pressTimer = null;
/* === DRAG STATE === */
var isDragging = false;
var wasDragged = false;
var dragStartX = 0;
var dragStartY = 0;
var dragOffsetX = 0;
var dragOffsetY = 0;
var positioned = false;
/* === SHAKE DETECTION === */
var shakeHistory = new Array();
var lastDragY = 0;
var lastDragDir = 0;
/* === DOM === */
var bWrap = document.getElementById('serverBuddy');
var bImg = document.getElementById('buddyImg');
var bSpeech = document.getElementById('buddySpeech');
if (!bWrap || !bImg || !bSpeech) return;
bWrap.style.display = 'block';
bImg.setAttribute('alt', '');
bImg.setAttribute('title', '');
bImg.setAttribute('draggable', 'false');
bImg.addEventListener('dragstart', function(e) { e.preventDefault(); });
bImg.addEventListener('contextmenu', function(e) { e.preventDefault(); });
/* === HELPERS === */
function pick(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
function isBubbleVisible() {
return bSpeech.className.indexOf('visible') !== -1;
}
function hideBubble() {
if (msgTimer) clearTimeout(msgTimer);
bSpeech.className = '';
}
function clamp(val, min, max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
/* === POSITION MANAGEMENT === */
function applyPosition(x, y) {
bWrap.style.right = 'auto';
bWrap.style.transform = 'none';
bWrap.style.left = x + 'px';
bWrap.style.top = y + 'px';
positioned = true;
updateBubblePos(x);
}
function savePosition(x, y) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({ x: x, y: y }));
} catch (e) {}
}
function loadPosition() {
try {
var data = localStorage.getItem(STORAGE_KEY);
if (!data) return null;
var pos = JSON.parse(data);
if (typeof pos.x === 'number' && typeof pos.y === 'number') {
var maxX = window.innerWidth - 96;
var maxY = window.innerHeight - 96;
return { x: clamp(pos.x, 0, maxX), y: clamp(pos.y, 0, maxY) };
}
} catch (e) {}
return null;
}
function updateBubblePos(buddyX) {
var midX = window.innerWidth / 2;
if (buddyX < midX) {
bSpeech.style.right = 'auto';
bSpeech.style.left = (buddyX + 104) + 'px';
if (bSpeech.className.indexOf('bubble-right') === -1) {
bSpeech.className = bSpeech.className.replace('bubble-right', '').replace(/\s+/g, ' ');
bSpeech.className += ' bubble-right';
}
} else {
bSpeech.style.left = 'auto';
bSpeech.style.right = (window.innerWidth - buddyX + 8) + 'px';
bSpeech.className = bSpeech.className.replace('bubble-right', '').replace(/\s+/g, ' ');
}
bSpeech.style.top = bWrap.style.top;
bSpeech.style.transform = 'translateY(-50%) scale(' + (bSpeech.className.indexOf('visible') !== -1 ? '1' : '0') + ')';
}
/* === RESTORE SAVED POSITION === */
var savedPos = loadPosition();
if (savedPos) {
applyPosition(savedPos.x, savedPos.y);
}
/* === WAKE / FADE === */
function wakeUp() {
bWrap.className = bWrap.className.replace(/\bactive\b/g, '').replace(/\s+/g, ' ');
bWrap.className += ' active';
if (fadeTimer) clearTimeout(fadeTimer);
fadeTimer = setTimeout(function() {
if (curState !== S_ERROR && curState !== S_LOAD && curState !== S_DIZZY && !preloading && !isDragging) {
bWrap.className = bWrap.className.replace(/\bactive\b/g, '').replace(/\s+/g, ' ');
}
}, FADE_SEC * 1000);
}
function showMsg(txt, duration) {
bSpeech.textContent = txt;
var cls = 'visible';
if (positioned) {
var bx = parseInt(bWrap.style.left, 10) || 0;
if (bx < window.innerWidth / 2) cls += ' bubble-right';
}
bSpeech.className = cls;
if (positioned) {
updateBubblePos(parseInt(bWrap.style.left, 10) || 0);
}
wakeUp();
if (msgTimer) clearTimeout(msgTimer);
msgTimer = setTimeout(function() {
bSpeech.className = '';
}, duration || 4000);
}
function setS(s, msg) {
if (curState === s && s !== S_HAPPY && s !== S_DIZZY) return;
curState = s;
/* dizzy uses error gif + CSS shake */
if (s === S_DIZZY) {
bImg.src = GIFS[S_ERROR];
bWrap.className = bWrap.className.replace(/\bdizzy\b/g, '');
void bWrap.offsetWidth;
bWrap.className += ' dizzy';
} else {
bImg.src = GIFS[s];
bWrap.className = bWrap.className.replace(/\bdizzy\b/g, '').replace(/\s+/g, ' ');
}
showMsg(msg || pick(SPEECH[s] || SPEECH[0]));
if (sTimer) clearTimeout(sTimer);
if (s === S_HAPPY) {
sTimer = setTimeout(function() { setS(S_IDLE); }, HAPPY_SEC * 1000);
}
if (s === S_ERROR && !pageError) {
sTimer = setTimeout(function() { setS(S_IDLE); }, ERROR_SEC * 1000);
}
if (s === S_LOAD) {
sTimer = setTimeout(function() { setS(S_HAPPY, 'Fertig!'); }, LOAD_SEC * 1000);
}
if (s === S_DIZZY) {
sTimer = setTimeout(function() {
bWrap.className = bWrap.className.replace(/\bdizzy\b/g, '').replace(/\s+/g, ' ');
setS(S_IDLE, 'Puh... besser.');
}, DIZZY_SEC * 1000);
}
}
/* === PAGE TOPIC === */
function fetchPageTopic() {
var pid = 0;
if (typeof Deki !== 'undefined' && Deki.PageId) {
pid = Deki.PageId;
}
if (!pid) return;
var url = '/@api/deki/pages/' + pid + '/properties';
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if (xhr.status !== 200) return;
try {
var parser = new DOMParser();
var xml = parser.parseFromString(xhr.responseText, 'text/xml');
var nodes = xml.getElementsByTagName('property');
var i;
for (i = 0; i < nodes.length; i++) {
var name = nodes[i].getAttribute('name') || '';
if (name.indexOf('buddy.pagetopic') !== -1) {
var contents = nodes[i].getElementsByTagName('contents');
if (contents.length > 0 && contents[0].textContent) {
var topic = contents[0].textContent.replace(/^\s+|\s+$/g, '');
if (topic) {
showMsg(topic, 8000);
}
}
break;
}
}
} catch (e) {}
};
xhr.onerror = function() {};
xhr.send();
}
/* === NAVIGATION === */
function goToChat() {
curState = -1;
setS(S_HAPPY, 'Komm mit!');
setTimeout(function() {
window.location.href = CHAT_URL;
}, 500);
}
function onSingleClick() {
if (isBubbleVisible()) {
hideBubble();
} else {
curState = -1;
setS(S_HAPPY, pick(HELLOS));
}
}
/* === IDLE === */
function resetIdle() {
lastAct = Date.now();
if (curState === S_SLEEP && !leaving && !preloading) setS(S_IDLE);
}
function checkIdle() {
if (leaving || pageError || preloading) return;
var sec = Math.floor((Date.now() - lastAct) / 1000);
if (sec >= SLEEP_SEC && curState === S_IDLE) setS(S_SLEEP);
}
/* === ERROR CHECK === */
function checkPageError() {
var errEl = document.querySelector('.errormsg.systemmsg');
var hasErr = (errEl && errEl.offsetParent !== null);
if (hasErr && !pageError) {
pageError = true;
if (sTimer) clearTimeout(sTimer);
curState = -1;
setS(S_ERROR, 'Systemfehler!');
} else if (!hasErr && pageError) {
pageError = false;
setS(S_IDLE, 'Wieder OK!');
}
}
/* === PRELOADER === */
function isPreloaderVisible() {
var pl = document.getElementById('preloader');
if (!pl) return false;
return pl.className.indexOf('show') !== -1;
}
function checkPreloader() {
var plShow = isPreloaderVisible();
if (plShow && !preloading) {
preloading = true;
wakeUp();
curState = -1;
setS(S_SLEEP, 'zzz...');
} else if (!plShow && preloading) {
preloading = false;
curState = -1;
setS(S_LOAD, 'Lade Seite...');
setTimeout(function() {
leaving = false;
setS(S_IDLE, 'Bereit!');
setTimeout(fetchPageTopic, TOPIC_DELAY * 1000);
}, 2000);
}
}
/* === DRAG & DROP === */
function getEventXY(e) {
if (e.touches && e.touches.length > 0) {
return { x: e.touches[0].clientX, y: e.touches[0].clientY };
}
return { x: e.clientX, y: e.clientY };
}
function onDragStart(e) {
if (e.button && e.button !== 0) return;
var pt = getEventXY(e);
var rect = bWrap.getBoundingClientRect();
dragStartX = pt.x;
dragStartY = pt.y;
dragOffsetX = pt.x - rect.left;
dragOffsetY = pt.y - rect.top;
isDragging = false;
wasDragged = false;
/* reset shake tracking */
shakeHistory = new Array();
lastDragY = pt.y;
lastDragDir = 0;
}
function onDragMove(e) {
if (dragOffsetX === 0 && dragOffsetY === 0) return;
var pt = getEventXY(e);
var dx = Math.abs(pt.x - dragStartX);
var dy = Math.abs(pt.y - dragStartY);
if (!isDragging && (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD)) {
isDragging = true;
wasDragged = true;
bWrap.className = bWrap.className.replace(/\bdragging\b/g, '') + ' dragging active';
hideBubble();
}
if (!isDragging) return;
e.preventDefault();
var maxX = window.innerWidth - 96;
var maxY = window.innerHeight - 96;
var nx = clamp(pt.x - dragOffsetX, 0, maxX);
var ny = clamp(pt.y - dragOffsetY, 0, maxY);
applyPosition(nx, ny);
/* === SHAKE DETECTION (Y-axis direction changes) === */
var deltaY = pt.y - lastDragY;
if (Math.abs(deltaY) > SHAKE_MIN_DIST) {
var dir = deltaY > 0 ? 1 : -1;
if (lastDragDir !== 0 && dir !== lastDragDir) {
shakeHistory.push(Date.now());
}
lastDragDir = dir;
lastDragY = pt.y;
}
/* clean old entries */
var now = Date.now();
var cleaned = new Array();
var si;
for (si = 0; si < shakeHistory.length; si++) {
if (now - shakeHistory[si] < SHAKE_WINDOW) {
cleaned.push(shakeHistory[si]);
}
}
shakeHistory = cleaned;
if (shakeHistory.length >= SHAKE_THRESHOLD) {
shakeHistory = new Array();
if (curState !== S_DIZZY) {
curState = -1;
setS(S_DIZZY);
}
}
}
function onDragEnd(e) {
if (isDragging) {
var rect = bWrap.getBoundingClientRect();
savePosition(rect.left, rect.top);
}
bWrap.className = bWrap.className.replace(/\bdragging\b/g, '').replace(/\s+/g, ' ');
isDragging = false;
dragOffsetX = 0;
dragOffsetY = 0;
shakeHistory = new Array();
lastDragDir = 0;
}
/* mouse drag */
bWrap.addEventListener('mousedown', function(e) {
onDragStart(e);
/* long press for chat */
pressTimer = setTimeout(function() {
if (!wasDragged) goToChat();
}, 800);
});
document.addEventListener('mousemove', function(e) { onDragMove(e); });
document.addEventListener('mouseup', function(e) {
if (pressTimer) clearTimeout(pressTimer);
onDragEnd(e);
});
/* touch drag */
bWrap.addEventListener('touchstart', function(e) {
onDragStart(e);
pressTimer = setTimeout(function() {
if (!wasDragged) {
e.preventDefault();
goToChat();
}
}, 800);
}, { passive: false });
document.addEventListener('touchmove', function(e) {
if (isDragging) onDragMove(e);
}, { passive: false });
document.addEventListener('touchend', function(e) {
if (pressTimer) clearTimeout(pressTimer);
onDragEnd(e);
});
bWrap.addEventListener('touchmove', function() {
if (pressTimer) clearTimeout(pressTimer);
});
/* === IDLE TRACKERS === */
document.addEventListener('mousemove', resetIdle);
document.addEventListener('scroll', resetIdle);
document.addEventListener('keydown', resetIdle);
document.addEventListener('touchstart', resetIdle);
bWrap.addEventListener('mouseenter', function() { wakeUp(); });
bWrap.addEventListener('mouseleave', function() {
if (pressTimer) clearTimeout(pressTimer);
});
/* === LINK CLICKS === */
document.addEventListener('click', function(e) {
resetIdle();
var t = e.target;
var link = null;
if (t.tagName === 'A') {
link = t;
} else if (t.parentNode && t.parentNode.tagName === 'A') {
link = t.parentNode;
}
if (link) {
var href = link.getAttribute('href') || '';
if (href && href.charAt(0) !== '#' && href.indexOf('javascript:') !== 0) {
leaving = true;
curState = -1;
setS(S_SLEEP, 'Bis gleich...');
} else {
setS(S_HAPPY);
}
}
});
window.addEventListener('beforeunload', function() {
leaving = true;
bImg.src = GIFS[S_SLEEP];
});
/* === CLICK: single = dismiss/greet, double = chat === */
bWrap.addEventListener('click', function(e) {
e.stopPropagation();
e.preventDefault();
if (wasDragged) {
wasDragged = false;
return;
}
clickCount++;
if (clickCount === 1) {
clickTimer = setTimeout(function() {
clickCount = 0;
onSingleClick();
}, 350);
} else if (clickCount === 2) {
clearTimeout(clickTimer);
clickCount = 0;
goToChat();
}
});
/* === GLOBAL ERRORS === */
window.addEventListener('error', function() { setS(S_ERROR); });
/* === VISIBILITY === */
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
setS(S_SLEEP, '*gaehn*');
} else {
leaving = false;
resetIdle();
setS(S_IDLE, 'Wieder da!');
}
});
/* === WINDOW RESIZE: keep buddy in bounds === */
window.addEventListener('resize', function() {
if (!positioned) return;
var cx = parseInt(bWrap.style.left, 10) || 0;
var cy = parseInt(bWrap.style.top, 10) || 0;
var maxX = window.innerWidth - 96;
var maxY = window.innerHeight - 96;
var nx = clamp(cx, 0, maxX);
var ny = clamp(cy, 0, maxY);
applyPosition(nx, ny);
savePosition(nx, ny);
});
/* === PRELOAD GIFS === */
var i;
for (i = 0; i < 5; i++) {
var preImg = new Image();
preImg.src = GIFS[i];
}
/* === INIT === */
if (isPreloaderVisible()) {
preloading = true;
wakeUp();
setS(S_SLEEP, 'zzz...');
} else {
setS(S_LOAD, 'Lade Seite...');
setTimeout(function() {
leaving = false;
setS(S_IDLE, 'Bereit!');
setTimeout(fetchPageTopic, TOPIC_DELAY * 1000);
}, 2000);
}
setInterval(checkIdle, 1000);
setInterval(checkPageError, 1000);
setInterval(checkPreloader, 300);
/* === HEADER HOVER FACTS === */
var headerFacts = new Object();
var hf = headerFacts;
hf['Charles Babbage'] = new Array(
'Der Urvater aller Computer! Hat die Analytical Engine nie fertig gebaut. Kennen wir das nicht alle?',
'Babbage hasste Strassenmusikanten. Haette er Slack-Notifications erlebt...',
'Fun fact: Die britische Regierung gab ihm 17000 Pfund. Das waere heute ueber 3 Millionen!'
);
hf['Ada Lovelace'] = new Array(
'Die erste Programmiererin der Welt! Und das ohne Stack Overflow.',
'Ada schrieb den ersten Algorithmus bevor es Computer gab. Talk about early adopter!',
'Tochter von Lord Byron. Poesie und Code liegen naeher als man denkt.'
);
hf['Konrad Zuse'] = new Array(
'Z3: Der erste funktionierende Computer der Welt. Made in Germany!',
'Zuse hat nebenbei auch die erste hoehere Programmiersprache erfunden: Plankalkuel.',
'Er baute den Z1 im Wohnzimmer seiner Eltern. Der erste Nerd-Keller war ein Wohnzimmer.'
);
hf['Howard Aiken'] = new Array(
'Harvard Mark I: 16 Meter lang, 5 Tonnen schwer. Und weniger Rechenpower als deine Smartwatch.',
'Aiken sagte: Die Welt braucht vielleicht 5 Computer. Ups.',
'Der Mark I klang wie eine Naehfabrik. Noise-Cancelling gabs noch nicht.'
);
hf['Alan Turing'] = new Array(
'Hat den Enigma-Code geknackt und den Krieg verkuerzt. Nicht schlecht fuer einen Mathematiker.',
'Der Turing-Test: Kann eine Maschine denken? Frag mich nochmal in 10 Jahren.',
'Turing liebte Langstreckenlaeufe. Debug-Methode: Rennen bis die Loesung kommt.'
);
hf['John von Neumann'] = new Array(
'Die Von-Neumann-Architektur: Jeder Computer den du je benutzt hast basiert darauf.',
'Er konnte ganze Buecher auswendig zitieren. Menschliches RAM auf Maximum.',
'Von Neumann rechnete schneller im Kopf als fruehere Computer. Kein Witz.'
);
hf['Steve Jobs bis 1976'] = new Array(
'Apple wurde in einer Garage gegruendet. Jedes Startup braucht eine Origin-Story.',
'Jobs war barfuss bei wichtigen Meetings. Der erste Casual Friday.',
'Er ging nach Indien um sich selbst zu finden. Kam zurueck und erfand Apple.'
);
hf['IBM PC 5150'] = new Array(
'Der IBM PC: 4.77 MHz, 16 KB RAM. Dein Browser-Tab braucht heute mehr.',
'1981 kostete er 1565 Dollar. Inflation-bereinigt ca. 5000 Dollar. Fuer 16 KB RAM!',
'IBM dachte PCs waeren ein Nischenprodukt. Klassischer Management-Move.'
);
hf['Apple II'] = new Array(
'Der Apple II: Erster Computer mit Farbgrafik fuer zuhause. Revolution!',
'Wozniak hat den Apple II quasi alleine designed. Jobs hat ihn verkauft.',
'VisiCalc auf dem Apple II war die erste Killer-App. Excel-Urahn!'
);
hf['Steve Jobs bis 1985'] = new Array(
'Von Apple gefeuert. Von der eigenen Firma. Das muss man erstmal schaffen.',
'Jobs Reality Distortion Field: Er konnte dich ueberzeugen dass schwarz weiss ist.',
'Nach Apple gruendete er NeXT. Spoiler: Er kommt zurueck.'
);
hf['Diskette'] = new Array(
'Speichern-Icon bis heute! Kinder fragen: Was ist dieses 3D-gedruckte Save-Symbol?',
'1.44 MB. Da passt nicht mal ein Handyfoto drauf.',
'Das befriedigende Klick-Geraeusch beim Einschieben. ASMR der 90er.'
);
hf['Game Boy'] = new Array(
'Tetris auf dem Game Boy: Produktivitaetskiller seit 1989.',
'Der Game Boy ueberlebte einen Bombenangriff im Golfkrieg. Nokia-Level Haerte.',
'118 Millionen Stueck verkauft. Und alle spielten Tetris.'
);
hf['NeXTstation'] = new Array(
'Tim Berners-Lee erfand das Web auf einem NeXT. Danke, Steve!',
'Der NeXT-Wuerfel kostete 6500 Dollar. Design hat seinen Preis.',
'NeXTSTEP wurde zu macOS. Die beste Rache ist Erfolg.'
);
hf['CD-ROM'] = new Array(
'700 MB! Das war mal unvorstellbar viel Speicher.',
'Bitte nicht die glaenzende Seite anfassen. BITTE!',
'AOL-CDs als Untersetzer. Recycling der 90er.'
);
hf['Netscape Navigator'] = new Array(
'Netscape: Der Browser der das Internet populaer machte. RIP.',
'Der Browserkrieg hat begonnen! Netscape vs. Microsoft, Runde 1.',
'Aus Netscape wurde Mozilla Firefox. Der Phoenix aus der Asche!'
);
hf['Internet Explorer'] = new Array(
'Internet Explorer: Nur genutzt um einen anderen Browser runterzuladen.',
'IE6 hat eine ganze Generation von Webentwicklern traumatisiert.',
'Ruhe in Frieden, IE. Du warst... ein Browser. Irgendwie.'
);
hf['Bill Gates'] = new Array(
'640 KB sollten fuer jeden reichen. Legendaeres Fehlzitat!',
'Von Harvard abgebrochen. Eltern hassen diesen Trick.',
'Ctrl+Alt+Delete war ein Fehler, sagt er selbst. Wenigstens ehrlich.'
);
hf['DVD und Blu-ray'] = new Array(
'DVD: Rewind war gestern! Aber Regionalcodes waren die neue Nerverei.',
'Blu-ray vs HD-DVD: Der letzte grosse Formatkrieg.',
'Wer hat noch eine DVD-Sammlung im Regal? Sei ehrlich.'
);
hf['Geschichte von Linux'] = new Array(
'Linus Torvalds: "Ich mache ein freies Betriebssystem. Wird wohl nichts Grosses."',
'Linux laeuft auf Supercomputern, Handys, Kuehlschraenken und dem Mars-Rover!',
'BTW, I use Arch. Der Veganer-Spruch der IT.'
);
hf['List of Linux distributions'] = new Array(
'Es gibt ueber 600 Linux-Distros. Fuer jedes Problem eine eigene Distribution.',
'Ubuntu, Debian, Arch, Fedora, Mint... Die Qual der Wahl.',
'Jeder Linux-User hat schon 3x die Distro gewechselt. Mindestens.'
);
hf['Handheld'] = new Array(
'Von Handhelds zu Smartphones. Die Evolution der Ablenkung.',
'Palm Pilot! Wer erinnert sich an Graffiti-Schrifterkennung?',
'Handhelds: Als Taschencomputer noch eine eigene Kategorie waren.'
);
hf['Personal Digital Assistant'] = new Array(
'PDA: Personal Digital Assistant. Heute sagt man einfach Handy.',
'Mit dem Stylus auf dem PDA tippen. Das war Premium-UX!',
'Newton MessagePad: Apples erster Flop. Oder seiner Zeit voraus?'
);
hf['Google'] = new Array(
'Googles erster Server war in Lego-Steinen eingebaut. Kein Witz!',
'Googles erstes Buero: Eine Garage. Schon wieder eine Garage.',
'"Don\'t be evil" hiess es mal. Heute heisst es... naja.'
);
hf['Notebook'] = new Array(
'Vom 10-Kilo-Laptop zum Ultrabook. Unsere Rucksaecke danken es.',
'Erster Laptop: Osborne 1, 1981. 11 Kilo. Armtraining inklusive.',
'Laptop im Bett: Modernes Lagerfeuer fuer digitale Nomaden.'
);
hf['USB-Stick'] = new Array(
'USB: Braucht immer 3 Versuche zum Einstecken. Immer.',
'USB-C: Endlich egal welche Seite! Nur 20 Jahre hat es gedauert.',
'Wer hat nicht mindestens 5 USB-Sticks in der Schublade liegen?'
);
hf['Youtube'] = new Array(
'Erstes Youtube-Video: "Me at the zoo". 19 Sekunden die alles aenderten.',
'Youtube frisst mehr Bandbreite als TV. Die Zukunft ist hier.',
'Katzenvideos: Der wahre Grund warum das Internet erfunden wurde.'
);
hf['Tim Berners-Lee'] = new Array(
'Hat das World Wide Web erfunden. Und nie Milliarden damit verdient. Respekt!',
'Erster Webserver lief auf einem NeXT-Wuerfel. Mit einem Zettel: "Nicht ausschalten!"',
'Ohne ihn waerst du jetzt nicht hier. Danke, Tim!'
);
hf['Containervirtualisierung'] = new Array(
'Docker: Funktioniert auf meinem Computer! Endlich auch auf deinem.',
'Container sind wie Schiffscontainer: Alles drin, ueberall einsetzbar.',
'kubectl get pods: Der Befehl der DevOps-Engineers nicht schlafen laesst.'
);
hf['Smartphone OS'] = new Array(
'Android vs iOS: Der ewige Glaubenskrieg. Schlimmer als Tabs vs Spaces.',
'Es gab mal Windows Phone. Moment der Stille bitte.',
'Dein Smartphone hat mehr Power als die Apollo-11-Rakete. Und du spielst Candy Crush.'
);
hf['SaaS'] = new Array(
'Software as a Service: Frueher kaufte man Software. Heute mietet man sie. Fuer immer.',
'SaaS: Wo jede App ein monatliches Abo ist. Dein Konto weint leise.',
'Die Cloud ist nur der Computer von jemand anderem. Romantisch, oder?'
);
hf['Cloud Computing'] = new Array(
'Die Cloud: Klingt fluffy, ist ein riesiges Rechenzentrum irgendwo in Irland.',
'Cloud Computing: Weil "anderer-Leute-Computer" nicht so cool klingt.',
'Frueher hatte man Server im Keller. Jetzt hat Amazon sie. Fortschritt?'
);
var hoverCooldown = false;
var areas = document.querySelectorAll('area[title]');
var ai;
for (ai = 0; ai < areas.length; ai++) {
(function(area) {
area.addEventListener('mouseenter', function() {
if (hoverCooldown) return;
var title = area.getAttribute('title') || '';
var facts = headerFacts[title];
if (!facts) return;
hoverCooldown = true;
curState = -1;
setS(S_HAPPY);
showMsg(pick(facts), 6000);
setTimeout(function() { hoverCooldown = false; }, 4000);
});
})(areas[ai]);
}
/* === PUBLIC API === */
window.serverBuddy = new Object();
window.serverBuddy.setState = function(name, msg) {
var map = new Object();
map['idle'] = 0; map['sleeping'] = 1; map['happy'] = 2;
map['error'] = 3; map['loading'] = 4; map['dizzy'] = 5;
if (map[name] !== undefined) setS(map[name], msg);
};
window.serverBuddy.say = showMsg;
window.serverBuddy.moveTo = function(x, y) {
applyPosition(x, y);
savePosition(x, y);
};
window.serverBuddy.resetPosition = function() {
try { localStorage.removeItem(STORAGE_KEY); } catch(e) {}
positioned = false;
bWrap.style.left = '';
bWrap.style.top = '';
bWrap.style.right = '16px';
bWrap.style.transform = 'translateY(-50%)';
bSpeech.style.left = '';
bSpeech.style.right = '120px';
bSpeech.style.top = '50%';
};
})();