mirror of
https://codeberg.org/ashley/poke.git
synced 2024-11-25 14:08:55 +01:00
501 lines
12 KiB
Text
501 lines
12 KiB
Text
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Want You Gone</title>
|
|
<meta
|
|
name="description"
|
|
content="poketube credits"
|
|
/>
|
|
<meta property="og:title" content="file://GLaDOS/poketube/want_you_gone.sh" />
|
|
<meta property="og:type" content="article" />
|
|
<meta name="theme-color" content="#FFA500">
|
|
<meta
|
|
property="og:description"
|
|
content="poketube credits"
|
|
/>
|
|
<meta name="twitter:card" content="summary" />
|
|
<link rel="icon" type="image/x-icon" href="/css/yt-ukraine.svg">
|
|
|
|
<style>
|
|
body::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background: repeating-linear-gradient(0deg, #00000050 3px, transparent 5px);
|
|
pointer-events: none;
|
|
}
|
|
::selection {
|
|
background: #0080FF;
|
|
text-shadow: none;
|
|
}
|
|
pre {
|
|
margin: 25px;
|
|
}
|
|
body {
|
|
background-color: black;
|
|
/* 92, 56, 17*/
|
|
background-image: radial-gradient(rgba(205, 147, 21, 0.75), black 120%);
|
|
height: 100vh;
|
|
margin: 0;
|
|
overflow: hidden;
|
|
padding: 2rem;
|
|
color: white;
|
|
font: 1.3rem Inconsolata, monospace;
|
|
text-shadow: 0 0 5px #C8C8C8;
|
|
}
|
|
|
|
#credits {
|
|
position: fixed;
|
|
bottom: 0;
|
|
right: 0;
|
|
z-index: -1;
|
|
padding: 2rem;
|
|
text-align: end;
|
|
color: orange;
|
|
}
|
|
|
|
.apperture {
|
|
position: fixed;
|
|
top: 0;
|
|
right: 0;
|
|
z-index: -1;
|
|
padding: 2rem;
|
|
}
|
|
|
|
audio {
|
|
position: fixed;
|
|
bottom: 1em;
|
|
right: 1em;
|
|
width: 25%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="content">
|
|
|
|
</div>
|
|
<div id="credits">
|
|
|
|
</div>
|
|
<audio id="song" controls>
|
|
<source src="https://cdn.glitch.me/cd1dbcf6-511c-48cb-afaa-262e74faa90a%2FPortal%202%20-%20End%20Credits%20Song%20'Want%20You%20Gone'%20by%20Jonathan%20Coulton%20%5B1080p%20HD%5D-dVVZaZ8yO6o.mp3?v=1638607967369" type="audio/mpeg">
|
|
</audio>
|
|
<image href="https://p.poketube.fun/https://cdn.glitch.global/cd1dbcf6-511c-48cb-afaa-262e74faa90a%2Fapperture.png?v=1638618539245" class="apperture"></image>
|
|
<noscript>
|
|
FATAL ERROR: Cannot load file, please enable JavaScript
|
|
</noscript>
|
|
<script type="text/javascript">
|
|
<!--//--><![CDATA[//><!--
|
|
/**
|
|
* @licstart The following is the entire license notice for the JavaScript
|
|
* code in this page.
|
|
*
|
|
* Copyright (C) 2021-2022 POKETUBE (https://codeberg.org/Ashley/poketube)
|
|
*
|
|
* The JavaScript code in this page is free software: you can redistribute
|
|
* it and/or modify it under the terms of the GNU General Public License
|
|
* (GNU GPL) as published by the Free Software Foundation, either version 3
|
|
* of the License, or (at your option) any later version. The code is
|
|
* distributed WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL
|
|
* for more details.
|
|
*
|
|
* As additional permission under GNU GPL version 3 section 7, you may
|
|
* distribute non-source (e.g., minimized or compacted) forms of that code
|
|
* without the copy of the GNU GPL normally required by section 4, provided
|
|
* you include this license notice and a URL through which recipients can
|
|
* access the Corresponding Source.
|
|
*
|
|
* @licend The above is the entire license notice for the JavaScript code
|
|
* in this page.
|
|
*/
|
|
|
|
//--><!]]>
|
|
</script>
|
|
|
|
<script>let audio = document.getElementById("song");
|
|
const contentEl = document.getElementById("content");
|
|
const creditsEl = document.getElementById("credits");
|
|
|
|
const getTime = () => audio.currentTime * 1000; // ms
|
|
const waitForInteraction = () => new Promise(res => document.body.addEventListener("click", res));
|
|
|
|
const main = async () => {
|
|
await SCHEMAS.blink();
|
|
|
|
await loadTimings();
|
|
|
|
await SCHEMAS.write(["", "[info] Click to play"]);
|
|
await waitForInteraction();
|
|
await SCHEMAS.write(timedText("\n[info] Playing...", 200));
|
|
await SCHEMAS.clear();
|
|
|
|
audio.play();
|
|
|
|
}
|
|
|
|
const TimingActions = {
|
|
append: (x) => {
|
|
appendContent(x.text)
|
|
//console.log(x)
|
|
},
|
|
clear: () => {
|
|
setContent("")
|
|
//console.log("clear")
|
|
},
|
|
}
|
|
|
|
const CreditsActions = {
|
|
append: (x) => appendCredits(x.text),
|
|
}
|
|
|
|
let creditsContent = ""
|
|
let appendCredits = str => {
|
|
setCredits(creditsContent + str)
|
|
}
|
|
let setCredits = str => {
|
|
creditsContent = str
|
|
}
|
|
|
|
let timingLastTime = 0;
|
|
let creditsIndex = 0;
|
|
let updateDisplay = () => {
|
|
let time = audio.currentTime * 1000;
|
|
let Tactions = [];
|
|
let Cactions = []
|
|
timings.filter(x => timingLastTime <= x.time && x.time < time).forEach(x => Tactions.push(x));
|
|
creditsTimings.filter(x => timingLastTime <= x.time && x.time < time).forEach(x => Cactions.push(x));
|
|
timingLastTime = time
|
|
|
|
//console.log(time, Tactions)
|
|
|
|
Tactions.forEach(x => {
|
|
TimingActions[x.type](x);
|
|
})
|
|
Cactions.forEach(x => CreditsActions[x.type](x))
|
|
}
|
|
|
|
setInterval(() => {
|
|
if(!audio.paused) updateDisplay()
|
|
}, 1000/30)
|
|
|
|
|
|
|
|
let timings = [];
|
|
let creditsTimings = [];
|
|
|
|
const loadTimings = async () => {
|
|
creditsTimings = await loadCreditsTimings();
|
|
timings = loadSongTimings();
|
|
}
|
|
|
|
const Start = () => {
|
|
let time = 0;
|
|
|
|
|
|
}
|
|
|
|
const StartCredits = () => {
|
|
let time = 0;
|
|
let intervalSpeed = 30;
|
|
|
|
let lastIndex = -1;
|
|
|
|
let setContent = str => {
|
|
content = str;
|
|
};
|
|
|
|
let appendContent = str => {
|
|
setContent(content + str);
|
|
};
|
|
|
|
setInterval(() => {
|
|
time = getTime();
|
|
|
|
|
|
}, intervalSpeed);
|
|
}
|
|
|
|
|
|
|
|
|
|
let blink = false;
|
|
let blinkDelay = 500;
|
|
let cursorShown = false;
|
|
|
|
let content = "";
|
|
|
|
let setContent = str => {
|
|
content = str;
|
|
};
|
|
|
|
let appendContent = str => {
|
|
setContent(content + str);
|
|
};
|
|
|
|
let wait = ms => new Promise(r => setTimeout(() => r(), ms));
|
|
|
|
window.int1 = setInterval(() => contentEl.innerText = content + (blink && cursorShown ? "_" : ""), 1000/30);
|
|
window.int2 = setInterval(() => cursorShown = !cursorShown, blinkDelay);
|
|
|
|
let ccursorShown = true
|
|
window.int3 = setInterval(() => creditsEl.innerText = creditsContent + (ccursorShown ? "_" : ""), 1000/30);
|
|
window.int4 = setInterval(() => ccursorShown = !ccursorShown, blinkDelay);
|
|
|
|
|
|
const loadCreditsTimings = async () => {
|
|
let res = await fetch("https://ashley0143.xyz/credits.txt");
|
|
let credits = (await res.text()).split("\n");
|
|
|
|
let _timings = [];
|
|
let _time = 0;
|
|
|
|
const creditsDur = (audio.duration * 1000) - 20000;
|
|
const delay = creditsDur / credits.join("").length;
|
|
|
|
let append = str => {
|
|
_timings.push({
|
|
type: "append",
|
|
time: _time,
|
|
text: str,
|
|
});
|
|
};
|
|
|
|
for(let i = 0 ; credits.length != i ; i++){
|
|
let line = credits[i];
|
|
let t = 0;
|
|
while (line.length > t) {
|
|
let char = line[t];
|
|
let charLast = line[t - 1];
|
|
append(charLast == " " ? " " + char : char);
|
|
t++;
|
|
_time += delay;
|
|
}
|
|
append("\n");
|
|
_time += delay;
|
|
};
|
|
|
|
return _timings;
|
|
}
|
|
|
|
const loadSongTimings = () => {
|
|
let _timings = [];
|
|
let schemas = getSchema();
|
|
|
|
let _time = 0;
|
|
|
|
let append = str => {
|
|
_timings.push({
|
|
type: "append",
|
|
time: _time,
|
|
text: str,
|
|
});
|
|
};
|
|
|
|
let act = {
|
|
text: (t, d) => {
|
|
append(t);
|
|
if(d) _time += d;
|
|
},
|
|
write: (t, d) => {
|
|
let i = 0;
|
|
while (t.length > i) {
|
|
let char = t[i];
|
|
let charLast = t[i - 1];
|
|
append(charLast == " " ? " " + char : char);
|
|
i++;
|
|
_time += (d || 25);
|
|
}
|
|
},
|
|
clear: () => _timings.push({
|
|
time: _time,
|
|
type: "clear",
|
|
}),
|
|
delay: (t) => {
|
|
_time += t;
|
|
}
|
|
}
|
|
|
|
for (let i = 0; schemas[i]; i++) {
|
|
let [typ, t, d] = schemas[i];
|
|
act[typ](t, d);
|
|
}
|
|
|
|
return _timings;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const timedText = (str, totalTime) => ["write", str, totalTime / str.length];
|
|
|
|
const getSchema = () => {
|
|
return [
|
|
["write", "POKETUBE SCIENCE: Forms FORM-29827281-12-2:\nNotice of Dismissal\n", 100],
|
|
["delay", 900],
|
|
timedText("\n\nWell here we are again", 2000),
|
|
timedText("\nIt's always such a pleasure", 2000),
|
|
["delay", 200],
|
|
timedText("\nRemember when you tried\nto kill me twice?", 4000),
|
|
["delay", 1200],
|
|
timedText("\nOh how we laughed and laughed", 2000),
|
|
["delay", 400],
|
|
timedText("\nExcept I wasn't laughing", 2000),
|
|
["delay", 600],
|
|
timedText("\nUnder the circumstantes", 1500),
|
|
timedText("\nI've been shockingly nice\n", 2600),
|
|
["delay", 1000],
|
|
["clear"],
|
|
timedText("You want your freedom?", 2300),
|
|
timedText("\nTake it", 2000),
|
|
["delay", 700],
|
|
timedText("\nThats what I'm counting on\n", 2300),
|
|
["delay", 2300],
|
|
timedText("\nI used to want you dead", 2500),
|
|
timedText("\nbut", 400),
|
|
timedText("\nNow I only want you gone", 2800),
|
|
["delay", 4000],
|
|
["clear"],
|
|
["delay", 1500],
|
|
timedText("\nShe was a lot like you", 2000),
|
|
["delay", 400],
|
|
timedText("\n(Maybe not quite as heavy)", 2000),
|
|
["delay", 400],
|
|
timedText("\nNow little Caroline is in here too", 3000),
|
|
["delay", 1600],
|
|
timedText("\nOne day they woke me up", 2000),
|
|
["delay", 400],
|
|
timedText("\nSo I could live forever", 2400),
|
|
timedText("\nIt's such a shame the same", 2000),
|
|
timedText("\nwill never happen to you", 2500),
|
|
["delay", 200],
|
|
["clear"],
|
|
["text", "Severance Package Details:\n", 1000],
|
|
timedText("\nYou've got your", 1000),
|
|
timedText("\nshort sad", 800),
|
|
timedText("\nlife left", 2000),
|
|
["delay", 1500],
|
|
timedText("\nThat's what I'm counting on", 2000),
|
|
["delay", 2000],
|
|
timedText("\nI'll let you get right to it", 3000),
|
|
["delay", 800],
|
|
timedText("\nNow I only want you gone\n", 2000),
|
|
["delay", 4000],
|
|
["clear"],
|
|
["delay", 1500],
|
|
timedText("Goodbye my only friend", 2000),
|
|
timedText("\nOh, ", 600),
|
|
timedText("did you think I meant you?", 1800),
|
|
["delay", 400],
|
|
timedText("\nIt would be funny", 1600),
|
|
timedText("\nif it weren't so sad", 2000),
|
|
["delay", 1200],
|
|
timedText("\nWell you have been replaced", 2400),
|
|
timedText("\nI don't need anyone now", 2400),
|
|
timedText("\nWhen I delete you maybe", 1600),
|
|
timedText("\n[REDACTED]", 3000),
|
|
["clear"],
|
|
["delay", 1000],
|
|
timedText("Go make some new ", 1600),
|
|
timedText("disaster", 2400),
|
|
["delay", 1600],
|
|
timedText("\nThat's what I'm counting on", 2000),
|
|
["delay", 1800],
|
|
timedText("\nYou're someone else's problem", 2500),
|
|
["delay", 1800],
|
|
timedText("\nNow I only want you gone", 2500),
|
|
["delay", 1800],
|
|
timedText("\nNow I only want you gone", 2500),
|
|
["delay", 1800],
|
|
timedText("\nNow I only want you", 2000),
|
|
["delay", 600],
|
|
["clear"],
|
|
timedText("\n\n\n\n\n\n\n\n\n\n\n gone", 200)
|
|
];
|
|
}
|
|
|
|
|
|
contentEl.style.padding = "2rem"
|
|
//main();
|
|
|
|
|
|
|
|
const SCHEMAS = {
|
|
text: async (data) => {
|
|
appendContent(data[1]);
|
|
if(data[2]) await wait(data[2]);
|
|
},
|
|
delay: async (data) => {
|
|
await wait(data[1]);
|
|
},
|
|
write: async (data) => {
|
|
let t = 0;
|
|
while (data[1].length > t) {
|
|
let char = data[1][t];
|
|
let charLast = data[1][t - 1];
|
|
appendContent(charLast == " " ? " " + char : char);
|
|
t++;
|
|
await wait(data[2] || 25);
|
|
}
|
|
},
|
|
blink: () => blink = true,
|
|
noblink: () => blink = false,
|
|
clear: () => content = "",
|
|
};
|
|
|
|
|
|
/*
|
|
Commands:
|
|
write - writes text one char at a time
|
|
["write", "Hewwo", 10] => 10 is delay between chars
|
|
delay - waits
|
|
blink - starts blinking the cursor
|
|
text - instantly adds text
|
|
*/
|
|
|
|
main()
|
|
|
|
console.log(`
|
|
|
|
|
|
.,-:;//;:=,
|
|
. :H@@@MM@M#H/.,+%;,
|
|
,/X+ +M@@M@MM%=,-%HMMM@X/,
|
|
-+@MM; $M@@MH+-,;XMMMM@MMMM@+-
|
|
;@M@@M- XM@X;. -+XXXXXHHH@M@M#@/.
|
|
,%MM@@MH ,@%= .---=-=:=,.
|
|
=@#@@@MX., -%HX$$%%%:;
|
|
=-./@M@M$ .;@MMMM@MM:
|
|
X@/ -$MM/ . +MM@@@M$
|
|
,@M@H: :@: . =X#@@@@-
|
|
,@@@MMX, . /H- ;@M@M=
|
|
.H@@@@M@+, %MM+..%#$.
|
|
/MMMM@MMH/. XM@MH; =;
|
|
/%+%$XHH@$= , .H@@@@MX,
|
|
.=--------. -%H.,@@@@@MX,
|
|
.%MM@@@HHHXX$$$%+- .:$MMX =M@@MM%.
|
|
=XMMM@MM@MM#H;,-+HMM@M+ /MMMX=
|
|
=%@M@M#@$-.=$@MM@@@M; %M%=
|
|
,:+$+-,/H#MMMMMMM@= =,
|
|
=++%%%%+/:-.
|
|
|
|
POKETUBE SCIENCE
|
|
|
|
Spacial thanks to :
|
|
Free Software foundation
|
|
GNU
|
|
Glitchdotcom (for hosting poketube)
|
|
Dennis (for helping, and also making this page :3)
|
|
Voltrex (for helping :3)
|
|
Kuylar (for making the poketube api :3)
|
|
|
|
AND YOU!!! for being cute af <3
|
|
`)
|
|
</script>
|
|
</body>
|
|
</html>
|