update build.js
This commit is contained in:
parent
384a0bd111
commit
abc2b9f2fa
336
public/bundle.js
336
public/bundle.js
|
|
@ -1,5 +1,5 @@
|
||||||
////
|
////
|
||||||
// version: 7d7febe
|
// version: 384a0bd
|
||||||
|
|
||||||
// src/js/dom.ts
|
// src/js/dom.ts
|
||||||
var content2 = $("content");
|
var content2 = $("content");
|
||||||
|
|
@ -24,28 +24,26 @@ var $$ = (tag, innerHTML = "") => {
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
|
|
||||||
// src/js/resize.ts
|
// src/js/focus.ts
|
||||||
var content3 = document.getElementById("content");
|
function initFocus() {
|
||||||
function initResize() {
|
window.addEventListener("click", focusHandler);
|
||||||
window.addEventListener("resize", resize);
|
focusInput();
|
||||||
resize();
|
|
||||||
}
|
}
|
||||||
function resize() {
|
function focusInput() {
|
||||||
if (document.body.dataset.mode === "tall") {
|
cmdInput.focus();
|
||||||
resizeTall();
|
}
|
||||||
} else {
|
function focusHandler(e) {
|
||||||
resizeCinema();
|
const target = e.target;
|
||||||
|
if (!(target instanceof HTMLElement)) {
|
||||||
|
focusInput();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
if (["INPUT", "TEXTAREA", "CANVAS", "A"].includes(target.tagName))
|
||||||
function resizeTall() {
|
return false;
|
||||||
const scale = Math.min(1, window.innerWidth / 960);
|
const selection = window.getSelection() || "";
|
||||||
content3.style.transformOrigin = "top center";
|
if (selection.toString() === "")
|
||||||
content3.style.transform = `scaleX(${scale})`;
|
focusInput();
|
||||||
}
|
e.preventDefault();
|
||||||
function resizeCinema() {
|
|
||||||
const scale = Math.min(window.innerWidth / 960, window.innerHeight / 540);
|
|
||||||
content3.style.transformOrigin = "center center";
|
|
||||||
content3.style.transform = `scale(${scale})`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/shared/utils.ts
|
// src/shared/utils.ts
|
||||||
|
|
@ -54,18 +52,23 @@ function randomId() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/js/scrollback.ts
|
// src/js/scrollback.ts
|
||||||
|
var statusColors = {
|
||||||
|
waiting: "yellow",
|
||||||
|
streaming: "purple",
|
||||||
|
ok: "green",
|
||||||
|
error: "red"
|
||||||
|
};
|
||||||
function initScrollback() {
|
function initScrollback() {
|
||||||
window.addEventListener("click", handleInputClick);
|
window.addEventListener("click", handleInputClick);
|
||||||
}
|
}
|
||||||
function autoScroll() {}
|
|
||||||
function insert(node) {
|
function insert(node) {
|
||||||
scrollback.append(node);
|
scrollback.append(node);
|
||||||
}
|
}
|
||||||
function addInput(id, input) {
|
function addInput(id, input, status) {
|
||||||
const parent = $$("li.input");
|
const parent = $$("li.input");
|
||||||
const status = $$("span.status.yellow", "•");
|
const statusSpan = $$(`span.status.${statusColors[status || "waiting"]}`, "•");
|
||||||
const content4 = $$("span.content", input);
|
const content3 = $$("span.content", input);
|
||||||
parent.append(status, content4);
|
parent.append(statusSpan, content3);
|
||||||
parent.dataset.id = id;
|
parent.dataset.id = id;
|
||||||
insert(parent);
|
insert(parent);
|
||||||
scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight;
|
scrollback.scrollTop = scrollback.scrollHeight - scrollback.clientHeight;
|
||||||
|
|
@ -74,31 +77,24 @@ function setStatus(id, status) {
|
||||||
const statusEl = document.querySelector(`[data-id="${id}"].input .status`);
|
const statusEl = document.querySelector(`[data-id="${id}"].input .status`);
|
||||||
if (!statusEl)
|
if (!statusEl)
|
||||||
return;
|
return;
|
||||||
const colors = {
|
statusEl.classList.remove(...Object.values(statusColors));
|
||||||
waiting: "yellow",
|
statusEl.classList.add(statusColors[status]);
|
||||||
streaming: "purple",
|
|
||||||
ok: "green",
|
|
||||||
error: "red"
|
|
||||||
};
|
|
||||||
statusEl.classList.remove(...Object.values(colors));
|
|
||||||
statusEl.classList.add(colors[status]);
|
|
||||||
}
|
}
|
||||||
function addOutput(id, output2) {
|
function addOutput(id, output2) {
|
||||||
const item = $$("li");
|
const item = $$("li");
|
||||||
item.classList.add("output");
|
item.classList.add("output");
|
||||||
item.dataset.id = id || randomId();
|
item.dataset.id = id || randomId();
|
||||||
const [format, content4] = processOutput(output2);
|
const [format, content3] = processOutput(output2);
|
||||||
if (format === "html")
|
if (format === "html")
|
||||||
item.innerHTML = content4;
|
item.innerHTML = content3;
|
||||||
else
|
else
|
||||||
item.textContent = content4;
|
item.textContent = content3;
|
||||||
const input = document.querySelector(`[data-id="${id}"].input`);
|
const input = document.querySelector(`[data-id="${id}"].input`);
|
||||||
if (input instanceof HTMLLIElement) {
|
if (input instanceof HTMLLIElement) {
|
||||||
input.parentNode.insertBefore(item, input.nextSibling);
|
input.parentNode.insertBefore(item, input.nextSibling);
|
||||||
} else {
|
} else {
|
||||||
insert(item);
|
insert(item);
|
||||||
}
|
}
|
||||||
autoScroll();
|
|
||||||
}
|
}
|
||||||
function addErrorMessage(message) {
|
function addErrorMessage(message) {
|
||||||
addOutput("", { html: `<span class="red">${message}</span>` });
|
addOutput("", { html: `<span class="red">${message}</span>` });
|
||||||
|
|
@ -109,12 +105,11 @@ function appendOutput(id, output2) {
|
||||||
console.error(`output id ${id} not found`);
|
console.error(`output id ${id} not found`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [format, content4] = processOutput(output2);
|
const [format, content3] = processOutput(output2);
|
||||||
if (format === "html")
|
if (format === "html")
|
||||||
item.innerHTML += content4;
|
item.innerHTML += content3;
|
||||||
else
|
else
|
||||||
item.textContent += content4;
|
item.textContent += content3;
|
||||||
autoScroll();
|
|
||||||
}
|
}
|
||||||
function replaceOutput(id, output2) {
|
function replaceOutput(id, output2) {
|
||||||
const item = document.querySelector(`[data-id="${id}"].output`);
|
const item = document.querySelector(`[data-id="${id}"].output`);
|
||||||
|
|
@ -122,12 +117,11 @@ function replaceOutput(id, output2) {
|
||||||
console.error(`output id ${id} not found`);
|
console.error(`output id ${id} not found`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [format, content4] = processOutput(output2);
|
const [format, content3] = processOutput(output2);
|
||||||
if (format === "html")
|
if (format === "html")
|
||||||
item.innerHTML = content4;
|
item.innerHTML = content3;
|
||||||
else
|
else
|
||||||
item.textContent = content4;
|
item.textContent = content3;
|
||||||
autoScroll();
|
|
||||||
}
|
}
|
||||||
function processOutput(output) {
|
function processOutput(output) {
|
||||||
let content = "";
|
let content = "";
|
||||||
|
|
@ -162,8 +156,181 @@ function handleInputClick(e) {
|
||||||
}
|
}
|
||||||
function handleOutput(msg) {
|
function handleOutput(msg) {
|
||||||
const result = msg.data;
|
const result = msg.data;
|
||||||
setStatus(msg.id, result.status);
|
const id = "id" in msg ? msg.id || "" : "";
|
||||||
addOutput(msg.id, result.output);
|
setStatus(id, result.status);
|
||||||
|
addOutput(id, result.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/js/browser.ts
|
||||||
|
var HEIGHT = 540;
|
||||||
|
var WIDTH = 960;
|
||||||
|
var controls = $("browser-controls");
|
||||||
|
var address = $("browser-address");
|
||||||
|
var iframe;
|
||||||
|
var realUrl = "";
|
||||||
|
var showInput = true;
|
||||||
|
function isBrowsing() {
|
||||||
|
return document.querySelector("iframe.browser.active") !== null;
|
||||||
|
}
|
||||||
|
function openBrowser(url, openedVia = "click") {
|
||||||
|
showInput = openedVia === "click";
|
||||||
|
iframe = $$("iframe.browser.active");
|
||||||
|
iframe.src = url;
|
||||||
|
iframe.sandbox.add("allow-scripts", "allow-same-origin", "allow-forms");
|
||||||
|
iframe.height = String(HEIGHT);
|
||||||
|
iframe.width = String(WIDTH);
|
||||||
|
iframe.tabIndex = 0;
|
||||||
|
window.addEventListener("message", handleAppMessage);
|
||||||
|
window.addEventListener("keydown", handleBrowserKeydown);
|
||||||
|
controls.addEventListener("click", handleClick);
|
||||||
|
iframe.addEventListener("load", handlePageLoad);
|
||||||
|
controls.style.display = "";
|
||||||
|
const main = document.querySelector("#content");
|
||||||
|
main?.prepend(iframe);
|
||||||
|
setAddress(url);
|
||||||
|
}
|
||||||
|
function closeBrowser() {
|
||||||
|
window.removeEventListener("keydown", handleBrowserKeydown);
|
||||||
|
window.removeEventListener("message", handleAppMessage);
|
||||||
|
controls.removeEventListener("click", handleClick);
|
||||||
|
iframe.removeEventListener("load", handlePageLoad);
|
||||||
|
const id = randomId();
|
||||||
|
if (showInput)
|
||||||
|
addInput(id, "browse " + realUrl, "ok");
|
||||||
|
iframe.height = String(HEIGHT / 2);
|
||||||
|
iframe.width = String(WIDTH / 2);
|
||||||
|
iframe.style.pointerEvents = "none";
|
||||||
|
iframe.tabIndex = -1;
|
||||||
|
iframe.classList.remove("fullscreen", "active");
|
||||||
|
scrollback.append(iframe);
|
||||||
|
controls.style.display = "none";
|
||||||
|
focusInput();
|
||||||
|
}
|
||||||
|
function handleAppMessage(event) {
|
||||||
|
const origin = event.origin;
|
||||||
|
if (!origin.includes("localhost") && !origin.match(/\.local$/)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { type, data } = event.data;
|
||||||
|
switch (type) {
|
||||||
|
case "NAV_READY":
|
||||||
|
break;
|
||||||
|
case "URL_CHANGED":
|
||||||
|
setAddress(data.url);
|
||||||
|
break;
|
||||||
|
case "TITLE_CHANGED":
|
||||||
|
console.log("Page title:", data.title);
|
||||||
|
break;
|
||||||
|
case "NAV_BLOCKED":
|
||||||
|
showNavigationError(data.url, data.reason);
|
||||||
|
break;
|
||||||
|
case "KEYDOWN":
|
||||||
|
const keyEvent = new KeyboardEvent("keydown", {
|
||||||
|
key: data.key,
|
||||||
|
ctrlKey: data.ctrlKey,
|
||||||
|
shiftKey: data.shiftKey,
|
||||||
|
altKey: data.altKey,
|
||||||
|
metaKey: data.metaKey,
|
||||||
|
bubbles: true
|
||||||
|
});
|
||||||
|
window.dispatchEvent(keyEvent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleBrowserKeydown(e) {
|
||||||
|
if (e.key === "Escape" || e.ctrlKey && e.key === "c") {
|
||||||
|
e.preventDefault();
|
||||||
|
closeBrowser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleClick(e) {
|
||||||
|
const target = e.target;
|
||||||
|
if (!(target instanceof HTMLElement))
|
||||||
|
return;
|
||||||
|
switch (target.id) {
|
||||||
|
case "back-button":
|
||||||
|
navigateBack();
|
||||||
|
break;
|
||||||
|
case "forward-button":
|
||||||
|
navigateForward();
|
||||||
|
break;
|
||||||
|
case "stop-button":
|
||||||
|
stopLoading();
|
||||||
|
break;
|
||||||
|
case "reload-button":
|
||||||
|
reloadBrowser();
|
||||||
|
break;
|
||||||
|
case "fullscreen-button":
|
||||||
|
fullscreenBrowser();
|
||||||
|
break;
|
||||||
|
case "close-button":
|
||||||
|
closeBrowser();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
function handlePageLoad() {}
|
||||||
|
function setAddress(url) {
|
||||||
|
realUrl = url;
|
||||||
|
address.textContent = url.replace(/https?:\/\//, "");
|
||||||
|
}
|
||||||
|
function navigateBack() {
|
||||||
|
sendNavCommand("back");
|
||||||
|
}
|
||||||
|
function navigateForward() {
|
||||||
|
sendNavCommand("forward");
|
||||||
|
}
|
||||||
|
function reloadBrowser() {
|
||||||
|
sendNavCommand("reload");
|
||||||
|
}
|
||||||
|
function stopLoading() {
|
||||||
|
sendNavCommand("stop");
|
||||||
|
}
|
||||||
|
function fullscreenBrowser() {
|
||||||
|
controls.style.display = "none";
|
||||||
|
iframe.classList.add("fullscreen");
|
||||||
|
document.body.append(iframe);
|
||||||
|
}
|
||||||
|
function sendNavCommand(action) {
|
||||||
|
if (!iframe.contentWindow)
|
||||||
|
return;
|
||||||
|
iframe.contentWindow.postMessage({
|
||||||
|
type: "NAV_COMMAND",
|
||||||
|
action
|
||||||
|
}, "*");
|
||||||
|
}
|
||||||
|
function showNavigationError(url, reason) {
|
||||||
|
alert(`NAVIGATION BLOCKED
|
||||||
|
|
||||||
|
${url}
|
||||||
|
|
||||||
|
${reason}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/js/resize.ts
|
||||||
|
var content3 = document.getElementById("content");
|
||||||
|
function initResize() {
|
||||||
|
window.addEventListener("resize", resize);
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
function resize() {
|
||||||
|
if (document.body.dataset.mode === "tall") {
|
||||||
|
resizeTall();
|
||||||
|
} else {
|
||||||
|
resizeCinema();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function resizeTall() {
|
||||||
|
const scale = Math.min(1, window.innerWidth / 960);
|
||||||
|
content3.style.transformOrigin = "top center";
|
||||||
|
content3.style.transform = `scaleX(${scale})`;
|
||||||
|
}
|
||||||
|
function resizeCinema() {
|
||||||
|
const scale = Math.min(window.innerWidth / 960, window.innerHeight / 540);
|
||||||
|
content3.style.transformOrigin = "center center";
|
||||||
|
content3.style.transform = `scale(${scale})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/js/session.ts
|
// src/js/session.ts
|
||||||
|
|
@ -391,32 +558,10 @@ class GameContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/js/focus.ts
|
|
||||||
function initFocus() {
|
|
||||||
window.addEventListener("click", focusHandler);
|
|
||||||
focusInput();
|
|
||||||
}
|
|
||||||
function focusInput() {
|
|
||||||
cmdInput.focus();
|
|
||||||
}
|
|
||||||
function focusHandler(e) {
|
|
||||||
const target = e.target;
|
|
||||||
if (!(target instanceof HTMLElement)) {
|
|
||||||
focusInput();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (["INPUT", "TEXTAREA", "CANVAS", "A"].includes(target.tagName))
|
|
||||||
return false;
|
|
||||||
const selection = window.getSelection() || "";
|
|
||||||
if (selection.toString() === "")
|
|
||||||
focusInput();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/js/game.ts
|
// src/js/game.ts
|
||||||
var FPS = 30;
|
var FPS = 30;
|
||||||
var HEIGHT = 540;
|
var HEIGHT2 = 540;
|
||||||
var WIDTH = 980;
|
var WIDTH2 = 960;
|
||||||
var oldMode = "cinema";
|
var oldMode = "cinema";
|
||||||
var running = false;
|
var running = false;
|
||||||
var canvas;
|
var canvas;
|
||||||
|
|
@ -458,8 +603,8 @@ async function handleGameStart(msg) {
|
||||||
function createCanvas() {
|
function createCanvas() {
|
||||||
const canvas2 = $$("canvas.game.active");
|
const canvas2 = $$("canvas.game.active");
|
||||||
canvas2.id = randomId();
|
canvas2.id = randomId();
|
||||||
canvas2.height = HEIGHT;
|
canvas2.height = HEIGHT2;
|
||||||
canvas2.width = WIDTH;
|
canvas2.width = WIDTH2;
|
||||||
canvas2.tabIndex = 0;
|
canvas2.tabIndex = 0;
|
||||||
const main = document.querySelector("main");
|
const main = document.querySelector("main");
|
||||||
main?.classList.add("game");
|
main?.classList.add("game");
|
||||||
|
|
@ -530,8 +675,8 @@ function endGame() {
|
||||||
const main = document.querySelector("main");
|
const main = document.querySelector("main");
|
||||||
main?.classList.remove("game");
|
main?.classList.remove("game");
|
||||||
canvas.classList.remove("active");
|
canvas.classList.remove("active");
|
||||||
canvas.style.height = HEIGHT / 2 + "px";
|
canvas.style.height = HEIGHT2 / 2 + "px";
|
||||||
canvas.style.width = WIDTH / 2 + "px";
|
canvas.style.width = WIDTH2 / 2 + "px";
|
||||||
const output2 = $$("li.output");
|
const output2 = $$("li.output");
|
||||||
output2.append(canvas);
|
output2.append(canvas);
|
||||||
insert(output2);
|
insert(output2);
|
||||||
|
|
@ -627,6 +772,7 @@ function retryConnection() {
|
||||||
// src/js/commands.ts
|
// src/js/commands.ts
|
||||||
var commands = [];
|
var commands = [];
|
||||||
var browserCommands = {
|
var browserCommands = {
|
||||||
|
browse: (url) => openBrowser(url, "command"),
|
||||||
"browser-session": () => sessionId,
|
"browser-session": () => sessionId,
|
||||||
clear: () => scrollback.innerHTML = "",
|
clear: () => scrollback.innerHTML = "",
|
||||||
commands: () => {
|
commands: () => {
|
||||||
|
|
@ -636,12 +782,11 @@ var browserCommands = {
|
||||||
mode: (mode) => {
|
mode: (mode) => {
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
mode = document.body.dataset.mode === "tall" ? "cinema" : "tall";
|
mode = document.body.dataset.mode === "tall" ? "cinema" : "tall";
|
||||||
send({ type: "ui:mode", data: mode });
|
send({ type: "session:update", data: { "ui:mode": mode } });
|
||||||
}
|
}
|
||||||
content2.style.display = "";
|
content2.style.display = "";
|
||||||
document.body.dataset.mode = mode;
|
document.body.dataset.mode = mode;
|
||||||
resize();
|
resize();
|
||||||
autoScroll();
|
|
||||||
focusInput();
|
focusInput();
|
||||||
},
|
},
|
||||||
reload: () => window.location.reload()
|
reload: () => window.location.reload()
|
||||||
|
|
@ -770,7 +915,7 @@ function keydownHandler(e) {
|
||||||
} else if (e.ctrlKey && e.key === "s" || e.ctrlKey && e.key === "Enter") {
|
} else if (e.ctrlKey && e.key === "s" || e.ctrlKey && e.key === "Enter") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
send({
|
send({
|
||||||
id: editor.dataset.path,
|
id: editor.dataset.path || "/tmp.txt",
|
||||||
type: "save-file",
|
type: "save-file",
|
||||||
data: editor.value
|
data: editor.value
|
||||||
});
|
});
|
||||||
|
|
@ -1058,30 +1203,11 @@ async function runCommand(input) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/js/statusbar.ts
|
|
||||||
var STATUS_MSG_LENGTH = 3000;
|
|
||||||
var statusbar = $("statusbar");
|
|
||||||
var statusbarMsg = $("statusbar-msg");
|
|
||||||
var timer;
|
|
||||||
function status(msg) {
|
|
||||||
showStatusMsg();
|
|
||||||
statusbarMsg.textContent = msg;
|
|
||||||
if (timer)
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = setTimeout(hideStatusMsg, STATUS_MSG_LENGTH);
|
|
||||||
}
|
|
||||||
function showStatusMsg() {
|
|
||||||
statusbar.classList.add("showing-msg");
|
|
||||||
}
|
|
||||||
function hideStatusMsg() {
|
|
||||||
statusbar.className = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// src/js/hyperlink.ts
|
// src/js/hyperlink.ts
|
||||||
function initHyperlink() {
|
function initHyperlink() {
|
||||||
window.addEventListener("click", handleClick);
|
window.addEventListener("click", handleClick2);
|
||||||
}
|
}
|
||||||
async function handleClick(e) {
|
async function handleClick2(e) {
|
||||||
const target = e.target;
|
const target = e.target;
|
||||||
if (!(target instanceof HTMLElement))
|
if (!(target instanceof HTMLElement))
|
||||||
return;
|
return;
|
||||||
|
|
@ -1091,13 +1217,13 @@ async function handleClick(e) {
|
||||||
const href = a.getAttribute("href");
|
const href = a.getAttribute("href");
|
||||||
if (!href)
|
if (!href)
|
||||||
return;
|
return;
|
||||||
if (href.startsWith("#")) {
|
if (href.startsWith("#") && href.length > 1) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await runCommand(href.slice(1));
|
await runCommand(href.slice(1));
|
||||||
focusInput();
|
focusInput();
|
||||||
} else {
|
} else if (!isBrowsing()) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
status(href);
|
openBrowser(href);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1155,7 +1281,7 @@ function clearInput() {
|
||||||
// src/js/vram.ts
|
// src/js/vram.ts
|
||||||
var vramCounter = $("vram-size");
|
var vramCounter = $("vram-size");
|
||||||
var startVramCounter = () => {
|
var startVramCounter = () => {
|
||||||
const timer2 = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
const count = parseInt(vramCounter.textContent) + 1;
|
const count = parseInt(vramCounter.textContent) + 1;
|
||||||
let val = count + "KB";
|
let val = count + "KB";
|
||||||
if (count < 10)
|
if (count < 10)
|
||||||
|
|
@ -1163,7 +1289,7 @@ var startVramCounter = () => {
|
||||||
vramCounter.textContent = val;
|
vramCounter.textContent = val;
|
||||||
if (count >= 64) {
|
if (count >= 64) {
|
||||||
vramCounter.textContent += " OK";
|
vramCounter.textContent += " OK";
|
||||||
clearInterval(timer2);
|
clearInterval(timer);
|
||||||
}
|
}
|
||||||
}, 15);
|
}, 15);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user