working2...

This commit is contained in:
Dooho Yi 2022-01-16 16:44:28 +09:00
parent c10cd29ae8
commit e264af7809
8 changed files with 230 additions and 222 deletions

View file

@ -9,6 +9,7 @@ body {
color: white; color: white;
font-size: 15px; font-size: 15px;
line-height: 1.4; line-height: 1.4;
font-family: 'Noto Sans KR', sans-serif;
} }
.bg { .bg {
@ -27,7 +28,6 @@ body {
.content { .content {
width: 100%; width: 100%;
height: 100%; height: 100%;
font-family: 'Noto Sans KR', sans-serif;
} }
.lang { .lang {
@ -122,6 +122,12 @@ ol, ul {
margin-left: 40px; margin-left: 40px;
} }
.noscroll {
overflow: hidden;
}
.noscroll * { touch-action: none;
}
button { button {
background-color: transparent; background-color: transparent;
@ -135,9 +141,13 @@ button {
} }
.drawing { .drawing {
width: 50px; position: relative;
display: inline-block; display: inline-block;
width: 300px;
left: 50%;
transform: translate(-50%);
vertical-align: top; vertical-align: top;
text-align: center;
} }
.name { .name {

View file

@ -1,8 +1,8 @@
function setup() { // function setup() {
noCanvas(); // noCanvas();
selectAll('.name').forEach(item => { // selectAll('.name').forEach(item => {
httpGet(item.attribute('src'), text => { // httpGet(item.attribute('src'), text => {
item.html(text); // item.html(text);
}) // })
}) // })
} // }

4
public/main.css Normal file
View file

@ -0,0 +1,4 @@
html,
body {
overflow: hidden;
}

View file

@ -1,9 +1,3 @@
/*
global loadSound frameRate background createButton io noCanvas
select createP windowWidth windowHeight random createImg createDiv
AUTO loadJSON createCanvas createRadio selectAll int str
*/
// // force https // // force https
// var http_confirm = location.href.split(":")[0]; // var http_confirm = location.href.split(":")[0];
// if (http_confirm == "http") { // if (http_confirm == "http") {
@ -14,12 +8,33 @@ var socket = io(location.host);
var n = 0; var n = 0;
var fr = 20; var fr = 20;
var arr = []; var arr = [];
var voice = [];
var looper; var looper;
var score; var score;
let logo; let logo;
var silence; var silence;
(async () => {
fetch("/entries").then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function() {
console.log("Booo");
});
var list = new Promise((resolve, reject) => {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "/entries", false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
loadJSON("/entries", (json) => {
resolve(json);
});
});
await list;
console.log(list);
})();
function preload() { function preload() {
loadJSON("/score.json", function(json) { loadJSON("/score.json", function(json) {
score = json; score = json;
@ -35,32 +50,10 @@ function setup() {
fr = 20; fr = 20;
} }
frameRate(fr); frameRate(fr);
voice[0] = loadSound("./audio/018.mp3");
voice[1] = loadSound("./audio/011.mp3");
voice[2] = loadSound("./audio/14.mp3");
voice[3] = loadSound("./audio/012.mp3");
voice[4] = loadSound("./audio/17.mp3");
voice[5] = loadSound("./audio/11.mp3");
voice[6] = loadSound("./audio/013.mp3");
voice[7] = loadSound("./audio/022.mp3");
voice[8] = loadSound("./audio/020.mp3");
voice[9] = loadSound("./audio/021.mp3");
voice[10] = loadSound("./audio/014.mp3");
voice[11] = loadSound("./audio/16.mp3");
voice[12] = loadSound("./audio/015.mp3");
voice[13] = loadSound("./audio/18.mp3");
voice[14] = loadSound("./audio/12.mp3");
voice[15] = loadSound("./audio/019.mp3");
voice[16] = loadSound("./audio/13.mp3");
voice[17] = loadSound("./audio/016.mp3");
voice[18] = loadSound("./audio/017.mp3");
voice[19] = loadSound("./audio/023.mp3");
// randomvoiceplay();
} }
// //
var myroom = -1; var myroom = -1;
var plogo;
var intro; var intro;
var ready; var ready;
// //
@ -68,60 +61,48 @@ socket.on("connect", function() {
console.log("connected!"); console.log("connected!");
// //
//TESTING... fixed to room 1.
// myroom = 1;
if (myroom == -1 && selectAll(".roomsel").length == 0) { if (myroom == -1 && selectAll(".roomsel").length == 0) {
//initial connection -> ask the room number. //initial connection -> ask the room number.
// plogo.position(windowWidth/2, 50); intro = createP("《흐름을 향하여 걷는》 ...");
plogo = createImg("./imgs/logo02.png", "퍼레이드진진진 로고", "", function(
im
) {
im.show();
im.size(windowWidth, AUTO);
});
intro = createP(
"흘러가는 진 퍼레이드에 오신거 환영합니다. <br>*본인의 기기로 보고 싶은 퍼레이드의 구간을 고르세요. <br>여러 개의 기기로 퍼레이드를 연결해서 볼 수 있습니다.<br>*이 퍼레이드에서 흘러가는 진들은 각자의 이야기를 가지고 있습니다. <br>대체텍스트가 포함되어 있어 스크린리더를 통해 이야기를 음성으로 들을 수 있습니다."
);
intro.style("font-size", windowHeight / 30 + "pt"); intro.style("font-size", windowHeight / 30 + "pt");
intro.class("intro"); intro.class("intro");
var roomsel = createDiv(); var roomsel = createDiv();
roomsel.class("roomsel"); roomsel.class("roomsel");
for (var idx = 9; idx > 0; idx--) { var b = createButton("시작하기!", 1);
var b = createButton(str(idx), str(idx)); b.mouseClicked(function() {
b.mouseClicked(function() { silence.play();
silence.play(); myroom = parseInt(this.value());
myroom = parseInt(this.value());
socket.emit("room", myroom, function(res) { socket.emit("room", myroom, function(res) {
if (res) { if (res) {
console.log("entered the room -> " + myroom); console.log("entered the room -> " + myroom);
createP(str(myroom)); createP(str(myroom));
setTimeout(function() { // setTimeout(function() {
ready = createP("퍼레이드 시작합니다!!"); // ready = createP("퍼레이드 시작합니다!!");
ready.position( // ready.position(
windowWidth / 2 - windowWidth / 10, // windowWidth / 2 - windowWidth / 10,
windowHeight / 2 // windowHeight / 2
); // );
}, 1000); // }, 1000);
} else { } else {
console.log("rejected!"); console.log("rejected!");
} }
});
setTimeout(function() {
selectAll(".roomsel").forEach(function(item) {
item.remove();
});
selectAll(".intro").forEach(function(item) {
item.remove();
});
plogo.remove();
}, 1000);
setTimeout(function() {
ready.remove();
}, 8000);
}); });
roomsel.child(b);
} setTimeout(function() {
selectAll(".roomsel").forEach(function(item) {
item.remove();
});
selectAll(".intro").forEach(function(item) {
item.remove();
});
}, 1000);
});
roomsel.child(b);
} else { } else {
//re-connection -> just connect to remembered room! //re-connection -> just connect to remembered room!
socket.emit("room", myroom, function(res) { socket.emit("room", myroom, function(res) {
@ -135,10 +116,21 @@ socket.on("connect", function() {
}); });
socket.on("post", function(post) { socket.on("post", function(post) {
console.log(post); console.log(post);
// // var object = post.object;
var object = post.object; var object = {
"id": 1,
"type": "abc",
"src": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/pixels.png",
"audio": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/audio.mp3",
"alt": "알트",
"size": { "base": 40, "random": 20 },
"y": { "base": 20, "random": 10 },
"showtime": 30000
};
console.log(object);
var img = createImg(object.src, object.alt, "", function(im) { var img = createImg(object.src, object.alt, "", function(im) {
var sound = loadSound(object.audio, function(snd) { var sound = loadSound(object.audio, function(snd) {
@ -201,6 +193,7 @@ socket.on("post", function(post) {
//첨에는 hide //첨에는 hide
img.hide(); img.hide();
}); });
function draw() { function draw() {

View file

@ -54,7 +54,6 @@ var io = require("socket.io")(fastify.server, {
//get '/' //get '/'
fastify.get("/", function (request, reply) { fastify.get("/", function (request, reply) {
// reply.get("/src/pages/parade.html", {}); //???
reply.view("/src/pages/parade.html", {}); reply.view("/src/pages/parade.html", {});
}); });
@ -70,35 +69,31 @@ fastify.get("/", function (request, reply) {
//get '/list', '/list/' //get '/list', '/list/'
["/list", "/list/"].forEach(function(item) { ["/list", "/list/"].forEach(function(item) {
fastify.get(item, async function (request, reply) { fastify.get(item, async function (request, reply) {
//get list
const client = new Client(server);
const sourceFolder = await client.getFolder("/Storage/public/sound-parade/");
const subFolders = await sourceFolder.getSubFolders();
//get list
let list = await fs.readdir('/media/storage/public/sound-parade/');
console.log(list);
let folders = []; let folders = [];
for (const subFolder of subFolders) { for (const item of list) {
console.log("folder", subFolder.name); folders.push({
folders.push(path.basename(subFolder.name)); foldername: item,
message: (await fs.readFile('/media/storage/public/sound-parade/' + item + '/message.txt')).toString('utf8')
})
} }
reply.view("/src/pages/list.html", { list: folders }); reply.view("/src/pages/list.html", {
list: folders,
});
}); });
}); });
//get '/folders' //get '/entries'
fastify.get("/folders", async function (request, reply) { fastify.get("/entries", async function (request, reply) {
//get list //get list
const client = new Client(server); let list = await fs.readdir('/media/storage/public/sound-parade/');
const sourceFolder = await client.getFolder("/Storage/public/sound-parade/");
const subFolders = await sourceFolder.getSubFolders();
let folders = []; reply.send({ list: list });
for (const subFolder of subFolders) {
console.log("folder", subFolder.name);
folders.push(subFolder.name);
}
reply.send({ list: folders });
}); });
// //get '/folder:{foldername}' // //get '/folder:{foldername}'
@ -194,16 +189,19 @@ var looper;
// NOTE: 'index' is same => 'indexed' // NOTE: 'index' is same => 'indexed'
setTimeout(function(pointed, indexed) { setTimeout(function(pointed, indexed) {
io.to("room" + indexed).emit("post", score[pointed]); // io.to("room" + indexed).emit("post", score[pointed]);
io.to("room" + indexed).emit("post", pointed);
}, score[pointer].object.showtime * index, pointer, index); // }, score[pointer].object.showtime * index, pointer, index);
}, 30000 * index, pointer, index);
} }
var timegap = score[pointer].timegap.base + Math.random()*score[pointer].timegap.random; var timegap = 10000 + Math.random()*(10000);
// console.log(timegap); console.log(timegap);
pointer++; pointer++;
if (pointer >= score.length) pointer = 0; // if (pointer >= score.length) pointer = 0;
if (pointer >= 10) pointer = 0; // up to # of folders.
looper(timegap); looper(timegap);
}, timeout); }, timeout);

View file

@ -3,13 +3,13 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>흐름을 향하여 걷는</title> <title>흐름을 향하여 걷는 | 입장</title>
<!-- <link rel="stylesheet" href="https://unpkg.com/tachyons@4.12.0/css/tachyons.min.css" /> --> <!-- <link rel="stylesheet" href="https://unpkg.com/tachyons@4.12.0/css/tachyons.min.css" /> -->
<link rel="stylesheet" href="/default.css" /> <link rel="stylesheet" href="/default.css" />
<link rel="stylesheet" href="/entry.css" /> <link rel="stylesheet" href="/entry.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" />
</head> </head>
<body> <body>
@ -17,60 +17,60 @@
<div class="content ph5 center"> <div class="content ph5 center">
<div class="lang"><a href="">EN</a></div> <div class="lang"><a href="">EN</a></div>
<div class="notice"> <div class="notice">
<section> <section>
<h1>흐름을 &nbsp;향하여 &nbsp;걷는</h1> <h1>흐름을 &nbsp;향하여 &nbsp;걷는</h1>
<p class="white f3 pv3"> <p class="white f3 pv3">
퍼레이드를 행렬 밖에서 바라본 적이 있나요? 북소리와 함성소리가 멀리서 들리고, 많은 존재들이 외치고, 흐르듯 지나가고, 무리가 등장하고, 잦아지는...... 퍼레이드를 행렬 밖에서 바라본 적이 있나요? 북소리와 함성소리가 멀리서 들리고, 많은 존재들이 외치고, 흐르듯 지나가고, 무리가 등장하고, 잦아지는......
</p> </p>
<p class="white f3 pv3"> <p class="white f3 pv3">
«흐름을 향하여 걷는»은 온라인으로 소리의 행렬을 만드는 사운드 퍼레이드입니다. 누구나 참여할 수 있는 이 퍼레이드는 여러분이 보내주시는 소리를 모아 만듭니다. 말하는 소리, 몸이 내는 소리, 주변의 사물 또는 누군가의 소리를 보내주세요. «흐름을 향하여 걷는»은 온라인으로 소리의 행렬을 만드는 사운드 퍼레이드입니다. 누구나 참여할 수 있는 이 퍼레이드는 여러분이 보내주시는 소리를 모아 만듭니다. 말하는 소리, 몸이 내는 소리, 주변의 사물 또는 누군가의 소리를 보내주세요.
</p> </p>
<p class="white f3 pv3"> <p class="white f3 pv3">
보내주신 소리는 무리를 지어 모양과 함께 흘러갑니다. «흐름을 향하여 걷는»은 총 다섯 개의 소리 무리로 이루어지고 무리별로 각 3분씩 총 15분동안 진행합니다. 보내주신 소리는 무리를 지어 모양과 함께 흘러갑니다. «흐름을 향하여 걷는»은 총 다섯 개의 소리 무리로 이루어지고 무리별로 각 3분씩 총 15분동안 진행합니다.
</p> </p>
<p class="white f3 pv3">
1월 27일(목) 밤, 프랑스 대사관이 주최하는 ‘사유의 밤’ 행사에서 «흐름을 향하여 걷는» 퍼레이드는 연주와 함께 송출될 예정입니다. 많은 참여 및 관심 부탁드립니다.
</p>
<div class="info">
<p class="white f3 pv3"> <p class="white f3 pv3">
1월 27일(목) 밤, «흐름을 향하여 걷는»은 라이브 사운드와 결합해 프랑스 대사관이 주최하는 ‘사유의 밤’ 행사에서 라이브 공연으로 송출할 예정입니다. 많은 참여와 관심 부탁드립니다.
</p>
<div class="info">
<p class="white f3 pv3">
소리 모집<br/> 소리 모집<br/>
2022년 1월 17일(월)2022년 1월 26일(수) 2022년 1월 17일(월)2022년 1월 26일(수)
</p> </p>
</p> </p>
<p class="white f3 pv3"> <p class="white f3 pv3">
라이브 공연<br/> 라이브 공연<br/>
2022년 1월 27일(목)<br> 2022년 1월 27일(목)<br>
20:45-21:00 (KST), 12:45-13:00 (CET)<br/> 20:45-21:00 (KST), 12:45-13:00 (CET)<br/>
</p> </p>
<p class="white f3 pv3"> <p class="white f3 pv3">
장소<br/> 장소<br/>
유튜브 스트리밍, 링크들 유튜브 스트리밍(추후공지), 링크들
</p> </p>
<p class="white f3 pv3"> <p class="white f3 pv3">
퍼레이드 구성<br/> 퍼레이드 구성<br/>
0 무리 약속들 — 1 무리 깃발들 — 2 무리 신체들 — 3 무리 사물들 — 4 무리 누구들 무리0 약속들 — 무리1 깃발들 — 무리2 신체들 — 무리3 사물들 — 무리4 누구들
</p> </p>
</div> </div>
</section> </section>
<section class="participation"> <section class="participation">
<p class="white f3 pv3 sec"> <p class="white f3 pv3 sec">
<h2>참여 방법</h2> <h2>참여 방법</h2>
<ol> <ol>
<li>1. 무리의 특성에 따라 녹음기기나 핸드폰으로 30초 가량의 소리를 녹음해주세요. <li>1. 무리의 특성에 따라 녹음기기나 핸드폰으로 30초 가량의 소리를 녹음해주세요.
<ol class="category"> <ol class="category">
<li>• 무리 깃발들 — 좋아하는 것, 가치에 대해 다섯 번 외쳐주세요.</li> <li>• 무리1 깃발들 — 좋아하는 것, 가치에 대해 다섯 번 외쳐주세요.</li>
<li>• 무리 신체들 — 몸의 소리를 모아 봅시다. 박수도 좋구요. 발을 구르거나 휘파람도 좋습니다.</li> <li>• 무리2 신체들 — 몸에서 나는 소리를 녹음해 보아요. 박수, 휘파람도 좋아요.</li>
<li>• 무리 사물들 — 주변에 사물들이 보이시죠? 그들의 몸의 소리, 목소리를 녹음해 보세요. 뽁뽁이 소리, 구슬구르는 소리</li> <li>• 무리3 사물들 — 주변 사물들의 소리를 찾아 주세요. 뽁뽁이 소리, 구슬 소리</li>
<li>• 무리 누구들 — 누구의 소리를 모아주세요. 반려동물, 물 흐르는 소리, 산책할 때 듣는 소리</li> <li>• 무리4 누구들 — 누구의 소리를 모아주세요. 반려동물, 물 소리, 산책의 장소</li>
</ol> </ol>
</li> </li>
<li>2. 녹음한 소리 파일을 업로드해주세요.</li> <li>2. 녹음한 소리 파일을 업로드해주세요.</li>
<li>3. 소리의 제목과 설명을 입력한 뒤, 소리의 모양을 그려 제출해주세요.</li> <li>3. 소리의 제목과 묘사을 입력한 뒤, 소리의 모양을 그려 제출해주세요.</li>
</ol> </ol>
</p> </p>
</section> </section>
<section> <section>
<p class="white f3 pv3"> <p class="white f3 pv3">
<h2>소리 제출</h2> <h2>소리 제출</h2>
<form <form
id="form" id="form"
@ -78,58 +78,58 @@
method="POST" method="POST"
enctype="multipart/form-data" enctype="multipart/form-data"
> >
<ul class="submit"> <ul class="submit">
<li> <li>
<h3>1. 소리 유형</h3> <h3>1. 소리 유형</h3>
<div class="pv3"> <div class="pv3">
<ul> <ul>
<li> <li>
<input type="radio" name="chk_info" value="flag"> 무리 깃발들 <input type="radio" name="chk_info" value="flag"> 무리1 깃발들
</li> </li>
<li> <li>
<input type="radio" name="chk_info" value="body"> 무리 신체들 <input type="radio" name="chk_info" value="body"> 무리2 신체들
</li> </li>
<li> <li>
<input type="radio" name="chk_info" value="object"> 무리 사물들 <input type="radio" name="chk_info" value="object"> 무리3 사물들
</li> </li>
<li> <li>
<input type="radio" name="chk_info" value="any"> 무리 누구들 <input type="radio" name="chk_info" value="any"> 무리4 누구들
<li> <li>
</ol> </ol>
</div> </div>
</li> </li>
<li> <li>
<h3>2. 소리 파일</h3> <h3>2. 소리 파일</h3>
<div class="pv3"> <div class="pv3">
<input type="file" name="audiofile" required="required" /> <input type="file" name="audiofile" required="required" />
</div> </div>
</li> </li>
<li> <li>
<h3>3. 소리 제목</h3> <h3>3. 소리 제목</h3>
<div class="pv3"> <div class="pv3">
<input id="message" name="message" required="required" type="text" /> <input id="message" name="message" required="required" type="text" />
</div> </div>
</li> </li>
<li> <li>
<h3>4. 소리 설명</h3> <h3>4. 소리 묘사</h3>
<div class="pv3"> <div class="pv3">
<input id="message" name="message" required="required" type="text" /> <input id="message" name="message" required="required" type="text" />
</div> </div>
</li> </li>
<!-- pixels.png ~ made with p5.js --> <!-- pixels.png ~ made with p5.js -->
<li> <li class="noscroll">
<h3>5. 소리 모양</h3> <h3>5. 소리 모양</h3>
<div class="pv3" id="p5"> <div class="pv3" id="p5">
</div> </div>
</li> </li>
<li> <li>
<div class="pv3"> <div class="pv3">
<input type="submit" value="Upload" /> <input type="submit" value="Upload" />
</li> </li>
</div> </div>
</form> </form>
</p> </p>
</section> </section>
</div> </div>
</div> </div>
<script src="/entry/script.js"></script> <script src="/entry/script.js"></script>

View file

@ -3,12 +3,12 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>흐름을 향하여 걷는</title> <title>흐름을 향하여 걷는 | 목록</title>
<link rel="stylesheet" href="/default.css" /> <link rel="stylesheet" href="/default.css" />
<link rel="stylesheet" href="/list.css" /> <link rel="stylesheet" href="/list.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" />
</head> </head>
<body> <body>
@ -17,12 +17,12 @@
<div class="notice"> <div class="notice">
<h1>흐름을 &nbsp;향하여 &nbsp;걷는</h1> <h1>흐름을 &nbsp;향하여 &nbsp;걷는</h1>
{{#each list}} {{#each list}}
<div class="items" foldername="{{this}}"> <div class="items" foldername="{{this.foldername}}">
<img class="drawing" src="https://p.dianaband.info/public/sound-parade/{{this}}/pixels.png" /> <img class="drawing" src="https://p.dianaband.info/public/sound-parade/{{this.foldername}}/pixels.png" />
<p class="name" src="https://p.dianaband.info/public/sound-parade/{{this}}/message.txt"></p> <p class="name">{{this.message}}</p>
<audio controls class="sound"> <!-- <audio controls class="sound">
<source src="https://p.dianaband.info/public/sound-parade/{{this}}/audio.mp3" type="audio/mpeg"> <source src="https://p.dianaband.info/public/sound-parade/{{this.foldername}}/audio.mp3" type="audio/mpeg">
</audio> </audio> -->
</div> </div>
{{/each}} {{/each}}
</div> </div>

View file

@ -1,20 +1,23 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>-*-parade-*- z/ne z//ne z///ne</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta <title>흐름을 향하여 걷는</title>
name="viewport" <link rel="stylesheet" href="/default.css" />
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" <link rel="stylesheet" href="/main.css" />
/>
<script src="/js/p5-v1.1.9.min.js"></script> <script src="/js/p5-v1.1.9.min.js"></script>
<script src="/js/socket-v2.3.0.io.slim.js"></script> <script src="/js/socket-v2.3.0.io.slim.js"></script>
<script src="/js/p5-v0.3.11.sound.min.js"></script> <script src="/js/p5-v0.3.11.sound.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Do+Hyeon&display=swap" rel="stylesheet"/> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" />
<script src="/sketch.js"></script> <script src="/sketch.js"></script>
<link rel="stylesheet" href="/style.css" />
</head> </head>
<body></body> <body>
<div class="bg"></div>
<div class="content">
</div>
</body>
</html> </html>