-
-
-
-
-
-
憛怠神?
-
???蝣箄?銝銝?/h3>
-
- - ?? 瑼??澆?嚗蔣?????嚗遣霅啣瑼?100MB 隞亙
- - ?? ?遢鞈???瘞湔?梯?蝷曉?冽??30TH ?隡?雿輻
- - ?? ?敺蝣箏???嚗?敺??西??砍?蝺渡???鋆賣???/li>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/yellow-note/crystal-dance-survey.html b/yellow-note/crystal-dance-survey.html
deleted file mode 100644
index 6affd35..0000000
--- a/yellow-note/crystal-dance-survey.html
+++ /dev/null
@@ -1,722 +0,0 @@
-
-
-
-
-
-
-
水晶男孩推廣部|水晶熱舞社
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 水晶男孩推廣部・舞蹈應援企劃
-
-
-
水晶熱舞社是水晶男孩推廣部中的舞蹈應援企劃,從 20TH台灣小黃串燒聯舞的集體記憶出發,整理經典舞台、翻跳紀錄與應援行動,並預備在 2027/04/15 30TH 前募集新的參與者。
-
水晶熱舞社不是獨立成立的社團,而是「水晶男孩推廣部」底下的舞蹈、翻跳、應援與影片紀錄分類。凡是跟 SECHSKIE舞台有關的練習、重現與紀錄,都會被收進這個企劃裡,由歷屆台灣小黃接力整理與延續。
-
-
-
-
-
-
-
-
-
從 20TH 到 30TH
-
-
-
-
-
-
-
水晶熱舞社是水晶男孩推廣部底下的舞蹈應援企劃,從 20TH 台灣小黃串燒聯舞的集體記憶出發,整理 SECHSKIES 經典舞台、翻跳紀錄與應援行動,並預備在 2027/04/15 30TH 前募集新的參與者,由歷屆台灣小黃接力延續。
-
-
-
-
延伸閱讀
-
-
-
-
-
-
-
-
-
幕後花絮 #2・雨中共舞
-
-
-
-
-
-
-
-
2027/04/15 是 SECHSKIES 出道 30 周年的日子。水晶熱舞社預計在 30TH
- 前重新整理舞蹈應援內容,募集想一起參與的台灣小黃,從經典舞曲、翻跳練習、影片剪輯到祝福文字,讓新的應援行動從這份表單開始累積。
-
你不需要一開始就很會跳舞,只要還記得水晶男孩的舞台、歌曲,或某個讓你入坑的瞬間,都可以在這裡留下你的參與方式。
-
- 💛 距離 30TH · 2027/04/15 倒數計算中...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/yellow-note/dance-application-submit.php b/yellow-note/dance-application-submit.php
deleted file mode 100644
index 5bfffd5..0000000
--- a/yellow-note/dance-application-submit.php
+++ /dev/null
@@ -1,170 +0,0 @@
- $maxUploadBytes + 1024 * 1024) {
- return_to_dance_form('file_too_large');
-}
-
-// 隱藏欄位有內容時視為機器送件;不透露攔截規則。
-if (trim((string) ($_POST['website'] ?? '')) !== '') {
- return_to_dance_form('success');
-}
-
-$nickname = post_value('nickname', 80);
-$email = mb_strtolower(post_value('email', 190), 'UTF-8');
-$danceYearsRaw = trim((string) ($_POST['dance_years'] ?? ''));
-$availableDate = trim((string) ($_POST['available_date'] ?? ''));
-$attended20th = trim((string) ($_POST['attended_20th'] ?? ''));
-$song = trim((string) ($_POST['song'] ?? ''));
-$message30th = post_value('message_30th', 5000);
-
-$allowedAttendance = ['attended', 'watched_video', 'first_time'];
-$allowedContent = ['cover', 'medley', 'blessing', 'graphic', 'editing', 'archive'];
-$allowedSongs = ['', 'couple', 'comeback', 'road_fighter', 'pom_saeng_pom_sa', 'other'];
-
-$selectedContent = $_POST['participate_content'] ?? [];
-if (!is_array($selectedContent)) {
- $selectedContent = [$selectedContent];
-}
-$selectedContent = array_values(array_unique(array_intersect(
- $allowedContent,
- array_map(static fn ($value): string => trim((string) $value), $selectedContent)
-)));
-
-if ($nickname === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || !$selectedContent) {
- return_to_dance_form('invalid');
-}
-if ($attended20th !== '' && !in_array($attended20th, $allowedAttendance, true)) {
- return_to_dance_form('invalid');
-}
-if (!in_array($song, $allowedSongs, true)) {
- return_to_dance_form('invalid');
-}
-
-$danceYears = null;
-if ($danceYearsRaw !== '') {
- $danceYearsFilter = filter_var($danceYearsRaw, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0, 'max_range' => 30]]);
- if ($danceYearsFilter === false) {
- return_to_dance_form('invalid');
- }
- $danceYears = (int) $danceYearsFilter;
-}
-
-if ($availableDate !== '') {
- $date = DateTimeImmutable::createFromFormat('!Y-m-d', $availableDate);
- if (!$date || $date->format('Y-m-d') !== $availableDate) {
- return_to_dance_form('invalid');
- }
-}
-
-$db = $config['db'];
-$dsn = "mysql:host={$db['host']};port={$db['port']};dbname={$db['name']};charset=utf8mb4";
-try {
- $pdo = new PDO($dsn, $db['user'], $db['pass'], [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
- PDO::ATTR_EMULATE_PREPARES => false,
- ]);
-} catch (PDOException) {
- return_to_dance_form('unavailable');
-}
-
-$submittedIp = mb_substr((string) ($_SERVER['REMOTE_ADDR'] ?? ''), 0, 45, 'UTF-8');
-if ($submittedIp !== '') {
- $rate = $pdo->prepare('SELECT COUNT(*) FROM dance_applications WHERE submitted_ip = ? AND created_at >= DATE_SUB(NOW(), INTERVAL 2 MINUTE)');
- $rate->execute([$submittedIp]);
- if ((int) $rate->fetchColumn() >= 3) {
- return_to_dance_form('too_many');
- }
-}
-
-$storedFileName = null;
-$originalFileName = null;
-$mimeType = null;
-$fileSize = null;
-$file = $_FILES['reference_file'] ?? null;
-if (is_array($file) && (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_NO_FILE) {
- if ((int) $file['error'] !== UPLOAD_ERR_OK || (int) $file['size'] > $maxUploadBytes) {
- return_to_dance_form('file_too_large');
- }
-
- $allowedMimeTypes = [
- 'image/jpeg' => 'jpg',
- 'image/png' => 'png',
- 'image/gif' => 'gif',
- 'image/webp' => 'webp',
- 'video/mp4' => 'mp4',
- 'video/webm' => 'webm',
- 'video/quicktime' => 'mov',
- ];
- $mimeType = (new finfo(FILEINFO_MIME_TYPE))->file((string) $file['tmp_name']) ?: '';
- if (!isset($allowedMimeTypes[$mimeType])) {
- return_to_dance_form('file_type');
- }
-
- $uploadDir = (string) $config['dance_upload_dir'];
- if (!is_dir($uploadDir) && !mkdir($uploadDir, 0750, true) && !is_dir($uploadDir)) {
- return_to_dance_form('unavailable');
- }
- $storedFileName = bin2hex(random_bytes(20)) . '.' . $allowedMimeTypes[$mimeType];
- if (!move_uploaded_file((string) $file['tmp_name'], $uploadDir . DIRECTORY_SEPARATOR . $storedFileName)) {
- return_to_dance_form('unavailable');
- }
- $originalFileName = mb_substr(basename((string) $file['name']), 0, 255, 'UTF-8');
- $fileSize = (int) $file['size'];
-}
-
-try {
- $stmt = $pdo->prepare(
- 'INSERT INTO dance_applications
- (nickname, email, dance_years, available_date, attended_20th, participate_content, song,
- reference_file_name, reference_original_name, reference_mime_type, reference_file_size,
- message_30th, submitted_ip, user_agent)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
- );
- $stmt->execute([
- $nickname,
- $email,
- $danceYears,
- $availableDate !== '' ? $availableDate : null,
- $attended20th !== '' ? $attended20th : null,
- implode(',', $selectedContent),
- $song !== '' ? $song : null,
- $storedFileName,
- $originalFileName,
- $mimeType,
- $fileSize,
- $message30th !== '' ? $message30th : null,
- $submittedIp !== '' ? $submittedIp : null,
- mb_substr((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255, 'UTF-8'),
- ]);
-} catch (PDOException) {
- if ($storedFileName !== null) {
- @unlink((string) $config['dance_upload_dir'] . DIRECTORY_SEPARATOR . $storedFileName);
- }
- return_to_dance_form('unavailable');
-}
-
-return_to_dance_form('success');
diff --git a/yellow-note/dance-practices-data.php b/yellow-note/dance-practices-data.php
deleted file mode 100644
index 8deaf85..0000000
--- a/yellow-note/dance-practices-data.php
+++ /dev/null
@@ -1,52 +0,0 @@
- PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
- PDO::ATTR_EMULATE_PREPARES => false,
- ]);
- $rows = $pdo->query(
- "SELECT id, title, tags, practice_focus, video_url, difficulty, progress_status,
- note_text, is_featured, sort_order, status
- FROM dance_practice_items
- WHERE status IN ('published', 'coming_soon')
- ORDER BY sort_order, id"
- )->fetchAll();
-} catch (PDOException) {
- http_response_code(503);
- echo json_encode(['ok' => false, 'items' => []], JSON_UNESCAPED_UNICODE);
- exit;
-}
-
-$difficultyLabels = ['easy' => '入門', 'medium' => '中等', 'hard' => '挑戰'];
-$progressLabels = ['not_started' => '未開始', 'practicing' => '練習中', 'review' => '待複習', 'completed' => '已完成'];
-
-$items = array_map(static function (array $row) use ($difficultyLabels, $progressLabels): array {
- $videoUrl = trim((string) ($row['video_url'] ?? ''));
- if ($videoUrl !== '' && (!filter_var($videoUrl, FILTER_VALIDATE_URL) || !preg_match('/^https?:\/\//i', $videoUrl))) {
- $videoUrl = '';
- }
- return [
- 'id' => (int) $row['id'],
- 'title' => (string) $row['title'],
- 'tags' => array_values(array_filter(array_map('trim', explode(',', (string) ($row['tags'] ?? ''))))),
- 'practiceFocus' => (string) $row['practice_focus'],
- 'videoUrl' => $videoUrl,
- 'difficulty' => $difficultyLabels[$row['difficulty']] ?? (string) $row['difficulty'],
- 'progress' => $progressLabels[$row['progress_status']] ?? (string) $row['progress_status'],
- 'note' => (string) ($row['note_text'] ?? ''),
- 'featured' => (bool) $row['is_featured'],
- 'comingSoon' => $row['status'] === 'coming_soon',
- ];
-}, $rows);
-
-echo json_encode(['ok' => true, 'items' => $items], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
diff --git a/yellow-note/practice-room.html b/yellow-note/practice-room.html
deleted file mode 100644
index 6d6b53c..0000000
--- a/yellow-note/practice-room.html
+++ /dev/null
@@ -1,1206 +0,0 @@
-
-
-
-
-
-
-
水晶男孩推廣部|水晶練習室
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SECHSKIES PRACTICE DEMO
- 水晶練習室
- Crystal Practice Room
-
- 水晶練習室是水晶男孩推廣部底下的粉絲向練習工具,結合水晶熱舞社、水晶歌詞社與水晶嘻哈社概念,將歌曲、舞蹈、歌詞、Rap 與應援整理成可以反覆練習的互動頁面。第一版先以舞蹈影片練習與歌詞段落整理為主,未來可擴充唱歌、Rap、應援詞、錄音回放與練習紀錄。
-
-
- 水晶熱舞社
- 水晶歌詞社
- 水晶嘻哈社
- 應援練習
- SECHSKIES Practice
-
-
-
-
-
- 分館功能
- FOUR PRACTICE HALLS
-
-
-
- 水晶熱舞社
- 以舞蹈影片為核心,支援鏡像、慢速播放、逐段練習與 A-B 循環,適合整理經典舞台、翻跳練習與應援舞蹈。
-
-
-
- 水晶歌詞社
- 整理歌曲段落、中文理解、韓文歌詞位置與跟唱提示,未來可加入羅馬拼音、逐句練唱與原唱開關。
-
-
-
- 水晶嘻哈社
- 針對 Rap 段落設計節奏、flow、咬字與慢速練習,未來可加入節拍器與錄音比較。
-
-
-
- 水晶應援社
- 整理演唱會應援詞、口號、手燈節奏與粉絲活動資訊,讓新加入的 Yellowkies 可以更快跟上。
-
-
-
-
-
-
- 舞蹈練習播放器
- DANCE PRACTICE PLAYER
-
-
-
-
-
-
-
-
請放入水晶熱舞社練習影片
-
支援本機或合法來源影片替換
-
-
-
-
-
-
-
-
-
-
-
-
-
- 鏡像
-
-
-
-
- 速度
-
-
-
-
-
-
-
- A-B
-
-
-
-
-
-
-
- A 點:未設定
- B 點:未設定
-
-
-
-
-
-
-
- 練舞清單
- DANCE PRACTICE LIST
-
-
-
-
-
- 段落練習
- SECTION PRACTICE
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 未來擴充
- COMING SOON
-
- - 韓文歌詞 / 羅馬拼音 / 中文理解
- - Rap 節拍器
- - 應援詞練習
- - 錄音回放
- - 錄影回放
- - 練習紀錄
- - 歌曲資料庫
- - 舞台版本比較
- - 30TH 應援企劃串接
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-