Greasy Fork is available in English.

RealTimeCombatting[Typing-Tube]

typing-tube.netにて、リアルタイムでの対戦を実現したい。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name        RealTimeCombatting[Typing-Tube]
// @namespace    http://tampermonkey.net/
// @version      1.38.451
// @description  typing-tube.netにて、リアルタイムでの対戦を実現したい。
// @author       Spacia(の)
// @exclude      https://typing-tube.net/movie/edit*
// @exclude      https://typing-tube.net/movie/show/*?test=test
// @match        ttps://typing-tube.net/
// @grant        none
// @require      https://www.gstatic.com/firebasejs/7.2.1/firebase-app.js
// @require      https://www.gstatic.com/firebasejs/7.2.1/firebase-auth.js
// @require      https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js
// ==/UserScript==

//重要な更新Verの最低値
var ImportantVer = 138451

//バージョンチェック値
var Ver = "1.38.451"

/////////////////////////////////////////////////////////////////////////////////////////////////
//
//firebase Project ? https://console.firebase.google.com/u/0/project/realtimecombatting-typingtube/overview
//Greasy Fork https://greasyfork.org/ja/scripts/391474-realtimecombatting-typing-tube
//テスト譜面 https://typing-tube.net/movie/show/28719
//
//  <参考サイト>
//Firebase初期化方法-Qiita  https://qiita.com/kohashi/items/43ea22f61ade45972881
//js内部から他scriptの読み込み https://teratail.com/questions/41023
//クッキーの使用方法 https://so-zou.jp/web-app/tech/programming/javascript/cookie/
//一意な文字列の作成 https://qiita.com/coa00/items/679b0b5c7c468698d53f
//ポップアップ作成 https://tech-dig.jp/js-modal/
//JavaScriptでHTMLタグを削除する正規表現 https://qiita.com/miiitaka/items/793555b4ccb0259a4cb8
//Divにイベントハンドラを追加 https://blog.keisuke11.com/webdesign/div-watch-js/
//下から出現する固定メニュー http://know-garden.com/%e4%b8%8b%e9%83%a8%e5%9b%ba%e5%ae%9a%e3%83%a1%e3%83%8b%e3%83%a5%e3%83%bc%e3%81%ae%e4%bd%9c%e3%82%8a%e6%96%b903%ef%bc%88%e6%a0%bc%e7%b4%8d%e5%bc%8f%ef%bc%9a%e7%b8%a6%e5%87%ba%e7%8f%be%ef%bc%89/
//Youtube API reference https://developers.google.com/youtube/iframe_api_reference#Playback_controls
//JavaScriptで連想配列に対してforEachループを使う方法 https://pisuke-code.com/javascript-dictionary-foreach/
//
/////////////////////////////////////////////////////////////////////////////////////////////////


/**
 * TypingTubeのサーバー時刻を取得します。取得したサーバー時刻を一定間隔で更新し、ログイン or ログアウトの状態をユーザー間で確認し合います。
 * @param LocationDateTimeStamp {number} サーバー時刻のタイムスタンプ
 * @param LocalDateTimeStamp {number} サーバー時刻を取得出来たときのローカル時刻のタイムスタンプ
 */


let LocationDateTimeStamp
let LocalDateTimeStamp
const GetLocationDate = async () => {
	const resp = await fetch(window.location.href)
	//サーバー時刻のタイムスタンプ
	LocationDateTimeStamp = await new Date(resp.headers.get("date")).getTime()
	//ローカル時刻タイムスタンプ
	LocalDateTimeStamp = new Date().getTime()

	//LocationDateTimeStamp + (new Date().getTime() - LocalDateTimeStamp)
	//サーバー時刻のタイムスタンプ + (現在のローカル時刻 - ローカル時刻タイムスタンプ)
	//上記の計算で環境の違いでズレない時刻を取得

	////////////////////////////////////////////////////////////////////

	//サーバー時刻取得後、現在ログインしていない部屋とユーザー情報を削除
	deleteIdlePlayerAndRoom();
	return true
}


/*
*@note サーバー時刻を取得 ここまで---
**/




/////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * @note RealTimeCombatting ON/OFF 切り替えスイッチをヘッダーに追加 ここから ---
*/


let RTC_Switch = sessionStorage.getItem("RTC_Switch") == "true"

document.querySelector('[data-sa-action="search-open"]').parentNode.insertAdjacentHTML('afterend',`<li id="RTC_Switch"><a class="" id="notify_room" data-sa-action="combat" style="
    padding-bottom: 1.5rem;
    padding-top: 0.6rem;
    position: relative;
    top: 5px;
  "><span style="
    position: absolute;
    top: 4.1em;
    margin: auto;
    font-size: 0.5em;
    left: 50%;
    transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    -ms-transform: translateX(-50%);
    font-weight: 600;
    color:`+(RTC_Switch ? "gold" : "")+`;
  ">`+(RTC_Switch ? "ON" : "OFF")+`</span>
 <i class="fas fa-users"></i></a></li>`)


//ON/OFF 切り替えスイッチクリック時イベント
document.getElementById("RTC_Switch").addEventListener("click",function RTC_Switcher(event){
	if(sessionStorage.getItem("RTC_Switch") == "true"){

		sessionStorage.setItem("RTC_Switch", "false")
		document.getElementById("RTC_Switch").removeEventListener("click",RTC_Switcher)
		if(isEnter){
			ExitRoom()
		}
		location.reload();
	}else if(sessionStorage.getItem("RTC_Switch") == "false" || !sessionStorage.getItem("RTC_Switch")){
		sessionStorage.setItem("RTC_Switch", "true")
		document.getElementById("RTC_Switch").removeEventListener("click",RTC_Switcher)
		location.reload();
	}
})


AddStyles();

/**
 *@note RealTimeCombatting切り替えスイッチをヘッダーに追加 ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////



(function() {
    'use strict';
	if(RTC_Switch || location.href.indexOf("https://typing-tube.net/movie")<0){
		SetUpFirebase();
	}
})();



/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note Firebase初期化ここから ---
*/

/**
*@Description Firebaseを使用可能状態にセットアップ (SDKのロード、初期化)
*/
function SetUpFirebase(){
	// <!-- The core Firebase JS SDK is always required and must be listed first -->
//	loadScript(["https://www.gstatic.com/firebasejs/7.2.1/firebase-app.js" , "https://www.gstatic.com/firebasejs/7.2.1/firebase-auth.js" , "https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js"])
//		.then(function(){
		InitFirebase(RoginAnon);
//	});
}

/**
*@Description urlで指定したscriptファイルを読み込みます。
*@param url 読み込むscriptファイル
*@param callback

function loadScript( urls ){
	return Promise.all( urls.map(function(url){return new Promise(function(resolve,reject){
		var script = document.createElement('script');
	  script.src = url;
	  script.onload=resolve;
	  document.head.appendChild(script);
  })}));

}
*/
/**
*@Description Firebaseの初期化作業、SDKの読み込み後、使用する前に呼び出す。
*@param callback
*/


function InitFirebase(callback){

    // Your web app's Firebase configuration
    var firebaseConfig = {
		/*
		RealTimeCombatting"TypingTube" データベース(非公式)
		https://console.firebase.google.com/u/1/project/realtimecombatting-typingtube/database/realtimecombatting-typingtube/data
        apiKey: "AIzaSyACA8ARVyv9vawk9BAfoaKg5Cl8dsNGItM",
        authDomain: "realtimecombatting-typingtube.firebaseapp.com",
        databaseURL: "https://realtimecombatting-typingtube.firebaseio.com",
        projectId: "realtimecombatting-typingtube",
        storageBucket: "realtimecombatting-typingtube.appspot.com",
        messagingSenderId: "62043628528",
        appId: "1:62043628528:web:3ab013403b1f3ed9383335",
        measurementId: "G-1P2BBSLWYW"
		*/

		/*
		TypingTube データベース(公式)
		*/
		apiKey: "AIzaSyDAsof24N3Ikx3vpKegkmhVYo6j1ejx2Ss",
		authDomain: "api-project-959901312274.firebaseapp.com",
		databaseURL: "https://typingtube.firebaseio.com",
		projectId: "api-project-959901312274",
		storageBucket: "api-project-959901312274.appspot.com",
		messagingSenderId: "959901312274",
		appId: "1:959901312274:web:f78a1d9339b573bbdc7fcb",
		measurementId: "G-04HLEDZM"
    };
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
	if(location.href.indexOf("https://typing-tube.net/movie/") == -1){
    callback();
	}
}

/**
*@note Firebase初期化ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////








/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note ログイン関係 ここから---
*/

var userName;
var myID;
var prevTS = new Date().getTime()
var playing = false;
let Latest_Ver
/**
*@Description ユーザの匿名ログイン
*@return bool  true:ログインに成功
*/
function RoginAnon(){

    firebase.auth().signInAnonymously().catch(function(error) {
        // Handle Errors here.
        var errorCode = error.code;
        var errorMessage = error.message;

        console.log(errorCode);
        console.log( errorMessage);
        alert("RealTimeCombatting:Firebaseのサインインに失敗しました。");
        return false;
        // ...
    });
    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            // User is signed in.
            var isAnonymous = user.isAnonymous;
            myID = "U"+user.uid;
			if(RTC_Switch){
				var path = firebase.database().ref('users/' + myID);
				//ユーザーネーム取得
				userName = document.querySelector("body > main > aside > aside > div > div.scrollbar-inner.scroll-content > div > div.user__info > div > div.user__name").innerHTML;
				path.transaction(function(currentData) {
					//プレイステータスをすべて初期値に戻す
					var updates = {};
					updates['/users/' + myID + '/name'] = userName;
					localStorage.setItem("RTCAfkTS", prevTS)
					updates['/users/' + myID + '/ver'] = Ver;
					firebase.database().ref().update(updates);
					firebase.database().ref('users/' + myID).once('value').then(user => {
						roomID = user.val().roomID;
					});
					firebase.database().ref('Version').once('value').then(Version => {
						Latest_Ver = Version.val()
					})
					//afkタイムアウト用
					timeStampForAFK = new Date().getTime();
					isWrittenAFKState = false;
					$('body').on('keydown mousedown mousemove',function(){
						timeStampForAFK = new Date().getTime();
						if(isWrittenAFKState == true){
							var updates = {};
							isWrittenAFKState = false;
							updates['/users/' + myID + "/state"] = prevState;
							if(LocationDateTimeStamp){
							updates['/users/' + myID + '/DeletetimeStamp'] = LocationDateTimeStamp+(new Date().getTime()-LocalDateTimeStamp)
							}
							firebase.database().ref().update(updates);
						}
					});
					checkMultipleOpen();
				});
			}else{
				GetLocationDate().then( () => {
					firebase.database().ref('rooms').once('value').then(_room => {
						if(location.href.indexOf("https://typing-tube.net/movie")<0&&_room.val()){
							document.getElementById("notify_room").classList.add("top-nav__notify_room");
						}
					})
					UpdateCheck()
				})
			}
			// ...
		} else {
            // User is signed out.
            // ...
             var _path = firebase.database().ref('users/' + myID);
            if(_path.name != null){
                _path.remove();
            }
        }
        // ...
    });

    return true;
}


var AFK_TIMEOUT = 60000;
var timeStampForAFK;
var isWrittenAFKState;
var prevState;
let RoomUserAfkWriteClock = 0
/**
*@Description ユーザーのタイムスタンプ書き換え
*/

function ClockWriteTimeStamp(){
const new_Date = new Date().getTime()
var updates = {};
    //afkTimeout
    if(new_Date > AFK_TIMEOUT + timeStampForAFK && playing == false && prevState == "idle"){
        if(isWrittenAFKState == false){
            firebase.database().ref('users/' + myID).once('value').then(user => {
					isWrittenAFKState = true;
					updates['/users/' + myID + "/state"] = "afk";
					firebase.database().ref().update(updates);
			});
		}
	}



	if(LocationDateTimeStamp){
		updates['/users/' + myID + '/DeletetimeStamp'] = LocationDateTimeStamp+(new_Date-LocalDateTimeStamp)

		if(!playing && new_Date - RoomUserAfkWriteClock >= 30000){
			RoomUserAfkWriteClock = new_Date
			firebase.database().ref('rooms/' + roomID + '/users').once('value').then(room_users => {
				firebase.database().ref('users').once('value').then(user => {
					var updates = {}
					for (let room_user_key in room_users.val()) {
						const TimeOut_time = LocationDateTimeStamp+(new_Date-LocalDateTimeStamp) - eval("user.val()."+room_user_key+".DeletetimeStamp")
						if(room_user_key != myID){
							if(TimeOut_time >= 50000){
								ForcePlayerDelete(room_user_key, null)
							}else if(TimeOut_time >= 20000){
								updates['/users/' + room_user_key + '/state'] = "timeOut"

							}
						}
					}
					firebase.database().ref().update(updates);
				});
			});
		}
	}

	firebase.database().ref().update(updates);
}

var checkNum = 0;
var CHECK_MAX = 5;
var isChecking = true;
/**
*@Description 2窓チェック
*/
function checkMultipleOpen(){
	if(isChecking){
		if(myID){
			firebase.database().ref('users/' + myID).once('value').then(user => {
				var ts = localStorage.getItem("RTCAfkTS");
				if(prevTS != ts){

					let alert_tag = document.createElement('b');
					alert_tag.textContent = "RealTimeCombatting:2窓アクセスが検出されました。このウィンドウでは対戦をすることができません。"
					let contentTag = document.getElementsByClassName("quick-stats")[0];
					contentTag.parentNode.insertBefore(alert_tag, contentTag);
					contentTag.parentNode.insertBefore(alert_tag, contentTag);
					RTC_Switch = false

				}else{
					checkNum++;

					if(checkNum > CHECK_MAX){
						isChecking = false;
						//対戦用のデータ読み込み + 対戦用の表示領域を作成。
						LoadFirebaseData();
						setInterval(ClockWriteTimeStamp,5000)
					}
					setTimeout(() => {
						checkMultipleOpen();
					}, 100);
				}
			});
		}else{
			setTimeout(() => {
				checkMultipleOpen();
			}, 100);
		}
	}
}


/**
*@Description 対戦用のデータ読み込み + 対戦用の表示領域を作成。
*/
	let First_Load_Room_Existence_flag = false
function LoadFirebaseData(){

	var updates = {};
if(location.href.indexOf("https://typing-tube.net/movie")==0 && player.getVideoData().title == ""){
	updates['/users/' + myID + '/state'] = prevState = "not_playable";
}else{
	updates['/users/' + myID + '/state'] = prevState = "idle";
}
	firebase.database().ref().update(updates);
    //対戦用のインタラクティブエリア作成
    CreateRTCElement();

    //チャット欄自動更新
    var chats = firebase.database().ref('chats').limitToLast(10);
    chats.on('child_added', onChatUpdate);

    //Room情報自動更新
    var rooms = firebase.database().ref('rooms');
    rooms.on('child_added', onAddRoom);
    rooms.on('child_changed', onChangeRoom);
    rooms.on('child_removed', onRemoveRoom);

    //初めの数秒は音を鳴らさない
    isSECancel = true;
    setTimeout(function(){
        isSECancel = false;
    }, 1500);

    //ルームにすでに入っているか
    if(roomID != null){
        EnterRoom(roomID);
    }else{
		First_Load_Room_Existence_flag = true
	}


    GetLocationDate().then( () => {
		var updates = {};
		updates['/users/' + myID + '/DeletetimeStamp'] = LocationDateTimeStamp+(new Date().getTime()-LocalDateTimeStamp)
		firebase.database().ref().update(updates);
		First_Load_Room_Existence_flag = false
		setTimeout(function(){
			if(document.getElementById("Room_Existence") != null){
				document.getElementById("Room_Existence").remove()
			}
		},200)
	})
}



/**
*@note ログイン関係 ここまで---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////








/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note 対戦用のインタラクティブエリア作成 ここから---
*/

var DOMContainer;
var DOMChatInput;
var movieID;
var movieTitle;
var RTCselectingMode;
var WindowBlur


/**
*@Description 対戦用のインタラクティブエリア作成 ルート
*/
function CreateRTCElement(){
    //動画の再生を無効化
    var playarea = document.getElementsByClassName("playarea")[0];
    if(playarea != null){
        playarea.classList.add("is-hide");
		document.getElementsByClassName("status")[0].classList.add("flex_100");

    }

	//2窓チェック用のtimestampをlocalStorageに保存
	window.addEventListener("blur",function WindowBlurTimeStamp(event){
		if(!WindowBlur){
			WindowBlur = setInterval(function(){
					const new_Date = new Date().getTime()
					localStorage.setItem("RTCAfkTS", new_Date)
				if(LocationDateTimeStamp){
					var updates = {}
					updates['/users/' + myID + '/DeletetimeStamp'] = LocationDateTimeStamp+(new_Date-LocalDateTimeStamp)
					firebase.database().ref().update(updates);
				}
				},400)
		}
	})

	window.addEventListener("focus",function(){
		if(WindowBlur){
			clearInterval(WindowBlur)
			WindowBlur = 0
		}
            firebase.database().ref('users/' + myID).once('value').then(user => {
				var updates = {}
				if(LocationDateTimeStamp){
					const new_Date = new Date().getTime()
					updates['/users/' + myID + '/name'] = userName
					updates['/users/' + myID + '/ver'] = Ver;
				}
				if(user.val().state == null){
					updates['/users/' + myID + '/state'] = "idle"
				}
				firebase.database().ref().update(updates);
				ClockWriteTimeStamp()
			})
	})

window.addEventListener('beforeunload', function(){
	if(!playing){
	var updates = {}
	updates['/users/' + myID + '/state'] = "idle"
	firebase.database().ref().update(updates);
	}
});
    CreateContainer();
    CreateStatusArea();
    CreateChatArea();
	UpdateCheck();
}





/**
*@note スタイルを追加---
*/
function AddStyles(){
    var DOMstyle = document.createElement("style");
    DOMstyle.setAttribute("type","text/css");
    DOMstyle.innerHTML = `
#ranking ::-webkit-scrollbar {
    width: 10px;
    background-color: hsla(0,0%,100%,.025);
    -webkit-border-radius: 100px;
}
#ranking ::-webkit-scrollbar-thumb {
    background: hsla(0,0%,100%,.5);
    -webkit-border-radius: 100px;
    background-clip: padding-box;
    border: 2px solid hsla(0,0%,100%,0);
    min-height: 10px;
}
#RTCRoomPlayers::-webkit-scrollbar{display:block;}/*バーの太さ*/
#RTCRoomPlayers::-webkit-scrollbar-thumb{display:block;background: #8b8b8b;border-radius: 1em;}

#RTCRoomPlayers::-webkit-scrollbar-thumb:hover{display:block;background: #8b8b8b;}
#RTCRoomPlayers::-webkit-scrollbar-thumb:active{background: #555555;}
.top-nav__notify_room:before {
    content: '';
    width: 5px;
    height: 5px;
    background-color: #fff;
    color: #fff;
    border-radius: 50%;
    position: absolute;
    top: -6.4px;
    right: 0;
    left: 0;
    margin: auto;
    -webkit-animation-name: flash;
    animation-name: flash;
    -webkit-animation-duration: 2s;
    animation-duration: 2s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-iteration-count: infinite;
    animation-iteration-count: infinite;
}
        .popup {
     position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        z-index: 101;
        opacity: 0;
        visibility: hidden;
		background:rgb(255 255 255 / 10%);
        }

        .is-show {
        opacity: 1;
        visibility: visible;
        }
        .is-hide {
        opacity:0;
        visibility: hidden;
        display:none;
        }
        .flex_100{
        flex:0 0 100%;
        max-width:100%;
        }
        .popup-inner {
        position: absolute;
        left: 50%;
        top: 40%;
        transform: translate(-50%,-50%);
        width: 60%;
        height:340px;
        padding: 10px;
        background-color: rgba(0, 0, 0, 0.96);
        z-index: 100;
        }
		.popup-text-area{
        background-color:rgba(0,0,0, 0.2);
        color:white;
        margin:4px 4px 10px;
        width:80%;
        border: none;
        border-bottom: solid thin;
        }
         .mine {
        color:#e65c00;
        }

        .RTCLine {
		font-size:13px;
        }

        .RTCLine:after{content:'\u200b';}

        .chatArea {
        display: none;
        width: 100%;
        position: fixed;
        background-color: rgb(0 0 0 / 78%);
        bottom: 0;
        z-index:101;
        }

        .is-disable {
        disabled:true;
        }

        .is-DifferInMovieID {
        color:#e6e600;
        }
        .count {
        display:none;
        }
       .select_area{
       font-weight: 600;
       display: flex;
       justify-content: flex-start;
       align-items: center;
       margin-top: 13px;
       margin-right: 10px;
       margin-left: 5px;
       }
        select {
        font-weight: 600;
        padding: 5px 8px;
        width: 130%;
        color:#FFF;
        box-shadow: none;
        background-color: #000000CC;
        background-image: none;
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        border-radius: 5px;
        width: auto;
        }
        select:focus {
        outline: none;
        }
        select:hover{
        background:#1E90FF;
        }
        option{
        background:#333;
        color:#FFF;
       }
        .ready_background_color{
        background: #5eff8330;
       }
    .display_AutoStart{
    display: flex!important;
    justify-content: flex-end;
    align-items: center;
    }
    .display_AutoMove{
    display: flex!important;
    justify-content: flex-end;
    align-items: center;
    }
.ready_loading{
    background: #ffffff38;
}

.rtc-button {
    vertical-align: middle;
    user-select: none;
    border:1.5px solid transparent;
    padding: .6rem 1rem;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.25;
    border-radius: 2px;
    transition: all .15s ease-in-out;
    cursor:pointer;
}

[value="準備完了"],[value="ゲーム開始"] {
    color: #56e576;
    background-color: transparent;
    background-image: none;
    border-color: #56e576!important;
}
[value="準備完了"]:hover,[value="ゲーム開始"]:hover {
    color: #fff;
    background-color: #56e576b3;
    border-color: #56e576b3!important;
    text-shadow: 0.5px 0.5px 0px #333, -0.5px -0.5px 0px #333, -0.5px 0.5px 0px #333, 0.5px -0.5px 0px #333, 0.5px 0px 0px #333, -0.5px 0px 0px #333, 0px 0.5px 0px #333, 0px -0.5px 0px #333;
}
[value="ルームを退出"]{
    color: #ffc107;
    background-color: transparent;
    background-image: none;
    border-color: #ffc107!important;
    border: 1px solid!important;
}
[value="ルームを退出"]:hover {
    color: #fff;
    background-color: #ffc107a6;
    border-color: #ffc107c9!important;
    text-shadow: 0.5px 0.5px 0px #333, -0.5px -0.5px 0px #333, -0.5px 0.5px 0px #333, 0.5px -0.5px 0px #333, 0.5px 0px 0px #333, -0.5px 0px 0px #333, 0px 0.5px 0px #333, 0px -0.5px 0px #333;
}
[value="準備完了を解除"]{
    color:#00dcff;
    background-color: transparent;
    background-image: none;
    border-color:#17a2b8!important;
    border: 1px solid!important;
}
[value="準備完了を解除"]:hover {
    color: #fff;
    background-color:#00dcffa6;
    border-color:#17a2b8!important;
    text-shadow: 0.5px 0.5px 0px #333, -0.5px -0.5px 0px #333, -0.5px 0.5px 0px #333, 0.5px -0.5px 0px #333, 0.5px 0px 0px #333, -0.5px 0px 0px #333, 0px 0.5px 0px #333, 0px -0.5px 0px #333;
}
`
        ;
    document.querySelector("head").appendChild(DOMstyle);
}

/**
*@note コンテナ作成---
*/
function CreateContainer(){
    DOMContainer = document.createElement("div");
    DOMContainer.classList.add('w-100');
    DOMContainer.id = "RTCContainer";
    DOMContainer.setAttribute("style","border-style: solid;border-color: #f5f5f5;border-width: 2px;margin-top:10px;z-index:5;");

    if(/movie\/show/.test(location.pathname)){
        const parent = CONTROLBOX_SELECTOR;
        parent.appendChild(DOMContainer);
        //var parent = after.parent();
        //parent.insertBefore(DOMContainer, after );
        movieID = location.pathname.match(/\/\w+/g)[2].match(/\d+/g)[0];
        movieTitle = document.querySelector(".movietitle > h1").innerHTML.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'');
    }else{
        const parent = document.querySelector("#main_content");
        parent.prepend(DOMContainer);
        movieID = 0;
        movieTitle = " ";
    }
}

/**
*RTCステータスエリア作成
*/
function CreateStatusArea(){
    var DOMStatus = document.createElement("div");
	DOMStatus.setAttribute("id","RTCStatus_Area");
	DOMStatus.setAttribute("style","height:300px;padding:0px 10px;");
    DOMContainer.appendChild(DOMStatus);

    CreateRoomSelectScene(DOMStatus);
    CreateRoomIdleScene(DOMStatus);
    CreateGamePlayScene(DOMStatus);
}

/**
*ルーム選択画面作成
*/
function CreateRoomSelectScene(parent){
    var DOMRoomSelectScene = document.createElement("div");
    DOMRoomSelectScene.setAttribute("style","width:100%");

    DOMRoomSelectScene.id = "RTCRoomSelectScene";
    parent.appendChild(DOMRoomSelectScene);

    var DOMp = document.createElement("p");
    DOMp.setAttribute("style","font-size:18px;margin:10px 0;");
    DOMp.innerHTML = "ルームを選択";
    DOMRoomSelectScene.appendChild(DOMp);

    var DOMRooms = document.createElement("ul");
    DOMRooms.setAttribute("style","height:200px;overflow-y:auto;margin:0;padding:0;");
    DOMRooms.id = "RTCRooms";
    DOMRoomSelectScene.appendChild(DOMRooms);

    var DOMNoRoomMes = document.createElement("p");
    DOMNoRoomMes.setAttribute("style","display:hidden;font-size:14px;padding-top:90px;text-align: center;");
    DOMNoRoomMes.id = "noRoomMes";
    DOMNoRoomMes.innerHTML = "現在ルームが存在しません。";
    DOMRooms.appendChild(DOMNoRoomMes);

    var DOMUIs = document.createElement("div");
    DOMUIs.setAttribute("style","height:30px;margin:10px 0; padding:0");
    DOMRoomSelectScene.appendChild(DOMUIs);

    var DOMCreateNewRoom = document.createElement("input");
    DOMCreateNewRoom.setAttribute("type","button");
	DOMCreateNewRoom.setAttribute("class","rtc-button");
    DOMCreateNewRoom.setAttribute("value","新しくルームを作成");
    DOMCreateNewRoom.addEventListener("click", onClickCreateNewRoom);
    DOMUIs.appendChild(DOMCreateNewRoom);

    CreateModalForCreateNewRoom();
}

/**
*ルーム新規作成用モーダルの作成
*/
function CreateModalForCreateNewRoom(){
    var DOMpopup = document.createElement("div");
    DOMpopup.classList.add("popup");
    DOMpopup.id = "createNewRoom";
    document.getElementsByTagName("body")[0].appendChild(DOMpopup);

    var DOMpopupInner = document.createElement("div");
    DOMpopupInner.classList.add("popup-inner");
    DOMpopup.appendChild(DOMpopupInner);

    var DOMdiv = document.createElement("div");
    DOMdiv.setAttribute("style","height:80%;");
    DOMpopupInner.appendChild(DOMdiv);

    var DOMp = document.createElement("p");
    DOMp.setAttribute("style","font-size:18px;margin:4px 0 20px;");
    DOMp.innerHTML = "新しく対戦ルームを作成";
    DOMdiv.appendChild(DOMp);

    var DOMlabelRoomName = document.createElement("label");
    DOMlabelRoomName.setAttribute("for","roomName");
    DOMlabelRoomName.setAttribute("style","font-size:14px;margin:4px 0;width:20%;");
    DOMlabelRoomName.innerHTML = "ルーム名: ";
    DOMdiv.appendChild(DOMlabelRoomName);

    var DOMroomName = document.createElement("input");
    DOMroomName.id = "roomName";
    DOMroomName.setAttribute("type","text");
    DOMroomName.setAttribute("name","roomName");
    DOMroomName.setAttribute("maxlength","19");
	DOMroomName.setAttribute("class","popup-text-area");
    DOMroomName.setAttribute("value", userName + "'s room");
    DOMdiv.appendChild(DOMroomName);

    var DOMbr = document.createElement("br");
    DOMdiv.appendChild(DOMbr );

    var DOMlabelDescription = document.createElement("label");
    DOMlabelDescription.setAttribute("for","roomDescription");
    DOMlabelDescription.setAttribute("style","font-size:14px;margin:4px 0;width:20%;");
    DOMlabelDescription.innerHTML = "詳細: ";
    DOMdiv.appendChild(DOMlabelDescription);

    var DOMDescription = document.createElement("input");
    DOMDescription.id = "roomDescription";
    DOMDescription.setAttribute("type","text");
    DOMDescription.setAttribute("name","roomName");
    DOMDescription.setAttribute("maxlength","64");
    DOMDescription.setAttribute("value", "誰でもわいわい!");
	DOMDescription.setAttribute("class","popup-text-area");
    DOMdiv.appendChild(DOMDescription);

    var DOMPassWord = document.createElement("label");
    DOMPassWord.setAttribute("style","display:flex;align-items: center;margin-top:10px;");
	DOMPassWord.innerHTML = `<span style="font-size: 14px;margin: 0 5px  0 0;">パスワード設定:</span>
                             <input type="checkbox" id="Enable_PassWord">`
    DOMdiv.appendChild(DOMPassWord);

	DOMPassWord.addEventListener("change",function(){
		if(document.getElementById("Enable_PassWord").checked){
			document.getElementById("roomPassWordArea").style.display = "block"
		}else{
			document.getElementById("roomPassWordArea").style.display = "none"
		}
	})


    var DOMPassWordArea = document.createElement("input");
    DOMPassWordArea.id = "roomPassWordArea";
    DOMPassWordArea.setAttribute("type","text");
    DOMPassWordArea.setAttribute("name","roomName");
    DOMPassWordArea.setAttribute("maxlength","64");
    DOMPassWordArea.setAttribute("value", "");
	DOMPassWordArea.setAttribute("class","popup-text-area");
	DOMPassWordArea.setAttribute("style","display:none;");
    DOMdiv.appendChild(DOMPassWordArea);


    var DOMdiv2 = document.createElement("div");
    DOMdiv2.setAttribute("style","height:20%;");
    DOMpopupInner.appendChild(DOMdiv2);

    var DOMbuttonCreate = document.createElement("input");
    DOMbuttonCreate.setAttribute("type","button");
    DOMbuttonCreate.setAttribute("value","ルームを作成");
	DOMbuttonCreate.setAttribute("class","btn btn-light");
    DOMbuttonCreate.setAttribute("style","margin:4px 4px");
    DOMbuttonCreate.addEventListener("click", onClickCreateRoom);
    DOMdiv2.appendChild(DOMbuttonCreate);

    var DOMbuttonCancel = document.createElement("input");
    DOMbuttonCancel.setAttribute("type","button");
    DOMbuttonCancel.setAttribute("value","キャンセル");
	DOMbuttonCancel.setAttribute("class","btn btn-light");
    DOMbuttonCancel.setAttribute("style","margin:4px 4px");
    DOMbuttonCancel.addEventListener("click", onClickCancel);
    DOMdiv2.appendChild(DOMbuttonCancel);
}

/**
*ルーム待機画面作成
*/
function CreateRoomIdleScene(parent){
    var DOMRoomIdleScene = document.createElement("div");
     DOMRoomIdleScene.setAttribute("style","width:100%");

    DOMRoomIdleScene.id = "RTCRoomIdleScene";
    DOMRoomIdleScene.classList.add('is-hide');
    parent.appendChild(DOMRoomIdleScene);

    var DOMp = document.createElement("p");
    DOMp.setAttribute("style","font-size:18px;margin:10px 0;");
    DOMp.id = "RTCRoomName";
    DOMp.innerHTML = "ルーム";
    DOMRoomIdleScene.appendChild(DOMp);

    var DOMRoomWrapper = document.createElement("div");
    DOMRoomWrapper.setAttribute("style","height:200px;margin:0;padding:0;");
    DOMRoomWrapper.id = "RTCRoomWrapper";
    DOMRoomIdleScene.appendChild(DOMRoomWrapper);


    var DOMRoomPlayers = document.createElement("div");
    DOMRoomPlayers.setAttribute("style","height:100%;width:47%;margin:0 5px;padding:0;display:inline-block;vertical-align: top;background-color:rgba(0,0,0, 0.2);font-size:12px;overflow-y:auto;");
    DOMRoomPlayers.id = "RTCRoomPlayers";
    DOMRoomWrapper.appendChild(DOMRoomPlayers);

    var DOMAutoStart = document.createElement("label");
    DOMAutoStart.setAttribute("style","float: right;display: none;");
    DOMAutoStart.innerHTML = `<input id="RTC_AutoStart" type="checkbox">自動開始`;
    DOMRoomPlayers.appendChild(DOMAutoStart);

	DOMAutoStart.addEventListener("change",function(event){
		if(isRoomMaster){
			var updates = {}
			if(event.target.checked){
				updates['/rooms/' + roomID + '/AutoStart'] = true;
			}else{
				updates['/rooms/' + roomID + '/AutoStart'] = false;
				if(prevState == "Auto_ready"){
					prevState = "idle"
					updates['users/' + myID + '/state'] = "idle";
				}
			}
			firebase.database().ref().update(updates);
		}
	})


    var DOMThead = document.createElement("P");
	DOMThead.id = "RTCRoomPlayerCount";
    DOMThead.innerHTML = "参加者一覧";
    DOMRoomPlayers.appendChild(DOMThead);

    var DOMTable = document.createElement("table");
    DOMTable.setAttribute("rules","all");
    DOMTable.setAttribute("border","1");
    DOMTable.id = "RTCRoomPlayersTable";
    DOMRoomPlayers.appendChild(DOMTable);

    var DOMRoomInfo = document.createElement("div");
    DOMRoomInfo.setAttribute("style","height:100%;width:47%;margin:0 5px;padding:0;display:inline-block;vertical-align: top;background-color:rgba(0,0,0, 0.2);font-size:12px;overflow-y:auto;");
    DOMRoomInfo.id = "RTCRoomInfo";
    DOMRoomWrapper.appendChild(DOMRoomInfo);

    var DOMAutoMove = document.createElement("label");
    DOMAutoMove.setAttribute("style","float: right;display: none;");
    DOMAutoMove.innerHTML = `<input id="RTC_AutoMove" type="checkbox"`+(localStorage.getItem("RTC_AutoMove") == "true" ? "checked" : "")+`>譜面ページ自動遷移`;
    DOMRoomInfo.appendChild(DOMAutoMove);
	DOMAutoMove.addEventListener("change",function(event){
		if(!isRoomMaster){
			localStorage.setItem("RTC_AutoMove",event.target.checked)
			if(event.target.checked && document.getElementById("RTCRoomMovieTitle").href != "https://typing-tube.net/movie/show/null" && window.location.href != document.getElementById("RTCRoomMovieTitle").href){
				window.location.href = document.getElementById("RTCRoomMovieTitle").href
			}
		}
	})


    var DOMplayModeMes = document.createElement("p");
    DOMplayModeMes.innerHTML = "プレイモード";
    DOMRoomInfo.appendChild(DOMplayModeMes);


    var DOMmovieTitleDiv = document.createElement("div");
    DOMmovieTitleDiv.id  = "RTCmovieTitleDiv";
    DOMmovieTitleDiv.setAttribute("style","margin:5px 5px;");
    DOMRoomInfo.appendChild(DOMmovieTitleDiv);

    var DOMmovieTitleMes = document.createElement("span");
    DOMmovieTitleMes.setAttribute("style","color:inherit;");
    DOMmovieTitleMes.innerHTML = "楽曲: "
    DOMmovieTitleDiv.appendChild(DOMmovieTitleMes);

    var DOMmovieTitleU = document.createElement("u");
    DOMmovieTitleDiv.appendChild(DOMmovieTitleU);

    var DOMmovieTitleA = document.createElement("a");
    DOMmovieTitleA.setAttribute("style","color:inherit;font-weight:600;");
    DOMmovieTitleA.id = "RTCRoomMovieTitle";
    DOMmovieTitleU.appendChild(DOMmovieTitleA);


    var DOMselectingMes = document.createElement("span");
    DOMselectingMes.innerHTML = "ルームマスターがプレイする曲を選択中です。 ";
    DOMselectingMes.id = "RTCMovleSelectingMes";
    DOMRoomIdleScene.classList.add('is-hide');
    DOMmovieTitleDiv.appendChild(DOMselectingMes);

    var DOMselectingMesRM = document.createElement("span");
    DOMselectingMesRM.innerHTML = "プレイする曲を選択してください。 ";
    DOMselectingMesRM.id = "RTCMovleSelectingMesRM";
    DOMselectingMesRM.classList.add('is-hide');
    DOMmovieTitleDiv.appendChild(DOMselectingMesRM);


    var DOMplaySpeedDiv = document.createElement("div");
    DOMplaySpeedDiv.setAttribute("style","margin:5px 5px;");
    DOMRoomInfo.appendChild(DOMplaySpeedDiv);

    var DOMplaySpeedMes = document.createElement("span");
    DOMplaySpeedMes.innerHTML = "プレイ速度: "
    DOMplaySpeedDiv.appendChild(DOMplaySpeedMes);

    var DOMbtSpeedlt = document.createElement("a");
	if(typeof title_speed != "number"){
    DOMbtSpeedlt.addEventListener("click", onClickPlaySpeedlt);
}
    DOMbtSpeedlt.innerHTML = " - ";
    DOMbtSpeedlt.setAttribute("style","margin:5px 5px;");
    DOMbtSpeedlt.id = "RTCPlaybtSpeedlt";
    DOMbtSpeedlt.classList.add('is-hide');
    DOMbtSpeedlt.setAttribute("title","プレイ速度を遅くする");
    DOMplaySpeedDiv.appendChild(DOMbtSpeedlt);

    var DOMplaySpeedSpan = document.createElement("span");
    DOMplaySpeedSpan.id = "RTCPlaySpeedSpan";
    DOMplaySpeedSpan.innerHTML = typeof title_speed == "number" ? title_speed.toFixed(2)+"倍" : "1.00倍"
    DOMplaySpeedDiv.appendChild(DOMplaySpeedSpan);

    var DOMbtSpeedgt = document.createElement("a");
	if(typeof title_speed != "number"){
    DOMbtSpeedgt.addEventListener("click", onClickPlaySpeedgt);
	}
    DOMbtSpeedgt.innerHTML = " + ";
    DOMbtSpeedgt.id = "RTCPlaybtSpeedgt";
    DOMbtSpeedgt.classList.add('is-hide');
    DOMbtSpeedgt.setAttribute("title","プレイ速度を速くする");
    DOMbtSpeedgt.setAttribute("style","margin:5px 5px;");
    DOMplaySpeedDiv.appendChild(DOMbtSpeedgt);


    var DOMPlayMideDiv = document.createElement("div");
    DOMPlayMideDiv.id = "RTCPlayModeDiv";
    DOMRoomInfo.appendChild(DOMPlayMideDiv);

    var DOMlabel1 = document.createElement("label");
    DOMlabel1.setAttribute("style","font-size:7px;margin:0 0 0 5px");
    DOMlabel1.setAttribute("for","rbModeKana");
    DOMlabel1.innerHTML = "かな表示";
    DOMRoomInfo.appendChild(DOMlabel1);

    var DOMrb1 = document.createElement("input");
    DOMrb1.id = "rbModeKana";
    DOMrb1.setAttribute("type","radio");
    DOMrb1.setAttribute("name","rbPlayMode");
    DOMrb1.setAttribute("checked","checked");
    DOMrb1.setAttribute("value","kana");
    DOMrb1.addEventListener("change", function(){
        mode = 'kana';
        kana_mode = false;
        keyboard='normal';
        RTCselectingMode = mode;
        WriteToCookie('cookieRTCselectingMode', 'roma1');
		var updates = {};
		updates['users/' + myID + '/status/InputMode'] = "ローマ字";
		firebase.database().ref().update(updates);
    });
    DOMRoomInfo.appendChild(DOMrb1);
	var updates = {};
	updates['users/' + myID + '/status/InputMode'] = "ローマ字";
	firebase.database().ref().update(updates);

    var DOMlabel2 = document.createElement("label");
    DOMlabel2.setAttribute("style","font-size:7px;margin:0 0 0 10px");
    DOMlabel2.setAttribute("for","rbModeRoma");
    DOMlabel2.innerHTML = "ローマ字表示";
    DOMRoomInfo.appendChild(DOMlabel2);

    var DOMrb2 = document.createElement("input");
    DOMrb2.id = "rbModeRoma";
    DOMrb2.setAttribute("type","radio");
    DOMrb2.setAttribute("name","rbPlayMode");
    DOMrb2.setAttribute("value","roma");
    DOMrb2.addEventListener("change", function(){
        mode = 'roma';
        kana_mode = false;
        keyboard='normal';
        WriteToCookie('cookieRTCselectingMode', 'roma2');
		var updates = {};
		updates['users/' + myID + '/status/InputMode'] = "ローマ字";
		firebase.database().ref().update(updates);
    });
    DOMRoomInfo.appendChild(DOMrb2);


    var DOMlabel3 = document.createElement("label");
    DOMlabel3.setAttribute("style","font-size:7px;margin:0 0 0 10px");
    DOMlabel3.setAttribute("for","rbModeKanaInput");
    DOMlabel3.innerHTML = "かな入力";
    DOMRoomInfo.appendChild(DOMlabel3);

    var DOMrb3 = document.createElement("input");
    DOMrb3.id = "rbModeKanaInput";
    DOMrb3.setAttribute("type","radio");
    DOMrb3.setAttribute("name","rbPlayMode");
    DOMrb3.setAttribute("value","kanaInput");
    DOMrb3.addEventListener("change", function(){
        mode = 'kana';
        kana_mode = true;
        keyboard='normal';
        WriteToCookie('cookieRTCselectingMode', 'kana1');
		var updates = {};
		updates['users/' + myID + '/status/InputMode'] = "かな";
		firebase.database().ref().update(updates);
    });
    DOMRoomInfo.appendChild(DOMrb3);


    var DOMlabel4 = document.createElement("label");
    DOMlabel4.setAttribute("style","font-size:7px;margin:0 0 0 10px");
    DOMlabel4.setAttribute("for","rbModeFlickInput");
    DOMlabel4.innerHTML = "フリック入力";
    DOMRoomInfo.appendChild(DOMlabel4);

    var DOMrb4 = document.createElement("input");
    DOMrb4.id = "rbModeKanaInput";
    DOMrb4.setAttribute("type","radio");
    DOMrb4.setAttribute("name","rbPlayMode");
    DOMrb4.setAttribute("value","flickInput");
    DOMrb4.addEventListener("change", function(){
        mode = 'kana';
        kana_mode = true;
        keyboard='mac';
        WriteToCookie('cookieRTCselectingMode', 'kana2');
		var updates = {};
		updates['users/' + myID + '/status/InputMode'] = "フリック";
		firebase.database().ref().update(updates);
    });
    DOMRoomInfo.appendChild(DOMrb4);

	DOMRoomInfo.insertAdjacentHTML('beforeend', `<div class="select_area"><span style="margin-right: 9px;">勝敗条件:</span>
<select id="combat_mode" style="width: 70px;" disabled>
<option value="Score" title="通常のScoreで対戦するモードです。">Score</option>
<option value="Line" title="いち早くLineクリアすると1clearポイント獲得できます。clearポイントの多さで競います。">Line先取</option>
<option value="Combo" title="Missをすると対戦エリアのScoreがリセットされます。">Combo</option>
<option value="Perfect" title="Missに加えて、ラインクリアに失敗しても対戦エリアのScoreがリセットされます。">Perfect</option>
</select></div><div class="select_area"><span style="margin-right: 9px;">Skip方法:</span>
<select id="skip_mode" style="width: 70px;" disabled>
<option value="HOST" title="ホストのユーザーがスキップしたタイミングで参加者全員がSkipされます。短い間奏(10秒未満)はSkip出来なくなります。">ホスト式</option>
<option value="All" title="参加者全員がスキップ申請したタイミングでスキップします。">申請式</option>
</select></div>`)
document.getElementById("combat_mode").addEventListener("change",onChangeCombatMode)
document.getElementById("skip_mode").addEventListener("change",onChangeSkipMode)

    var DOMdiv2 = document.createElement("div");
    DOMdiv2.setAttribute("style","height:20%;");
    DOMRoomIdleScene.appendChild(DOMdiv2);

    var DOMbuttonReady = document.createElement("input");
    DOMbuttonReady.setAttribute("type","button");
	DOMbuttonReady.setAttribute("class","rtc-button");
    DOMbuttonReady.setAttribute("value","準備完了");
    DOMbuttonReady.id = "RTCbtnReady";
    DOMbuttonReady.setAttribute("style","margin:10px 4px;visibility:hidden;");
    DOMbuttonReady.addEventListener("click", onClickBtnReady);
    DOMdiv2.appendChild(DOMbuttonReady);

    var DOMbuttonGameStart = document.createElement("input");
    DOMbuttonGameStart.setAttribute("type","button");
	DOMbuttonGameStart.setAttribute("class","rtc-button");
    DOMbuttonGameStart.setAttribute("value","ゲーム開始");
    DOMbuttonGameStart.id = "RTCbtnGameStart";
    if(movieID == 0){
        DOMbuttonGameStart.disabled = true;
        DOMbuttonGameStart.setAttribute("title","プレイする楽曲を選択してください。");
    }
    DOMbuttonGameStart.setAttribute("style","margin:10px 4px;" + (movieID == 0 ? "visibility:hidden;":""));
    DOMbuttonGameStart.addEventListener("click", onClickBtnGameStart);
    DOMdiv2.appendChild(DOMbuttonGameStart);

    var DOMbuttonExit = document.createElement("input");
    DOMbuttonExit.setAttribute("type","button");
	DOMbuttonExit.id = "RTCbtnExit";
	DOMbuttonExit.setAttribute("class","rtc-button");
    DOMbuttonExit.setAttribute("value","ルームを退出");
    DOMbuttonExit.setAttribute("style","margin:10px 4px 10px 30px");
    DOMbuttonExit.addEventListener("click", function(){
            ExitRoom();
    });
    DOMdiv2.appendChild(DOMbuttonExit);


	if(!localStorage.getItem("RTCpreview")){
		localStorage.setItem("RTCpreview", "false")
	}
    var DOMbuttonPreview = document.createElement("span");
    DOMbuttonPreview.setAttribute("style","display: flex;justify-content: flex-end;    position: relative;top: -10px;");
	DOMbuttonPreview.innerHTML = `<label><input type="checkbox" value="RTC_Scroll" `+(localStorage.getItem("RTC_Scroll")=="false" ? "":"checked")+`>自動スクロール</label> <label><input type="checkbox" value="nowplay_preview" `+(localStorage.getItem("RTCpreview")=="false"?"":"checked")+`>プレビュー再生</label>`

	DOMdiv2.appendChild(DOMbuttonPreview);

    document.querySelector("[value='RTC_Scroll']").addEventListener("change", function(event){
		localStorage.setItem("RTC_Scroll", event.target.checked)
    });
    document.querySelector("[value='nowplay_preview']").addEventListener("change", function(event){
		localStorage.setItem("RTCpreview", event.target.checked)
		if(!event.target.checked && location.href.indexOf("https://typing-tube.net/movie/") >= 0 && !playing){
			player.pauseVideo()
		}
    });

    //クッキーにより、記憶されていたモードを自動で選択するようにする処理
    RTCselectingMode = ReadFromCookie('cookieRTCselectingMode');
    if(RTCselectingMode == ''){
        WriteToCookie('cookieRTCselectingMode', 'roma1');
    }else{
        switch(RTCselectingMode){
            case 'roma1':DOMrb1.click();break;
            case 'roma2':DOMrb2.click();break;
            case 'kana1':DOMrb3.click();break;
            case 'kana2':DOMrb4.click();break;
            default: WriteToCookie('cookieRTCselectingMode', 'roma1');DOMrb1.click();break;
        }

    }
}

/**
*プレイ中画面作成
*/
function CreateGamePlayScene(parent){
  var DOMGamePlayScene = document.createElement("div");
    DOMGamePlayScene.id = "RTCGamePlayScene";
    DOMGamePlayScene.setAttribute("style","width:98.5%;margin:8px 8px;");
    DOMGamePlayScene.classList.add('is-hide');
    parent.appendChild(DOMGamePlayScene);

    var DOMWrapper = document.createElement("div");
    DOMWrapper.setAttribute("style","height:292px;margin:0;padding:0;overflow-y:auto;background-color:rgba(0,0,0, 0.2);");
    DOMWrapper.id = "RTCGamePlayWrapper";
    DOMGamePlayScene.appendChild(DOMWrapper);

     var DOMTable = document.createElement("table");
    DOMTable.id = "RTCGamePlayPlayersStatusTable";
     DOMTable.setAttribute("style","width:100%;margin: 8px 0px 6.5px 0;");
    DOMTable.setAttribute("rules","all");
    DOMTable.setAttribute("border","1");
    DOMWrapper.appendChild(DOMTable);

    var DOMdiv2 = document.createElement("div");
    DOMGamePlayScene.appendChild(DOMdiv2);

    var DOMp2 = document.createElement("p");
    DOMp2.setAttribute("style","font-size:14px;margin:25px 0;display:none;");
    DOMp2.id = "RTCRoomMes";
    DOMp2.innerHTML = " ";
    DOMWrapper.appendChild(DOMp2);
}

var isChatOpen;
/**
*チャットエリア作成
*/
function CreateChatArea(){

    isChatOpen = ReadFromCookie('cookieRTCisChatOpen');
    if(isChatOpen == ''){
        isChatOpen = 'true';
        WriteToCookie('cookieRTCisChatOpen', 'true');
    }

    var DOMChatDiv = document.createElement("div");
    DOMChatDiv.classList.add("chatArea");
    DOMChatDiv.setAttribute("style","height:232px;display:inline-block;vertical-align: top;");
    //DOMContainer.appendChild(DOMChatDiv)
    document.getElementsByClassName('main')[0].appendChild(DOMChatDiv);
    if(isChatOpen == 'false'){
        $('.chatArea').animate({height: 'hide',opacity:'hide'}, 0)
    }else{
        DOMChatDiv.focus();
    }


    var DOMDiv = document.createElement("div");
    DOMDiv.setAttribute("style","margin:0 2.5%;padding-top: 7px;");
    DOMChatDiv.appendChild(DOMDiv);

    var DOMChatModeDiv = document.createElement("span");
    DOMChatModeDiv.id = "RTCchatModeDiv";
    DOMChatModeDiv.classList.add('is-hide');
    DOMDiv.appendChild(DOMChatModeDiv);


    var DOMlabelWorldChat = document.createElement("label");
    DOMlabelWorldChat.setAttribute("style","font-size:7px;margin:0 0 0 20px");
    DOMlabelWorldChat.setAttribute("for","rbWorldChat");
    DOMlabelWorldChat.innerHTML = "全体チャット";
    DOMChatModeDiv.appendChild(DOMlabelWorldChat);

    var DOMrbWorldChat = document.createElement("input");
    DOMrbWorldChat.id = "rbWorldChat";
    DOMrbWorldChat.setAttribute("type","radio");
    DOMrbWorldChat.setAttribute("name","rbChatMode");
    DOMrbWorldChat.setAttribute("checked","checked");
    DOMrbWorldChat.setAttribute("value","world");
    DOMrbWorldChat.addEventListener("change", function(){
        isRoomChat = false;
        document.getElementById("RTCChat").classList.remove("is-hide");
        document.getElementById("RTCRoomChat").classList.add("is-hide");
    });
    DOMChatModeDiv.appendChild(DOMrbWorldChat);

    var DOMlabelRoomChat = document.createElement("label");
    DOMlabelRoomChat.setAttribute("style","font-size:7px;margin:0");
    DOMlabelRoomChat.setAttribute("for","rbRoomChat");
    DOMlabelRoomChat.innerHTML = "ルームチャット";
    DOMChatModeDiv.appendChild(DOMlabelRoomChat);

    var DOMrbRoomChat = document.createElement("input");
    DOMrbRoomChat.id = "rbRoomChat";
    DOMrbRoomChat.setAttribute("type","radio");
    DOMrbRoomChat.setAttribute("style","font-size:10px;");
    DOMrbRoomChat.setAttribute("name","rbChatMode");
    DOMrbRoomChat.setAttribute("value","room");
    DOMrbRoomChat.addEventListener("change", function(){
        isRoomChat = true;
        document.getElementById("RTCChat").classList.add("is-hide");
        document.getElementById("RTCRoomChat").classList.remove("is-hide");
    });
    DOMChatModeDiv.appendChild(DOMrbRoomChat);


    var DOMp2 = document.createElement("span");
    DOMp2.setAttribute("style","font-size:12px;margin:0 20px;");
    DOMp2.innerHTML = "F4キーで表示非表示を切り替えられます。";
    DOMDiv.appendChild(DOMp2);

    var DOMChatUl = document.createElement("ul");
    DOMChatUl.id = "RTCChat";
    DOMChatUl.setAttribute("style","max-height:150px; height:150px;margin:0 0 5px 0; padding:0;background-color:rgba(0,0,0, 0.2);overflow-y:auto;font-size:10px;");
    DOMDiv.appendChild(DOMChatUl);


    var DOMRoomChatUl = document.createElement("ul");
    DOMRoomChatUl.id = "RTCRoomChat";
    DOMRoomChatUl.classList.add('is-hide');
    DOMRoomChatUl.setAttribute("style","max-height:150px; height:150px;margin:0 0 5px 0; padding:0;background-color:rgba(0,0,0, 0.2);overflow-y:auto;");
    DOMDiv.appendChild(DOMRoomChatUl);

    var DOMForm = document.createElement("div");
    DOMForm.setAttribute("style","margin:10px 0; padding:0;");
    DOMDiv.appendChild(DOMForm);

    DOMChatInput = document.createElement("input");
	DOMChatInput.id = "ChatInput"
    DOMChatInput.setAttribute("type","text");
    DOMChatInput.setAttribute("name","text");
    DOMChatInput.setAttribute("placeholder","メッセージをこちらに入力");
	DOMChatInput.setAttribute("autocomplete","off");
    DOMChatInput.setAttribute("style","width:80%;background-color:rgba(0,0,0, 0.2);border:none;color:white;");
    DOMChatInput.addEventListener("mouseenter",function(){
        DOMChatInput.setAttribute("style","width:80%;background-color:rgba(80,80,80, 0.5);border:none;color:white;");
    });
    DOMChatInput.addEventListener("mouseleave",function(){
        DOMChatInput.setAttribute("style","width:80%;background-color:rgba(0,0,0, 0.2);border:none;color:white;");
    });
    DOMForm.appendChild(DOMChatInput);

    var DOMChatSubmit = document.createElement("input");
    DOMChatSubmit.setAttribute("type","button");
    DOMChatSubmit.setAttribute("value","送信");
    DOMChatSubmit.setAttribute("style","width:20%;");
    DOMChatSubmit.addEventListener("click", SubmitMessage);
    DOMForm.appendChild(DOMChatSubmit);

    //コメント入力後Enterを押したら送信
    DOMChatInput.addEventListener("keydown" , function(event){
        if(!event.isComposing && event.code == "Enter" && document.getElementById("ChatInput").value){
            DOMChatSubmit.click();
			event.stopImmediatePropagation()
        }
	});
	document.addEventListener("click" , function(event){

		const focusing_area = event.target.type == "text" || event.target.type == "select-one" || document.activeElement.id == "RoomNameArea" ? true:false
		const selecting_input = String(document.getSelection()) && document.activeElement.type == "text" ? true:false
		if(!focusing_area && !selecting_input){
			$('.chatArea input[name="text"]:visible').focus();
		}
	});
	document.addEventListener("change" , function(event){
			$('.chatArea input[name="text"]:visible').focus();
	});
	//F4キークリックで表示非表示切り替え
	window.addEventListener("keydown" , function(event){
		if(event.code == "F4" && (playing == false || document.getElementsByClassName("RTCRoomPlayerName").length >= 2 && playing == true)){
			if(isChatOpen == 'true'){
				$('.chatArea').animate({height: 'hide',opacity:'hide'}, 'nomal')
				isChatOpen = 'false';
			}else{
				$('.chatArea').animate({height: 'show',opacity:'show'}, 'nomal')
				isChatOpen = 'true';
			}
			WriteToCookie('cookieRTCisChatOpen', isChatOpen);

			$('.chatArea input[name="text"]:visible').focus();
		}
	 },true);
	if(location.href.indexOf("https://typing-tube.net/movie/show/")>-1 && localStorage.getItem("RTC_Scroll") != "false"){
	window.scrollBy({
		top:CONTROLBOX_SELECTOR.getBoundingClientRect().bottom-document.documentElement.clientHeight+250
	})
	}
    //ページ読み込み時、チャットが表示されているならDOMChatInputに自動フォーカス by.Toshi
	$('.chatArea input[name="text"]:visible').focus();
    //F8キークリックで key/sec と key/minのトグル
     window.addEventListener("keydown" , function(event){
        if(event.code == "F8"){
            isDispFmtKeySec = !isDispFmtKeySec;
        }
    });
}



/**
*バージョンチェック
*/
function UpdateCheck(){
	firebase.database().ref('ImportantUpdate').once('value').then(Update => {
		if(Update.val() != null && Update.val() > ImportantVer){
			if(confirm(`RealTimeCombatting[Typing-Tube]: 重要な更新があります。お手数ですが、最新バージョンに更新してください。\n(OKを選択すると更新ページを開きます。)`)){
				window.location.href = "https://greasyfork.org/ja/scripts/391474-realtimecombatting-typing-tube/versions"
			}
		}
	});
	if(RTC_Switch){
		firebase.database().ref('Version').once('value').then(Version => {
			if(Version.val() != null && Version.val() != Ver){
				document.getElementById("RTCContainer").insertAdjacentHTML('afterend', `<a style="z-index:50;margin-left:5px;font-size:1.2rem;text-decoration:underline;" target="_blank" href="https://greasyfork.org/ja/scripts/391474-realtimecombatting-typing-tube/versions">RealTimeCombatting[Typing-Tube]: こちらから新しいバージョン (`+Version.val()+`) へ更新できます</a>`)
			}
		});
	}
}


/**
*@note 対戦用のインタラクティブエリア作成 ここまで---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////










/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note チャット関連 ここから ---
*/

var isRoomChat = false;
/**
*@Description チャット送信
*/
function SubmitMessage(){
    if(DOMChatInput.value.length == 0){
        return;
    }
    var messageRef;
    if(isRoomChat){
        messageRef = firebase.database().ref('rooms/' + roomID + '/chats').push();
    }else{
        messageRef = firebase.database().ref('chats').push();
    }
    messageRef.set({
            "userID": myID,
            "text" :DOMChatInput.value
        });
    DOMChatInput.value = "";
}

/**
*@Description チャット欄更新
*/
function onChatUpdate(snapshot){
    var msg = snapshot.val();

    if(roomID == null){
        playSE("chat");
    }

    var li = document.createElement("li");
    var name;
    var query = firebase.database().ref('users/' + msg.userID);
    query.once('value').then(player => {
       if(msg.userID == myID){
           name = player.val().name;
           li.innerHTML = "<span class='mine'>" + name +"</span> : <span>" + msg.text+ "</span>";
        }else if(player.val() != null){
           name = player.val().name;
           li.innerHTML = "<span>" + name +"</span> : <span>" + msg.text + "</span>";
        }else{
            li.innerHTML = "<span>undefined" +"</span> : <span>" + msg.text + "</span>";
        }
    });

    var target = document.getElementById("RTCChat");

    if(target.scrollTop + 10 >= target.scrollHeight - target.clientHeight){
        target.appendChild(li);
        target.scrollTop = target.scrollHeight - target.clientHeight;
    }else{
        target.appendChild(li);
    }
}

/**
*@Description チャット欄更新(roomChat)
*/
function onRoomChatUpdate(snapshot){
    var msg = snapshot.val();

    playSE("chat");
    var li = document.createElement("li");
    var name;
    var query = firebase.database().ref('users/' + msg.userID);
    query.once('value').then(player => {
       if(msg.userID == myID){
           name = player.val().name;
           li.innerHTML = "<span class='mine'>"  + name +"</span> : <span>" + msg.text+ "</span>";
        }else if(player.val() != null){
           name = player.val().name;
           li.innerHTML = "<span>" + name +"</span> : <span>" + msg.text + "</span>";
        }else{
            li.innerHTML = "<span>undefined" +"</span> : <span>" + msg.text + "</span>";
        }
    });

    var target = document.getElementById("RTCRoomChat");

    if(target.scrollTop + 10 >= target.scrollHeight - target.clientHeight){
        target.appendChild(li);
        target.scrollTop = target.scrollHeight - target.clientHeight;
    }else{
        target.appendChild(li);
    }
}


/**
*@note チャット関連 ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////










/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note クッキー関連 ここから ---
*/


/**
*@description クッキーデータの読み込み
*@param name
*@return val
*/
function ReadFromCookie(name){
    var result = null;

    var cookieName = name + '=';
    var allcookies = document.cookie;

    var position = allcookies.indexOf( cookieName );
    if( position != -1 )
    {
        var startIndex = position + cookieName.length;

        var endIndex = allcookies.indexOf( ';', startIndex );
        if( endIndex == -1 )
        {
            endIndex = allcookies.length;
        }

        result = decodeURIComponent(
            allcookies.substring( startIndex, endIndex ) );
    }
    return result;
}

/**
*@description クッキーにデータの書き込み
*@param name
*@param val
*/
function WriteToCookie(name, val){
    var expire = new Date();
    expire.setTime( expire.getTime() + 1000 * 3600 * 24 * 30);
    document.cookie = name + '=' +  encodeURIComponent(val) + '; path=/ ; expires=' + expire.toUTCString();
}


/**
*@note クッキー関連 ここから ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////











/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note room関連 ここから ---
*/

var roomID;
var playSpeeds = [0.25, 0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00];

/**
*@Description Roomが追加された
*/
function onAddRoom(snapShot){
    var msg = snapShot.val();

    var roomID = snapShot.ref_.path.pieces_[1];
    var roomName = msg.roomName;
    var desc = msg.description;
    var state = msg.state;
    var movieID = msg.movieID;
    var movieTitle = msg.movieTitle;
    var roomMaster = msg.roomMaster;
    var players = msg.users;
	var roomPassWord = msg.roomPassWord;
	if(First_Load_Room_Existence_flag){
		First_Load_Room_Existence_flag = false
document.getElementById("RTCRooms").insertAdjacentHTML('afterbegin', `<span style="font-size:14px;background: #000000dd;position: absolute;height: 201px;width:`+document.getElementById("RTCRooms").clientWidth+`px;" id="Room_Existence"><span style="
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    position: absolute;
    top: 48%;
    left: 50%;
">ルーム情報を確認中...</span></span>`)
	}
    //キックされた部屋なら表示しない
    if(msg.kick != null){
        if(msg.kick[myID] != undefined){
            return;
        }
    }

    var DOMroom = document.createElement("div");
    DOMroom.id = roomID;
    DOMroom.classList.add("RTCroom");

    DOMroom.setAttribute("style","width:45%;max-height:160px; height:160px;margin:5px;background-color:rgba(0,0,0, 0.2);display:inline-block;overflow-y:auto;");
    DOMroom.addEventListener("mouseenter",function(){
        DOMroom.setAttribute("style","width:45%;max-height:160px; height:160px;margin:5px;background-color:rgba(40,40,40, 0.5);display:inline-block;overflow-y:auto;");
    });
    DOMroom.addEventListener("mouseleave",function(){
        DOMroom.setAttribute("style","width:45%;max-height:160px; height:160px;margin:5px;background-color:rgba(0,0,0, 0.2);display:inline-block;overflow-y:auto;");
    });
    DOMroom.addEventListener("click",function(event){
        var roomID = event.currentTarget.id
	if(Latest_Ver != null && Latest_Ver != Ver){
		const Update_check = alert(`RealTimeCombatting[Typing-Tube]: 新しいバージョンが利用可能です。\n更新後、TypingTubeページをリロードすると最新Verが適用されます。`)
		return false;
	}
        if(event.currentTarget.closest(".RTCroom")){
			if(event.currentTarget.id.length == 14){
				EnterRoom(roomID);
			}else if(event.currentTarget.id.length == 15){
				const pass_form = window.prompt("このゲームに参加するにはパスワードが必要です")
				if(pass_form){
					firebase.database().ref('rooms/' + roomID).once('value').then(room => {
						if(room.val().roomPassWord == pass_form){
							EnterRoom(roomID);
						}else{
							alert("パスワードが違います。")
						}
					})
				}
			}
			}
		});
    document.getElementById("RTCRooms").appendChild(DOMroom);

	var DOMroomTitle = document.createElement("div");
	DOMroomTitle.setAttribute("id","roomTitle");
	DOMroomTitle.setAttribute("style",`display: flex;justify-content: space-between;`);
	DOMroom.appendChild(DOMroomTitle);

    var DOMName = document.createElement("p");
    DOMName.setAttribute("style","font-size:14px;margin:2px 2px;");
    DOMName.innerHTML =roomName;
    DOMName.classList.add("RTCroomName");
    DOMroomTitle.appendChild(DOMName);

	if(roomPassWord){
		DOMName.insertAdjacentHTML('afterend', `<i class="fas fa-lock" style="margin: 6px 9px 0 5px;font-size: 1.5rem;"></i>`)
	}

    var DOMDesc = document.createElement("p");
    DOMDesc.setAttribute("style","font-size:10px;margin:2px 2px;");
    DOMDesc.innerHTML = desc;
    DOMDesc.classList.add("RTCroomDescription");
    DOMroom.appendChild(DOMDesc);

    var DOMstatus = document.createElement("p");
    DOMstatus.setAttribute("style","font-size:8px;margin:10px 2px;");
    DOMstatus.classList.add("RTCroomPlayStatus");

    if(state == "play"){
        DOMstatus.innerHTML = "プレイ中";
    }else if(state == "result"){
        DOMstatus.innerHTML = "プレイ終了";
    }else{
        DOMstatus.innerHTML = "プレイ前";
    }
    DOMroom.appendChild(DOMstatus);


    var DOMMovieTitle = document.createElement("p");
    DOMMovieTitle.setAttribute("style","font-size:8px;margin:2px 2px;");
    DOMMovieTitle.classList.add("RTCroomMovieTitle");
    DOMMovieTitle.innerHTML = "楽曲: [ID" + movieID + "]" + movieTitle;
    DOMroom.appendChild(DOMMovieTitle);

    var DOMplayers = document.createElement("p");
    DOMplayers.setAttribute("style","font-size:8px;margin:10px 2px; 2px");
    DOMplayers.innerHTML = "参加者: ";
    DOMplayers.classList.add("RTCroomPlayers");
    DOMroom.appendChild(DOMplayers);

    if(players != null){
        Object.keys(players).forEach(function(key) {
            DOMplayers.innerHTML += players[key] + " ";
        });
    }
    document.getElementById("noRoomMes").classList.add('is-hide');
}

/**
*@Description Room情報が変更された
*/
function onChangeRoom(snapshot){
    var msg = snapshot.val();
    var roomID = snapshot.ref_.path.pieces_[1];
    var roomName = msg.roomName;
    var desc = msg.description;
    var state = msg.state;
    var movieID = msg.movieID;
    var movieTitle = msg.movieTitle;
    var roomMaster = msg.roomMaster;
    var players = msg.users;
	var roomPassWord = msg.roomPassWord;
    //キックされた部屋なら表示しない
    if(msg.kick != null){
        if(msg.kick[myID] != undefined){
            return;
        }
    }

    document.getElementById(roomID).getElementsByClassName("RTCroomName")[0].innerHTML = roomName;

    document.getElementById(roomID).getElementsByClassName("RTCroomDescription")[0].innerHTML = desc;
    if(state == "play"){
        document.getElementById(roomID).getElementsByClassName("RTCroomPlayStatus")[0].innerHTML = "プレイ中";
    }else if(state == "result"){
        document.getElementById(roomID).getElementsByClassName("RTCroomPlayStatus")[0].innerHTML = "プレイ終了";
    }else{
        document.getElementById(roomID).getElementsByClassName("RTCroomPlayStatus")[0].innerHTML = "プレイ前";
    }
    document.getElementById(roomID).getElementsByClassName("RTCroomMovieTitle")[0].innerHTML= "楽曲: [ID" + movieID + "]" + movieTitle;
    document.getElementById(roomID).getElementsByClassName("RTCroomPlayers")[0].innerHTML = "参加者: ";

    if(players != null){
        Object.keys(players).forEach(function(key) {
            document.getElementById(roomID).getElementsByClassName("RTCroomPlayers")[0].innerHTML += players[key] + " ";
        });
    }
}

/**
*@Description Roomが削除された
*/
function onRemoveRoom(snapshot){
    var msg = snapshot.val();
    var roomID = snapshot.ref_.path.pieces_[1];

    document.getElementById(roomID).remove();
    if(document.getElementById("RTCRooms").getElementsByClassName("RTCroom").length === 0){
        document.getElementById("noRoomMes").classList.remove('is-hide');
    }
}

/**
*@Description [新しくルームを作成] ボタンが押された
*/
function onClickCreateNewRoom(){
	if(Latest_Ver != null && Latest_Ver != Ver){
		const Update_check = alert(`RealTimeCombatting[Typing-Tube]: 新しいバージョンが利用可能です。\n更新後、TypingTubeページをリロードすると最新Verが適用されます。`)
		return false;
	}
    playSE("click");
    document.getElementById("createNewRoom").classList.add('is-show');
}

/**
*@Description 32文字の一意な文字列を作成
*/
function getUniqueStr(){
    var strong = 1000;
    return new Date().getTime().toString(16) + Math.floor(strong*Math.random()).toString(16);
}

/**
*@Description [ルームを作成] ボタンが押された
*/
function onClickCreateRoom(){

	let roomPassWord = document.getElementById("Enable_PassWord").checked?document.getElementById("roomPassWordArea").value:""
    var roomId = getUniqueStr()
	if(roomId.length < 14){
		while(roomId.length != 14){
			roomId += "0"
		}
	}else if(roomId.length > 14){
		while(roomId.length != 14){
			roomId = roomId.slice(0,-1)
		}
	}
	if(roomPassWord){
		roomId = "P"+roomId
	}

	var description = document.getElementById("roomDescription").value;
    var _movieID = movieID;
    if(_movieID == null){
        _movieID =  " ";
    }
    var _movieTitle = movieTitle;
    if(_movieTitle == null){
        _movieTitle =  " ";
    }
    var roomMaster = myID;
    var roomName = document.getElementById("roomName").value;
    var state = "idle";



    var path = firebase.database().ref('rooms/' + roomId);
    path.set({
            "description": description,
            "movieID" :_movieID,
            "movieTitle": _movieTitle,
            "roomMaster": roomMaster,
            "roomName": roomName,
		    "roomPassWord": roomPassWord,
            "state": state,
        "playSpeed": 3,
		"playMode": "Score",
		"skipMode": "HOST",
		"AutoStart": false
        });

    document.getElementById("createNewRoom").classList.remove('is-show');
    EnterRoom(roomId);
}

/**
*@Description [キャンセル] ボタンが押された
*/
function onClickCancel(){
    playSE("cancel");
     document.getElementById("createNewRoom").classList.remove('is-show');
}

var isEnter;
/**
*@Description roomに入室した
*@param _roomID
*/
function EnterRoom(_roomID){

    playSE("greet");
    //初めの数秒は音を鳴らさない
    isSECancel = true;
    setTimeout(function(){
        isSECancel = false;
    }, 1500);
				//are you ready? SoundEffect Load
				if(!matchconfirm_sound){
					matchconfirm_sound = new AudioContext();
					matchconfirm_sound_load()
				}
				if(!CountDown_sound){
					CountDown_sound = new AudioContext();
					countDownEnd_sound = new AudioContext();
					countDownEnd_sound_load()
					CountDown_sound_load()
				}
    isEnter = true;
	roomID = _roomID;
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        //roomがない
        if(room.val() == null){
            ExitRoom();
        }else{
            //チャット先をルームチャットに変更
            isRoomChat = true;
            document.getElementById("rbRoomChat").checked = true;
            document.getElementById("RTCRoomChat").classList.remove("is-hide");
            document.getElementById("RTCChat").classList.add("is-hide");
            document.getElementById("RTCRoomName").innerHTML = "ルーム - <span id='RoomNameArea'>" + room.val().roomName + "</span>";
			if(_roomID.length == 15){
				document.getElementById("RoomNameArea").insertAdjacentHTML('afterend',`<i id="roomKey" class="fas fa-key" style="
                                                                                           margin-left: 15px;cursor:pointer;
                                                                                           "></i>`)
				document.getElementById("roomKey").addEventListener("click",getRoomKey)
			}

            var updates = {};
            updates['/users/' + myID + '/roomID'] = roomID;
            updates['/rooms/' + roomID + '/users/' + myID] = userName;
            //ルームマスターになったか
            if(room.val().roomMaster == myID){
                becomeRoomMaster();
            }else{
                becomeCommon();
            }
            firebase.database().ref().update(updates);


            document.getElementById("RTCRoomSelectScene").classList.add('is-hide');
            document.getElementById("RTCRoomIdleScene").classList.remove('is-hide');


            //room情報が更新された時用のイベントリスナー追加
            firebase.database().ref('/rooms/' + roomID).on('child_changed', onUpdateRoomInfo);
            firebase.database().ref('/rooms/' + roomID + '/users/').on('child_added', onAddRoomUser);
            firebase.database().ref('/rooms/' + roomID + '/users/').on('child_removed', onRemoveRoomUser);

            onUpdateRoomInfo();

            //ルームチャット切り替えようラジオボタンの表示
            document.getElementById("RTCchatModeDiv").classList.remove('is-hide');

            //ルームチャット欄自動更新
            var chats = firebase.database().ref('rooms/' + roomID + '/chats').limitToLast(10);
            chats.on('child_added', onRoomChatUpdate);

           //プレイ速度更新
			if( typeof title_speed != "number"){
				document.getElementById("RTCPlaySpeedSpan").innerHTML = playSpeeds[room.val().playSpeed].toFixed(2) + "倍速";
				play_speed = playSpeeds[room.val().playSpeed]
				speed = playSpeeds[room.val().playSpeed]
			}
			document.getElementById("combat_mode").value = room.val().playMode
			document.getElementById("skip_mode").value = room.val().skipMode

            //ボタン等表示
            if(!isRoomMaster){
                document.getElementById("RTCbtnReady").classList.remove("is-hide");
                document.getElementById("RTCbtnGameStart").classList.add("is-hide");
            }else{
                document.getElementById("RTCbtnReady").classList.add("is-hide");
                document.getElementById("RTCbtnGameStart").classList.remove("is-hide");
				if(movieID && !playing && isRoomMaster){
					window.addEventListener("keydown" , ready_key)
				}
            }
        }
    });
}

/**
*@Description roomから退出した
*/
function ExitRoom(){

    //退出音を鳴らす
    playSE("exit");

    isEnter = false;
	isRoomMaster = false;
    var updates = {};
    updates['/users/' + myID + '/roomID'] = null;
    updates['/rooms/' + roomID + '/users/' + myID] = null;
    firebase.database().ref().update(updates);

    //ルームチャット欄自動更新解除
    var chats = firebase.database().ref('rooms/' + roomID + '/chats').limitToLast(10);
    chats.off('child_added', onRoomChatUpdate);

    //ルームチャットすべて削除
    var rc = document.getElementById("RTCRoomChat");
    while(rc.firstChild){
        rc.removeChild(rc.firstChild );
    }

    //ルームチャット切り替えようラジオボタンの非表示
    document.getElementById("rbWorldChat").checked = true;
    document.getElementById("RTCChat").classList.remove("is-hide");
    document.getElementById("RTCRoomChat").classList.add("is-hide");
    document.getElementById("RTCchatModeDiv").classList.add('is-hide');
    isRoomChat =false;

    //room情報が更新された時用のイベントリスナー削除
    firebase.database().ref('/rooms/' + roomID).off('child_changed', onUpdateRoomInfo);
    firebase.database().ref('/rooms/' + roomID + '/users/').off('child_added', onAddRoomUser);
    firebase.database().ref('/rooms/' + roomID + '/users/').off('child_removed', onRemoveRoomUser);
	window.removeEventListener("keydown" , ready_key)
    document.getElementById("RTCRoomSelectScene").classList.remove("is-hide");
    document.getElementById("RTCRoomIdleScene").classList.add('is-hide');

    firebase.database().ref('rooms/' + roomID + '/users/').once('value').then(users => {
        //もしroomに誰もいなければこのroomを削除
        if(users.val() === null || users.length === 0){
              firebase.database().ref("/rooms/" + roomID).set(null);
        }else{
            firebase.database().ref('rooms/' + roomID).once('value').then(rm => {
                //自分がルームマスターなら他の誰かにルームマスターを移動
                var newRoomMaster = {};
                var idx = 0;
                if(rm.val().roomMaster != null && rm.val().roomMaster  == myID){
                    newRoomMaster = {};
                    Object.keys(rm.val().users).forEach(function(key){
                         if(key != myID){
                            newRoomMaster[idx++] = key;
                        }
                    }, rm.val().users);

                    if(idx > 0){
                        idx = Math.floor( Math.random() * idx);
                        updates = {};
                        updates['/rooms/' + roomID + '/roomMaster'] = newRoomMaster[idx];
                        firebase.database().ref().update(updates);
                    }
                }
                roomID = null;
            });
        }
    });
}

/**
*@Description 入室中のroom情報が更新された
*/
let AutoStart_Mode = false
function onUpdateRoomInfo(snapshot){
      firebase.database().ref('rooms/' + roomID).once('value').then(room => {
		  var updates = {};
          //roomがない
          if(room.val() == null){
              ExitRoom();
          }else if (room.val().kick && room.val().users && room.val().kick[myID] && room.val().users[myID] == null && isEnter == true){
              //キックされた
              kicked();
            }else{
                //ルームリーダの移動
				if(isEnter){

					document.getElementById("RoomNameArea").textContent = room.val().roomName
					AutoStart_Mode = room.val().AutoStart
					if(room.val().state == "play" || room.val().state == "result"){
						let room_state = room.val().state
						const room_user_id = room.val().users
						firebase.database().ref('users').once('value').then(room_user => {
							for (let room_user_key in room_user_id) {
								if(eval("room_user.val()."+room_user_key+".state") == "play" || eval("room_user.val()."+room_user_key+".state") == "preStart" || Pre_flag || room_state == "result"){
									room_state = room.val().state
									break;
								}else{
									room_state = "idle"
								}
							}
							var updates = {};
							updates['/rooms/' + roomID + '/state'] = room_state;
							firebase.database().ref().update(updates);
						});
					}
                Object.keys(room.val().users).forEach(function(key){
                    if(key == room.val().roomMaster){
                        document.querySelector("#" + key + " > td.RTCRoomPlayerAuthority").innerHTML = "🚩";
                        //ルームマスターになったか
                        if(key == myID){
							document.getElementById("RTC_AutoMove").parentNode.classList.remove("display_AutoMove")
							if(prevState != "not_playable"){
								if(Object.keys(room.val().users).length >= 2){
									document.getElementById("RTC_AutoStart").parentNode.classList.add("display_AutoStart")
									if(room.val().AutoStart == true){
										document.getElementById("RTC_AutoStart").checked = true
									}
								}else if(prevState != "preStart"){
									document.getElementById("RTC_AutoStart").parentNode.classList.remove("display_AutoStart")
									document.getElementById("RTC_AutoStart").checked = false
									prevState = "idle"
									updates['users/' + myID + '/state'] = "idle";
									updates['rooms/' + roomID + '/AutoStart'] = false;
								}
							}
							becomeRoomMaster();
						}else{
							document.getElementById("RTC_AutoStart").parentNode.classList.remove("display_AutoStart")
							if(room.val().users && Object.keys(room.val().users).length >= 2){
								document.getElementById("RTC_AutoMove").parentNode.classList.add("display_AutoMove")
							}else{
								document.getElementById("RTC_AutoMove").parentNode.classList.remove("display_AutoMove")
							}
                            becomeCommon();
                        }
                    }else{
                        document.querySelector("#" + key + " > td.RTCRoomPlayerAuthority").innerHTML = "・";
                    }
                }, room.val().users);

				if(room.val().Winner){
						while(document.getElementsByClassName("Winner_Trophy").length){
							document.getElementsByClassName("Winner_Trophy")[0].remove()
						}
					Object.keys(room.val().Winner).forEach(function(winner_id){
						const Consecutive_wins = room.val().Winner[winner_id].length
						if(room.val().users[winner_id] != null && document.getElementById(winner_id) != null){
						document.getElementById(winner_id).getElementsByClassName("RTCRoomBtBan")[0].insertAdjacentHTML('afterend', `<span class="Winner_Trophy"><i class="fa fa-trophy" style="color:#FFD700"></i>`+ (Consecutive_wins > 1 ? "x"+Consecutive_wins : "")+"</span>")
						}
					})
				}
                //プレイ速度更新
				document.getElementById("RTCRoomPlayerCount").textContent = "参加者一覧 ("+Object.keys(room.val().users).length+"人)"
					if( typeof title_speed != "number"){
						document.getElementById("RTCPlaySpeedSpan").innerHTML = playSpeeds[room.val().playSpeed].toFixed(2) + "倍速";
						play_speed = playSpeeds[room.val().playSpeed]
						speed = playSpeeds[room.val().playSpeed]
					}
				document.getElementById("combat_mode").value = room.val().playMode
				document.getElementById("skip_mode").value = room.val().skipMode

					if(!playing && location.href.indexOf("https://typing-tube.net/movie/show/")>-1){
					map_info_generator()
					}
                document.getElementById("RTCmovieTitleDiv").classList.remove("is-DifferInMovieID");

                //Roomが選択中の楽曲を更新
                //Readyボタンの表示変更
                if(room.val().movieID == 0){
                    document.getElementById("RTCbtnReady").disabled = true;
					document.getElementById("RTCbtnReady").style.visibility = "hidden";
					document.getElementById("RTCbtnReady").setAttribute("title","");
					prevState = "idle"
					updates['users/' + myID + '/state'] = "idle";
                    document.getElementById("RTCRoomMovieTitle").innerHTML = "";
                    document.getElementById("RTCRoomMovieTitle").href = null;
                    if(!isRoomMaster){
                        document.getElementById("RTCMovleSelectingMes").classList.remove('is-hide');
                        document.getElementById("RTCMovleSelectingMesRM").classList.add('is-hide');
                        document.getElementById("RTCRoomMovieTitle").setAttribute("title","");
                    }else{
                        document.getElementById("RTCMovleSelectingMesRM").classList.remove('is-hide');
                        document.getElementById("RTCMovleSelectingMes").classList.add('is-hide');
                        document.getElementById("RTCRoomMovieTitle").setAttribute("title","");
                    }
                }else{
                    if(document.getElementById("RTCRoomMovieTitle").href != "https://typing-tube.net/movie/show/" + room.val().movieID){
                        playSE("cngSong");
						if(!playing && demo_play_flag && room.val().movieID != (location.pathname).replace(/[^0-9]/g, '')){
							player.pauseVideo()
							demo_play_flag = false
						}
					}
					document.getElementById("RTCRoomMovieTitle").innerHTML = "[ID" + room.val().movieID + "]" + room.val().movieTitle;
					document.getElementById("RTCRoomMovieTitle").href = "https://typing-tube.net/movie/show/" + room.val().movieID;
					document.getElementById("RTCMovleSelectingMes").classList.add('is-hide');
					document.getElementById("RTCMovleSelectingMesRM").classList.add('is-hide');
					if(!playing && localStorage.getItem("RTCpreview")=="true" && !demo_play_flag && room.val().movieID == (location.pathname).replace(/[^0-9]/g, '')){
						player.setVolume(volume*.7)
						player.seekTo(+BGM_time)
						player.playVideo()

						demo_play_flag = true
					}
					if(!isRoomMaster){
						if(movieID == room.val().movieID){
							document.getElementById("RTCbtnReady").disabled = false;
							document.getElementById("RTCbtnReady").style.visibility = "visible";
							document.getElementById("RTCbtnReady").setAttribute("title","");
							document.getElementById("RTCmovieTitleDiv").classList.remove("is-DifferInMovieID");
							document.getElementById("RTCRoomMovieTitle").setAttribute("title","準備が完了したら、準備完了ボタンを押してください。");
							if(!playing){
								window.addEventListener("keydown" , ready_key)
							}
						}else{
							document.getElementById("RTCbtnReady").disabled = true;
							document.getElementById("RTCbtnReady").style.visibility = "hidden";
							if(document.getElementById("RTC_AutoMove").checked && room.val().state == "idle"){
							window.location.href = document.getElementById("RTCRoomMovieTitle").href
							}
							document.getElementById("RTCbtnReady").setAttribute("title","ルームマスターが選択した曲と同じ曲を選択してください。");

                            document.getElementById("RTCmovieTitleDiv").classList.add("is-DifferInMovieID");
                            document.getElementById("RTCRoomMovieTitle").setAttribute("title","ルームマスターが選択した曲と違います。コチラをクリックして開きなおしてください。");
							window.removeEventListener("keydown" , ready_key)
							if(prevState == "ready"){
								prevState = "idle"
								updates['users/' + myID + '/state'] = "idle";
								document.getElementById("RTCbtnReady").setAttribute("value","準備完了");
							}
						}
					}else if(prevState == "idle" && AutoStart_Mode && room.val().state != "result"){
						prevState = "Auto_ready"
						updates['users/' + myID + '/state'] = "Auto_ready";
					}
				}
				}
				firebase.database().ref().update(updates);
			}
	  });
}

/**
*@Description roomに人が入室した
*/
function onAddRoomUser(snapshot){

    playSE("greet");
    var _userID = snapshot.ref_.path.pieces_[3];
    var _userName = snapshot.val();

    //すでに追加されていたらそれ以上の処理はしない
    if(document.getElementById(_userID) != null){
        return;
    }

    var DOMTr = document.createElement("tr");
    DOMTr.id = _userID;
    DOMTr.classList.add("RTCroomPlayer");
    if(_userID == myID){
        DOMTr.classList.add("mine");
    }

	document.getElementById("RTCRoomPlayersTable").appendChild(DOMTr);


    var DOMisRM = document.createElement("td");
    DOMisRM.classList.add("RTCRoomPlayerAuthority");
    DOMisRM.setAttribute("style","width:20px;");
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == _userID){
            DOMisRM.innerHTML = "🚩";
        }else{
            DOMisRM.innerHTML = "・";
        }
    });
    DOMTr.appendChild(DOMisRM);

    var DOMname = document.createElement("td");
    DOMname.classList.add("RTCRoomPlayerName");
    DOMname.innerHTML = _userName;
    DOMTr.appendChild(DOMname);

    var DOMstatus = document.createElement("td");
    DOMstatus.classList.add("RTCRoomPlayerState");
    DOMstatus.setAttribute("style","width:75px;");
    firebase.database().ref('users/' + _userID).once('value').then(user => {
        switch(user.val().state){
            case "idle":
                DOMstatus.innerHTML = "準備中";
                break;
            case "ready":
            case "Auto_ready":
                DOMstatus.innerHTML = "準備完了";
                break;
            case "play":
            case "preStart":
                DOMstatus.innerHTML = "プレイ中";
                break;
            case "timeOut":
                DOMstatus.innerHTML = "タイムアウト";
                break;
            case "afk":
                DOMstatus.innerHTML = "afk";
                break;
            case "result":
            case "end":
                DOMstatus.innerHTML = "プレイ終了";
                break;
        }
    });
    DOMTr.appendChild(DOMstatus);

    var DOMbtChangeRM = document.createElement("a");
    DOMbtChangeRM.classList.add("RTCRoomBtChangeRM");
    DOMbtChangeRM.setAttribute("style","width:20px;font-size:8px");
    DOMbtChangeRM.setAttribute("title",_userName + " にルームマスター権限を渡す。");
    DOMbtChangeRM.addEventListener("click", onButtonChangeRM);
    DOMbtChangeRM.innerHTML = "↪🚩";
    DOMTr.appendChild(DOMbtChangeRM);

    var DOMbtBan = document.createElement("a");
    DOMbtBan.classList.add("RTCRoomBtBan");
    DOMbtBan.setAttribute("style","width:20px;font-size:12px");
    DOMbtBan.setAttribute("title",_userName + " をルームからキックする。");
    DOMbtBan.addEventListener("click", onButtonBan);
    DOMbtBan.innerHTML = "💣";
    DOMTr.appendChild(DOMbtBan);

     if(!isRoomMaster || _userID == myID){
        DOMbtChangeRM.classList.add("is-hide");
        DOMbtBan.classList.add("is-hide");
    }

    //このユーザにイベントリスナー追加
    firebase.database().ref('/users/' +_userID+'/state').on('value', onUpdateRoomUser);

}

/**
*@Description room人が退出した
*/
function onRemoveRoomUser(snapshot){
    var _userID = snapshot.ref_.path.pieces_[3];
    var _userName = snapshot.val();
	firebase.database().ref('/users/' +_userID+'/state').off('value', onUpdateRoomUser);
	var _roomPlayers = document.getElementsByClassName("RTCroomPlayer");
    document.getElementById(_userID).remove();

     //もし自分自身ならルーム参加者欄すべて削除
    if(_userID == myID){
for(let i=0;i<_roomPlayers.length;i++){
	firebase.database().ref('/users/' +_roomPlayers[i].id+'/state').off('value', onUpdateRoomUser);
	_roomPlayers[i].remove()
	i--
        }
	}else{
		firebase.database().ref('rooms/' + roomID).once('value').then(room => {
			const room_users = Object.keys(room.val().users)

			var AutoStart = true
			firebase.database().ref('users/').once('value').then(users => {
				room_users.some(function(key){
					if(users.val()[key].state != "ready" && users.val()[key].state != "Auto_ready"){
						AutoStart = false
					}
				});

				//ゲーム前準備処理
					if(AutoStart && isRoomMaster){
						var updates = {}
						prevState = "idle"
						updates['users/' + myID + '/state'] = "idle";
						firebase.database().ref().update(updates);
					}
			}, room.val().users);
		});
	}
}





/**
*@Description roomの選択譜面が変更された
*/
let ready_player = 0
let room_state_changed = false
function RoomStateChange(snapshot){
if(isEnter && snapshot.node_.value_ != movieID){
	let room_state_changed = true
    var updates = {};
	firebase.database().ref('rooms/' + roomID + '/movieID').off('value', RoomStateChange)
    updates['/rooms/' + roomID + '/state' ] = "idle";
    firebase.database().ref().update(updates);
}
}


/**
*@Description room内の人の情報が変更された
*/
var playing_interval
function onUpdateRoomUser(snapshot){
	const user = snapshot.ref_.path.pieces_[1];
	const state = snapshot.node_.value_
	switch(state){
		case "idle":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "準備中";
			document.querySelector("#" + user + " > .RTCRoomPlayerAuthority").classList.remove("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerName").classList.remove("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerState").classList.remove("ready_background_color");
			break;
		case "ready":


				firebase.database().ref('rooms/' + roomID).once('value').then(room => {
					const room_users = Object.keys(room.val().users)
					if(room_users.length >= 2){
					document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "準備完了";
					document.querySelector("#" + user + " > .RTCRoomPlayerAuthority").classList.add("ready_background_color");
					document.querySelector("#" + user + " > .RTCRoomPlayerName").classList.add("ready_background_color");
					document.querySelector("#" + user + " > .RTCRoomPlayerState").classList.add("ready_background_color");
					}
					var AutoStart = true
					firebase.database().ref('users/').once('value').then(users => {
						firebase.database().ref('Version').once('value').then(Version => {
							if(users.val()[user].ver == null || +Version.val().replace(/\D/g,"") > +users.val()[user].ver.replace(/\D/g,"")){
								var updates = {};
								updates['users/' + user + '/state'] = "OldVer";
								firebase.database().ref().update(updates);
								document.querySelector("#" + user + " > .RTCRoomPlayerAuthority").classList.remove("ready_background_color");
								document.querySelector("#" + user + " > .RTCRoomPlayerName").classList.remove("ready_background_color");
								document.querySelector("#" + user + " > .RTCRoomPlayerState").classList.remove("ready_background_color");
								return;
							}
							room_users.some(function(key){
								if(room.val().roomMaster == user && state == "ready"){
									AutoStart = true
									return true;
								}
								if(users.val()[key].state != "ready" && users.val()[key].state != "Auto_ready"){
									AutoStart = false
								}
							});
							if(!AutoStart){
								return;
							}

							//ゲーム前準備処理
							if(prevState == "ready" || prevState == "Auto_ready"){
								if(room_users.length >= 2){
									if(matchconfirm_sound){
										matchconfirm_sound_play()
									}
									document.getElementById("RTCbtnGameStart").disabled = true;
									document.getElementById("RTCbtnReady").disabled = true;
									document.getElementById("RTCbtnExit").disabled = true;
									window.removeEventListener("keydown" , ready_key)
									if(isRoomMaster){
										setTimeout(function(){
											if(prevState != "idle"){
												PreStartRM();
											}
										},1600)
									}
								}else{
									PreStartRM();
								}
							}
						}, room.val().users);
					});
				});
			break;
		case "Auto_ready":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "準備完了";
			document.querySelector("#" + user + " > .RTCRoomPlayerAuthority").classList.add("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerName").classList.add("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerState").classList.add("ready_background_color");

				firebase.database().ref('rooms/' + roomID).once('value').then(room => {
					var AutoStart = true
					firebase.database().ref('users/').once('value').then(users => {
						Object.keys(room.val().users).some(function(key){
							if(users.val()[key].state != "ready" && users.val()[key].state != "Auto_ready"){
								AutoStart = false
							}
						});
						if(!AutoStart){
							return;
						}

						//ゲーム前準備処理
							if(Object.keys(room.val().users).length >= 2){
								if(matchconfirm_sound){
								matchconfirm_sound_play()
								}
							document.getElementById("RTCbtnGameStart").disabled = true;
							document.getElementById("RTCbtnReady").disabled = true;
							document.getElementById("RTCbtnExit").disabled = true;
							window.removeEventListener("keydown" , ready_key)
							if(isRoomMaster){
								setTimeout(function(){
									if(prevState != "idle"){
										PreStartRM();
									}
								},1600)
							}
							}else{
								PreStartRM();
							}
					}, room.val().users);
				});
			break;
		case "play":
			if(prevState == "preStart"){
				console.log("played")
				ready_player++
				document.querySelector("#__" + user + " > .RTCLine").classList.remove("ready_loading")
				if(Object.keys(Players_ID).length <= ready_player){
					playing = true
					prevState = "play"
					console.log(0)
					window.removeEventListener("keydown",preventScrollBySpacaKey)
					player.setVolume(volume)
					playing_interval = setInterval(function(){
						console.log(1)
						if(playing){
							player.pauseVideo();
							player.playVideo();
							clearInterval(playing_interval)
						}
					},10)
					document.getElementsByClassName("playarea")[0].classList.remove("is-hide");
					document.getElementsByClassName("status")[0].classList.remove("flex_100");
				}
			}
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "プレイ中";
			document.querySelector("#" + user + " > .RTCRoomPlayerAuthority").classList.remove("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerName").classList.remove("ready_background_color");
			document.querySelector("#" + user + " > .RTCRoomPlayerState").classList.remove("ready_background_color");
			break;
		case "preStart":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "プレイ中";
			if(user == myID && !playing){
				prevState = "preStart"
					//ゲーム前準備処理
				console.log("preStart")
					PreStart();
			}
			break;
		case "timeOut":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "タイムアウト";
			if(user == myID){
				isWrittenAFKState = true
			}
			break;
		case "afk":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "afk";
			if(user == myID){
				isWrittenAFKState = true
			}
			break;
		case "result":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "プレイ終了";
			break;
		case "OldVer":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "バージョン古";
			break;
		case "not_playable":
			document.querySelector("#" + user + " > .RTCRoomPlayerState").innerHTML = "再生不可";
			break;
	}
}


var isRoomMaster = false;

/**
*@Description ルームマスターになった。
*/
function becomeRoomMaster(){
	if(isRoomMaster){return;}
    isSECancel = true;
    setTimeout(function(){
        isSECancel = false;
    }, 1500);
	if(!isSECancel){
		matchconfirm_sound_play()
	}
    var updates = {};
	firebase.database().ref('rooms/' + roomID + '/movieID').on('value', RoomStateChange)
	firebase.database().ref('rooms/' + roomID).once('value').then(room => {
		if(room.val().movieID != movieID){
			updates['/rooms/' + roomID + '/movieID' ] = movieID;
			updates['/rooms/' + roomID + '/movieTitle' ] = movieTitle;
			firebase.database().ref().update(updates);
		}
	})

    var cngRMbts = document.getElementsByClassName("RTCRoomBtChangeRM");
    var Banbts = document.getElementsByClassName("RTCRoomBtBan");

    Array.prototype.forEach.call(cngRMbts, function(bt) {
       if(bt.parentNode.id != myID){
            bt.classList.remove("is-hide");
        }
    });
    Array.prototype.forEach.call(Banbts, function(bt) {
       if(bt.parentNode.id != myID){
            bt.classList.remove("is-hide");
        }
    });

	document.getElementById("RoomNameArea").setAttribute("contentEditable","true")
	document.getElementById("RoomNameArea").addEventListener("input",RoomName_Change)
    document.getElementById("RTCPlaybtSpeedlt").classList.remove("is-hide");
    document.getElementById("RTCPlaybtSpeedgt").classList.remove("is-hide");
	document.getElementById("combat_mode").removeAttribute("disabled")
	document.getElementById("skip_mode").removeAttribute("disabled")
    document.getElementById("RTCbtnReady").classList.add("is-hide");
    document.getElementById("RTCbtnGameStart").classList.remove("is-hide");

    isRoomMaster = true;
}

/**
*@Description ルームマスターではなくなった。
*/
function becomeCommon(){
    if(!isRoomMaster){return;}
	firebase.database().ref('rooms/' + roomID + '/movieID').off('value', RoomStateChange)
    var cngRMbts = document.getElementsByClassName("RTCRoomBtChangeRM");
    var Banbts = document.getElementsByClassName("RTCRoomBtBan");
    Array.prototype.forEach.call(cngRMbts, function(bt) {
        if(bt.parentNode.id != myID){
            bt.classList.add("is-hide");
        }
    });
    Array.prototype.forEach.call(Banbts, function(bt) {
        if(bt.parentNode.id != myID){
            bt.classList.add("is-hide");
        }
    });
	document.getElementById("RoomNameArea").setAttribute("contentEditable","false")
	document.getElementById("RoomNameArea").removeEventListener("input",RoomName_Change)
    document.getElementById("RTCPlaybtSpeedlt").classList.add("is-hide");
    document.getElementById("RTCPlaybtSpeedgt").classList.add("is-hide");
	document.getElementById("combat_mode").setAttribute("disabled","")
	document.getElementById("skip_mode").setAttribute("disabled","")
    document.getElementById("RTCbtnReady").classList.remove("is-hide");
    document.getElementById("RTCbtnGameStart").classList.add("is-hide");

    isRoomMaster = false;
}

/**
*@Description ルームマスター権限を渡す ボタンが押された。
*/
function onButtonChangeRM(event){
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
              firebase.database().ref('rooms/' + roomID + '/users/' + event.path[1].id).once('value').then(user => {
                  if (window.confirm("RealTimeCombatting:" + user.val() + " にルームマスター権限を渡します。よろしいですか?")) {
					  var updates = {};
					  prevState = "idle"
					  updates['users/' + myID + '/state'] = "idle";
                      updates['/rooms/' + roomID + '/roomMaster' ] =  event.path[1].id;
                      firebase.database().ref().update(updates);
					  document.getElementById("RTCbtnReady").setAttribute("value","準備完了");
                  }
              });
        }
    });
}

/**
*@Description キックする ボタンが押された。
*/
function onButtonBan(event){
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
            firebase.database().ref('rooms/' + roomID + '/users/' + event.path[1].id).once('value').then(user => {
				const kick_password = Math.floor( Math.random() * (999 + 1 - 100) ) + 100
const pass_form = window.prompt("RealTimeCombatting: " + user.val() + " さんをルームからキックします。\nよろしければ入力欄に "+kick_password+" を入力してください。")
                if (pass_form == kick_password) {
                    var updates = {};
                    updates['/rooms/' + roomID + '/users/' + event.path[1].id] = null;
					updates['/rooms/' + roomID + '/kick/' + event.path[1].id] =  event.path[1].id;
					updates['users/' + event.path[1].id + '/roomID'] = null;
                    firebase.database().ref().update(updates);
					window.alert("RealTimeCombatting: " + user.val() + " さんをルームからキックしました。")
                }
            });
        }
    });
}


/**
*@Description 。player情報をDBから削除
*@param playerID
*@param roomID nullならroomからの削除処理はしない
*/
function ForcePlayerDelete(playerID, _roomID){

    var updates = {};

    if(_roomID == null){
firebase.database().ref('users/' + playerID).once('value').then(player_info => {
	if(player_info.val().roomID != null){
		ForcePlayerDelete(playerID, player_info.val().roomID)
		return;
	}else{
		updates['/users/' + playerID] = null;
	}
	firebase.database().ref().update(updates);
})
    }else{
        firebase.database().ref('rooms/' + _roomID).once('value').then(room => {
			let room_user_array = room.val().users
			if(room_user_array){
				updates['/users/' + playerID] = null;
				delete room_user_array[playerID]
			}
            //最後の1人ならRoom削除
            if(!room_user_array || Object.keys(room_user_array).length == 0){
                updates['/rooms/' + _roomID] = null;
            }else if(room.val().roomMaster == myID){
                //ルームマスターならマスター権限の移動
                var masterID;
                Object.keys(room.val().users).forEach(function(id){
                    if(id != playerID){
                        masterID = id;
                    }
                });
                updates['/rooms/' + _roomID + '/roomMaster'] = masterID;
            }
			if(updates["/rooms/"+_roomID] === undefined){
			updates['/rooms/' + _roomID + '/users/' + playerID] = null;
			}
			firebase.database().ref().update(updates);
        });
    }
}


/**
*@Description キックされた
*/
function kicked(){
	//alert("RealTimeCombatting:" + document.getElementById("RTCRoomName").textContent + "からキックされました。以降入室することができません。");
    location.reload();
    ExitRoom();
}


/**
*@Description 対戦モードが変更された
*/
function onChangeCombatMode(event){
    playSE("click");
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
			var updates = {};
            updates['/rooms/' + roomID + '/playMode'] = document.getElementById("combat_mode").value;
            firebase.database().ref().update(updates);
        }
    });
}

function onChangeSkipMode(event){
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
			var updates = {};
            updates['/rooms/' + roomID + '/skipMode'] = document.getElementById("skip_mode").value;
            firebase.database().ref().update(updates);
        }
    });
}

/**
*@Description プレイ速度変更ボタンが押された
*/
function onClickPlaySpeedlt(event){
    playSE("click");
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
            var ps = room.val().playSpeed - 1;
            if(ps < 0){
                ps = 0;
            }
            var updates = {};
            updates['/rooms/' + roomID + '/playSpeed'] = ps;
            firebase.database().ref().update(updates);
        }
    });
}

/**
*@Description プレイ速度変更ボタンが押された
*/
function onClickPlaySpeedgt(event){
    playSE("click");

    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        if(room.val().roomMaster == myID){
            var ps = room.val().playSpeed + 1;
            if(ps >= playSpeeds.length){
                ps = playSpeeds.length - 1;
            }
            var updates = {};
            updates['/rooms/' + roomID + '/playSpeed'] = ps;
            firebase.database().ref().update(updates);
        }
    });
}


/**
*@Description 準備完了ボタンを押した
*/

let ReadyTimeStamp = 0
function onClickBtnReady(event){
    firebase.database().ref('users/' + myID).once('value').then(user => {
		var updates = {};
		const now_date = new Date().getTime()
        if(user.val().state == "idle" && LocationDateTimeStamp){
			console.log(LocationDateTimeStamp)
			ReadyTimeStamp = new Date().getTime()
            playSE("enter");
			prevState = "ready"
            updates['users/' + myID + '/state'] = "ready";
            firebase.database().ref().update(updates);
            document.getElementById("RTCbtnReady").setAttribute("value","準備完了を解除");
        }else if(user.val().state != "OldVer" && user.val().state != "not_playable" && now_date-ReadyTimeStamp > 1000){
			playSE("cancel");
			prevState = "idle"
            updates['users/' + myID + '/state'] = "idle";
			firebase.database().ref().update(updates);
            document.getElementById("RTCbtnReady").setAttribute("value","準備完了");
        }
    });
}

/**
*@*(F5時)1分以上更新されていない部屋&人データを削除
*/


function deleteIdlePlayerAndRoom(){


	const TIME_FOR_DELETE = 60000;
    var nowTime = LocationDateTimeStamp+(new Date().getTime()-LocalDateTimeStamp)

    firebase.database().ref('users/').once('value').then(users => {
        firebase.database().ref('rooms/').once('value').then(rooms => {
			if(rooms.val() != null){ //ルーム有り

				//現在ログインしていない人と部屋の削除
				Object.keys(rooms.val()).forEach(function(roomID){
					var roomInfo = rooms.val()[roomID];

					//ユーザーが存在しない部屋を削除
					if(!roomInfo.users){
						ForcePlayerDelete(null ,roomID)
						return;
					}

					//部屋にユーザーがいた場合の処理
					Object.keys(roomInfo.users).forEach(function(userID){

						//部屋内のログアウトしているユーザーを削除
						if(users.val()[userID] == null){
							ForcePlayerDelete(userID, roomID);
							return;
						}

/**
 * 部屋内の1分以上タイムアウトしているユーザーを削除
 * @param PlayerTimeStamp {number} ユーザーのタイムスタンプ
 */
						//
						const PlayerTimeStamp = userID != myID ? users.val()[userID].DeletetimeStamp : LocationDateTimeStamp+(new Date().getTime()-LocalDateTimeStamp)

						if(nowTime > TIME_FOR_DELETE + PlayerTimeStamp){
							ForcePlayerDelete(userID, roomID);
						}
					});
				});
			}
			if(users.val() != null){
				//その他の人の削除
				Object.keys(users.val()).forEach(function(userID){
					const PlayerTimeStamp = users.val()[userID].DeletetimeStamp;
					if(!PlayerTimeStamp){
						var updates = {};
						updates['/users/' + userID + '/DeletetimeStamp'] = nowTime
						firebase.database().ref().update(updates);
					}
					if(nowTime > TIME_FOR_DELETE + PlayerTimeStamp){
						ForcePlayerDelete(userID);
					}
				});
			}
		});
	});
}

/**
*@note room関連 ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////










/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*@note ゲーム中処理 ここから ---
*/

/**
*@note (ルームマスター)ゲーム開始ボタンを押した
*/
let Enter_flag = true
function onClickBtnGameStart(event){
	if(!LocationDateTimeStamp){
		Enter_flag = true
		return;
	}
    //room内の全員が準備完了かどうか確認
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        firebase.database().ref('users/').once('value').then(users => {
			var isEveryoneReady = true;
            Object.keys(room.val().users).forEach(function(key){
                if(users.val()[key].state != "ready" && key != myID){
					isEveryoneReady = false;
				}
            });
            if(!isEveryoneReady){
              if (!window.confirm("RealTimeCombatting: ルーム内全員が準備完了ボタンを押していません。ゲームをスタートしてもよろしいですか?")) {
				  Enter_flag = true
                  return;
              }
            }
			var updates = {};
			prevState = "ready"
			updates['users/' + myID + '/state'] = "ready";
			firebase.database().ref().update(updates);
			window.removeEventListener("keydown" , ready_key)
        }, room.val().users);
    });

}

/**
*@note (ルームマスター)ゲーム開始ボタンを押した
*/
let Pre_flag = false
let combating_mode = "Score"
let Players_ID = {}
let RoomMaster_ID = ""
let ready_users=0
function PreStartRM(){
    //全員の状態をpreStartへ。
	firebase.database().ref('rooms/' + roomID).once('value').then(room => {
		firebase.database().ref('users/').once('value').then(users => {
			var updates = {};
			Object.keys(room.val().users).forEach(function(key){
				if(users.val()[key].state == "ready" || users.val()[key].state == "Auto_ready" || key == myID){
					ready_users++
					updates['users/' + key + '/state'] = "preStart";
				}
			}, room.val().users);
			updates['rooms/' + roomID + '/state'] = "play";
			const new_Date = new Date().getTime()
			updates['rooms/' + roomID + '/StartTime'] = LocationDateTimeStamp+(new_Date-LocalDateTimeStamp);
			Pre_flag = true
			firebase.database().ref().update(updates);
		});
    });
}
/**
*@note ゲーム開始準備処理
*/

let speed_background = "transparent"
let speed_color = "rgba(255,255,255,.85)"
let RTCGamePlayPlayersStatusTableSelector
let Skip_Mode = "HOST"
let FirstVideoLoadedCheck
let selected_play_mode

function PreStart(){

	feedout_volume = +localStorage.getItem("volume_storage")
    //プレイスピードをroomの設定に合わせる。
	if( typeof title_speed != "number"){
    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        player.setPlaybackRate( playSpeeds[room.val().playSpeed]);
		document.getElementById("playspeed").textContent = speed.toFixed(2)+"倍速"
		document.getElementById("speed").textContent = play_speed.toFixed(2)+"倍速"

		if(play_mode == "normal"){
			if(play_speed == 2){
				speed_background = "#ed143d99"
				speed_color = "ghostwhite"
			}else if(play_speed == 1.75){
				speed_background = "#9370dba9"
				speed_color = "ghostwhite"
			}else if(play_speed == 1.5){
				speed_background = "#00ff7f7a"
				speed_color = "#FFF"
			}else if(play_speed == 1.25){
				speed_background = "#4ed6ff73"
			}else if(play_speed == 1){
				speed_background = "transparent"
			}
			document.getElementById("speed").setAttribute("style", `
    color:`+speed_color+`;
    background:`+speed_background+`;`);
		}
	});
	}
	var updates = {};
	updates['/users/' + myID + '/status/ClearTime'] = null;
	firebase.database().ref().update(updates);
    //プレイステータスをすべて初期値に戻す
	updates = {};
    updates['/users/' + myID + '/status/score'] = "0.00";
    updates['/users/' + myID + '/status/miss'] = 0;
    updates['/users/' + myID + '/status/combo'] = 0;
    updates['/users/' + myID + '/status/clearline'] = 0;
    updates['/users/' + myID + '/status/combo'] = 0;
    updates['/users/' + myID + '/status/maxCombo'] = 0;
    updates['/users/' + myID + '/status/type'] = 0;
    updates['/users/' + myID + '/status/correct'] = 100;
    updates['/users/' + myID + '/status/moviePos'] = "0"
    updates['/users/' + myID + '/status/lineInput'] = " ";
    updates['/users/' + myID + '/status/lineRemain'] = " ";
	updates['/users/' + myID + '/status/SkipOptin'] = " ";
    updates['/users/' + myID + '/status/keySec'] = "0.00";
	updates['/users/' + myID + '/status/ClearTime/start'] = 0;

	firebase.database().ref().update(updates);


    //表示画面の切り替え
    document.getElementById("RTCRoomIdleScene").classList.add("is-hide");
    document.getElementById("RTCGamePlayScene").classList.remove("is-hide");


	combating_mode = document.getElementById("combat_mode").value
	Skip_Mode = document.getElementById("skip_mode").value
	// 選択状態を再設定(TypingTubeMODと競合しないように)
	selected_play_mode = document.querySelector("[name=rbPlayMode]:checked").value
	if(selected_play_mode == "kana"){
		mode = 'kana';
		kana_mode = false;
		keyboard='normal';
	}else if(selected_play_mode == "roma"){
		mode = 'roma';
		kana_mode = false;
		keyboard='normal';
	}else if(selected_play_mode == "kanaInput"){
		mode = 'kana';
		kana_mode = true;
		keyboard='normal';
	}else if(selected_play_mode == "flickInput"){
		mode = 'kana';
		kana_mode = true;
		keyboard='mac';
	}
	window.removeEventListener("keydown" , ready_key)
	player.setVolume(volume/7.5)

    //チャットを非表示にする
    $('.chatArea').animate({height: 'hide'}, 'slow');


	//対戦エリアの表示設定を呼び出し
	const ViewMode = localStorage.getItem("combat_ranking_ViewMode")
	if(ViewMode){
		combat_ranking_ViewMode = ViewMode
	}


if(ready_users >= 2 || !isRoomMaster){
	let mode_color = "transparent"
	if(combating_mode == "Combo"){
		mode_color = "#fd7e009e"
	}else if(combating_mode == "Line"){
		mode_color = "#37a34a"
	}else if(combating_mode == "Perfect"){
		mode_color = "#dab3008c"
	}

	//controlエリアを対戦用に変更
	document.getElementById("time_settings").style.marginTop = "8px"
	document.getElementById("time_settings").style.marginBottom = "8px"
	document.getElementById("speed_change_F10").style.display = "none"
	document.getElementById("song_reset").style.display = "none"
	document.getElementById("shortcut").style.zIndex = "6"
	document.getElementById("speed").style.border = "solid thin"
	document.getElementById("speed").classList.remove('pointer');
	document.getElementById("more_shortcutkey").style.display = "none"
	document.getElementById("more_shortcutkey").insertAdjacentHTML('afterend',`<div id="battle_mode"><span style="border:solid thin;background:`+mode_color+`;" class="control_option">`+(combating_mode == "Line" ? "Line先取" : combating_mode)+`</span></div>`)

	document.getElementById("song_reset").insertAdjacentHTML('afterend',`<div id="battle_container_display"><span id="battle_container_display_button" class="control_option pointer">順位表示切り替え</span><span id="battle_container_display_button_F1" class="shortcut_navi hover_dom select_none">F1</span></div>`)
	document.getElementById("battle_container_display").addEventListener("click",battle_container_change)
	document.getElementById("battle_container_display_button_F1").addEventListener("mouseover",function battle_container_underline(event){
		document.getElementById("battle_container_display_button").style.textDecoration = "underline"
	})
	document.getElementById("battle_container_display_button_F1").addEventListener("mouseout",function battle_container_underline_delete(event){
		document.getElementById("battle_container_display_button").style.textDecoration = ""
	})
	document.querySelector("#shortcut > div").style.display = "none"

	//ルーム情報更新イベント削除
	firebase.database().ref('/rooms/' + roomID).off('child_changed', onUpdateRoomInfo);
	//カウントダウン
	ClockCountDownFirst();

}

	//ステータス表示用のテーブルの作成
	var table = document.getElementById("RTCGamePlayPlayersStatusTable");
	while(table.firstChild){
		table.firstChild.remove();
	}
	//スペースキーによるscrollの無効化
	window.addEventListener("keydown",preventScrollBySpacaKey)
	//ルーム内ユーザーに対してイベントハンドラを追加
	firebase.database().ref('rooms/' + roomID).once('value').then(room => {
		RoomMaster_ID = room.val().roomMaster
		firebase.database().ref('users/').once('value').then(users => {
			Object.keys(room.val().users).forEach(function(key){
				if(users.val()[key].state == "preStart"){
					Players_ID[key] = users.val()[key].name
					firebase.database().ref('users/' + key + '/status').on('child_changed', onUpdateRoomUserInfo);
					firebase.database().ref('users/' + key + '/state').on('value', onUpdateRoomUserState)

					if(combating_mode == "Line"){
						ClearTime_addevent_target = firebase.database().ref('users/' + key + '/status/ClearTime');
						ClearTime_addevent_target.on('child_added', add_clear_time);
					}
				}

				if(document.getElementById("_" + key) != null){
					return;
				}

				if(users.val()[key].state == "preStart"){
                    var DOMtr = document.createElement("tr");
                    DOMtr.id = "_" + key ;
                    if(key == myID){
                        DOMtr.classList.add("mine");
                    }
					if(key == RoomMaster_ID){
						DOMtr.classList.add("host");
					}
                    DOMtr.setAttribute("style","font-size:14px;font-weight:bold");

                    document.getElementById("RTCGamePlayPlayersStatusTable").appendChild(DOMtr);

                    var DOMrank = document.createElement("td");
                    DOMrank .classList.add("RTCrank");
                    DOMrank.setAttribute("style","width:7%;");
                    DOMrank.setAttribute("rowspan","2");
                    DOMrank.innerHTML = "1位";
                    DOMtr.appendChild(DOMrank);

                    var DOMname = document.createElement("td");
                    DOMname.innerHTML = users.val()[key].name;
                    DOMname.setAttribute("rowspan","2");
                    DOMname.setAttribute("style","width:11%;");

                    DOMtr.appendChild(DOMname);


                    var DOMscore = document.createElement("td");
                    DOMscore .classList.add("RTCscore");
                    if(key == myID){
						DOMscore .classList.add("mine_score");
                    }
                    DOMscore.setAttribute("style","width:9%;");
					DOMscore.innerHTML = "0.00点"
                    var DOMclear = document.createElement("td");
                    DOMclear .classList.add("RTCclear");
                    DOMclear.setAttribute("style","width:9%;");
					if(combating_mode != "Line"){
						DOMtr.appendChild(DOMscore);
					}else{
						DOMclear.innerHTML = "0pt"
						DOMtr.appendChild(DOMclear);
					}
                    var DOMmiss = document.createElement("td");
                    DOMmiss.classList.add("RTCmiss");
                    DOMmiss.setAttribute("style","width:9%;");
                    DOMmiss.innerHTML = "0ミス";
                    DOMtr.appendChild(DOMmiss );

                    var DOMcombo = document.createElement("td");
                    DOMcombo.classList.add("RTCcomboArea");
                    DOMcombo.setAttribute("style","width:16%;");
                    DOMcombo.innerHTML = "<span class='RTCcombo'>0</span> / <span class='RTCmaxcombo'>0</span> コンボ";
                    DOMtr.appendChild(DOMcombo);

                    var DOMtype = document.createElement("td");
                    DOMtype.classList.add("RTCtype");
                    DOMtype.setAttribute("style","width:9%;");
                    DOMtype.innerHTML = "0打";
                    DOMtr.appendChild(DOMtype);

                    var DOMcorrect = document.createElement("td");
                    DOMcorrect .classList.add("RTCcorrect");
                    DOMcorrect.setAttribute("style","width:9%;");
                    DOMcorrect .innerHTML = "100%";
                    DOMtr.appendChild(DOMcorrect);
					if(combating_mode != "Line"){
						DOMclear.innerHTML = "0clear"
						DOMtr.appendChild(DOMclear);
					}else{
						DOMtr.appendChild(DOMscore);
					}
                    var DOMkeySec = document.createElement("td");
                    DOMkeySec .classList.add("RTCkeySec");
                    DOMkeySec.setAttribute("style","width:11%;");
                    DOMkeySec .innerHTML = "0.00key/sec";
                    DOMtr.appendChild(DOMkeySec);

                    var DOMTime = document.createElement("td");
                    DOMTime .classList.add("RTCtime");
                    DOMTime.setAttribute("style","width:12%;");
                    DOMTime .innerHTML = "0秒";
                    DOMtr.appendChild(DOMTime);


                     var DOMLinetr = document.createElement("tr");
                    DOMLinetr.id = "__" + key ;
                    if(key == myID){
                        DOMLinetr.classList.add("mine");
                    }
					if(key == RoomMaster_ID){
						DOMLinetr.classList.add("host");
					}
                    DOMLinetr.setAttribute("style","font-size:10px;font-weight:bold");
                    document.getElementById("RTCGamePlayPlayersStatusTable").appendChild(DOMLinetr);


                    var DOMLine = document.createElement("td");
                    DOMLine .classList.add("RTCLine","ready_loading");
                    if(key == myID){
						DOMscore .classList.add("mine_line");
					}
                    DOMLine.setAttribute("colspan","7");
                    DOMLine.setAttribute("style","max-width: 350px;white-space: nowrap;overflow:hidden;");
                    DOMLinetr.appendChild(DOMLine);

                    var DOMInputMode = document.createElement("td");
                    DOMInputMode .classList.add("InputMode");
                    DOMInputMode.innerHTML = users.val()[key].status.InputMode;
                    DOMInputMode.setAttribute("style","font-size:12px");
                    DOMLinetr.appendChild(DOMInputMode);

                    var DOMlineInput = document.createElement("span");
                    DOMlineInput .classList.add("RTClineInput");
                    DOMLine.appendChild(DOMlineInput);

                    var DOMlineRemain = document.createElement("span");
                    DOMlineRemain .classList.add("RTClineRemain");
                    DOMlineRemain .innerHTML = " ";
                    DOMLine.appendChild(DOMlineRemain);
                }

            }, room.val().users);
			RTCGamePlayPlayersStatusTableSelector = document.getElementById("RTCGamePlayPlayersStatusTable")
			if(ready_users == 1){
				//ソロプレイ時のカウントダウン
				ClockCountDownFirst();
			}
			document.getElementById("RTCGamePlayWrapper").scrollTo({
				top:999
			})
			if(localStorage.getItem("RTC_Scroll") != "false"){
				const gauge_height = (document.getElementById("gauge").clientHeight - (document.getElementById("gauge").clientHeight > 0 ? -20:0))
				const absolute_controlbox_point = window.pageYOffset+CONTROLBOX_SELECTOR.getBoundingClientRect().top-gauge_height-document.getElementsByTagName("header")[0].clientHeight
				const display_size_height = document.documentElement.clientHeight-document.getElementsByTagName("header")[0].clientHeight
				window.scrollTo({top: absolute_controlbox_point-(display_size_height > CONTROLBOX_SELECTOR.clientHeight+50 ? localStorage.getItem('scroll_adjustment1') : 0)})
			}
			ready_users = Object.keys(Players_ID).length
		});
	});
}

function preventScrollBySpacaKey(){
        if(event.code == "Space" && document.activeElement.tagName != "INPUT"){
           event.preventDefault();
        }
}

var isFirstClockCountDown =true;
var startTime; //ホストが開始ボタンを押したTimeStamp
var countDown = 3;
/**
*@note プレイ前カウントダウンはじめ
*/
function ClockCountDownFirst(){
        startTime = parseInt(new Date().getTime() +(ready_users >= 2 || !isRoomMaster ? 3000:0));
        countDown = 3;
	if(ready_users >= 2 || !isRoomMaster){
	CountDown_sound_play()
	}
	ClockCountDown();
}

/**
*@note プレイ前カウントダウン
*/
let feedout_volume = 0
let volume_feedout

function ClockCountDown(){
    var now =new Date().getTime()

    if(now < startTime){
       var  ct = Math.ceil(((startTime - now) * 0.001));
        if(ct == countDown){
			if(countDown == 2 && demo_play_flag){
				feedout_volume = +localStorage.getItem("volume_storage")/7.5
				volume_feedout = setInterval(function(){
					feedout_volume --
					player.setVolume(feedout_volume)
					if(feedout_volume < 0){
						demo_play_flag = false
						feedout_volume = +localStorage.getItem("volume_storage")/7.5
						player.pauseVideo()
						clearInterval(volume_feedout);}
				},75)
			}
            countDown--;
			if(countDown <= 2){
				CountDown_sound_play()
			}
        }
		document.getElementById("RTCRoomMes").style.display = "block"
        document.getElementById("RTCRoomMes").innerHTML = "開始まであと" + ct+ "秒です。";


        setTimeout(ClockCountDown, 100);
	}else{
		if(Object.keys(Players_ID).length >= 2){
			countDownEnd_sound_play()
		}
		document.getElementById("RTCRoomMes").style.display = "none"
		document.getElementById("RTCRoomMes").innerHTML = " ";
		const users = document.getElementById("RTCGamePlayPlayersStatusTable").children;
		document.getElementById("RTCGamePlayWrapper").scrollTo({
			top:combat_ranking_ViewMode == "Scroll" ? (document.getElementsByClassName("mine")[1].querySelector(".RTCrank").clientHeight*(([].slice.call( users ).indexOf(document.getElementsByClassName("mine")[1])/2)-6)):0,
		})
		if(combat_ranking_ViewMode == "none"){
			document.getElementById("RTCContainer").style.display = "none"
			document.querySelector('[class="wrapper row mt-5 w-80"]').parentNode.setAttribute("style","margin-top:250px!important;")
		}
		console.log(-1)
		player.playVideo()
		player.seekTo(0);

    }
}


var isDispFmtKeySec = true; //true:key/sec形式で表示 false key/min形式で表示
/**
*@note ルーム内ユーザーの状態が変更された。
*/
let rank = -5
let HostLineCount = 0

function onUpdateRoomUserState(snapshot){
	const uid = snapshot.ref_.path.pieces_[1];
	const Update_Info = snapshot.ref_.path.pieces_[3]

	if(RTCGamePlayPlayersStatusTableSelector == null){return;}
	const SnapShotValue = snapshot.val()
//	BubbleSort()
	if(SnapShotValue == "end"){
		delete Players_ID[uid]
	}else if(SnapShotValue == "result"){
		RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCtime").textContent = "プレイ終了";
		firebase.database().ref('users/' + uid + '/status').off('child_changed', onUpdateRoomUserInfo);
		firebase.database().ref('users/' + uid + '/state').off('value', onUpdateRoomUserState)
		delete Players_ID[uid]
	}else if(SnapShotValue != "play"){
		firebase.database().ref('rooms/' + roomID + '/state').once('value').then(room_state => {
			firebase.database().ref('users/' + uid + '/status').off('child_changed', onUpdateRoomUserInfo);
			firebase.database().ref('users/' + uid + '/state').off('value', onUpdateRoomUserState)
			delete Players_ID[uid]
			if(room_state.val() == "play"){
				RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineInput").textContent = " ";
				RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineRemain").textContent = "タイムアウトしました。";
			}else{
				RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCtime").textContent = "プレイ終了";
			}
		})
	}
if(Object.keys(Players_ID).length == 0 ){
	//勝者を記録
	const users = document.getElementById("RTCGamePlayPlayersStatusTable").children;
	if(users.length > 2){
		firebase.database().ref('rooms/' + roomID).once('value').then(room => {
			const StartTime = room.val().StartTime

			var updates = {}
			if(room.val().Winner){
				if(Object.values(room.val().Winner).flat().includes(StartTime)){
					return;
				}

				let Win_data = Object.keys(room.val().Winner)

				for (let i = 0; i < users.length/2; i++){
					if(document.getElementsByClassName("RTCrank")[i].textContent == "1位"){
						const Winner_ID = document.getElementsByClassName("RTCrank")[i].parentElement.id.slice(1)
						const idx = Win_data.indexOf(Winner_ID);
						if(idx >= 0){
							Win_data.splice(idx, 1);
						}
					}else{
						break;
					}
				}
				for (let i = 0; i < Win_data.length; i++){
					updates['/rooms/' + roomID + '/Winner/' + Win_data[i]] = null
				}
				firebase.database().ref().update(updates);
			}

			firebase.database().ref('rooms/' + roomID + '/Winner').once('value').then(Winner => {
				var updates = {}
				for (let i = 0; i < users.length/2; i++){
					if(document.getElementsByClassName("RTCrank")[i].textContent == "1位"){
						const Winner_ID = document.getElementsByClassName("RTCrank")[i].parentElement.id.slice(1)
						let Win_count = Winner.val() && Winner.val()[Winner_ID] && Winner.val()[Winner_ID].length ? Winner.val()[Winner_ID].concat(StartTime) : [StartTime]
						updates['/rooms/' + roomID + '/Winner/' + Winner_ID] = Win_count.length > 1 ? Win_count.filter((x, i, self) => self.indexOf(x) === i):Win_count
					}else{
						break;
					}
				}
				firebase.database().ref().update(updates);
			})
		})
	}
}
}


function onUpdateRoomUserInfo(snapshot){
    const uid = snapshot.ref_.path.pieces_[1];
	const Update_Info = snapshot.ref_.path.pieces_[3]
    if(RTCGamePlayPlayersStatusTableSelector == null){return;}
	const SnapShotValue = snapshot.val()
    switch(Update_Info){
        case "clearline":
			if(combating_mode != "Line"){
				RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCclear").textContent = SnapShotValue+"clear"
			}
			break;
		case "combo":
            RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " .RTCcombo").textContent =  SnapShotValue;
			break;
        case "maxCombo":
            RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " .RTCmaxcombo").textContent =  SnapShotValue;
			break;
        case "correct":
            RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCcorrect").textContent = SnapShotValue +"%";
            break;
        case "keySec":
			if(isDispFmtKeySec){
				RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCkeySec").textContent = SnapShotValue + 'key/sec';
			}else{
				RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCkeySec").textContent = Math.round(SnapShotValue * 60) + 'key/min';
			}
			break;
		case "lineInput":
			const RTCLineWidth = RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine")
			const LineInput = RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineInput")
			if(RTCLineWidth.scrollWidth > RTCLineWidth.clientWidth && RTCLineWidth.clientWidth / LineInput.offsetWidth < 2.5){
				RTCLineWidth.scrollLeft += document.querySelector("#__" + uid + " .RTClineRemain > span").offsetWidth
			}
			LineInput.innerHTML = SnapShotValue;
			if(!LineInput.textContent){
				RTCLineWidth.scrollLeft = 0
			}
			break;
		case "lineRemain":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineRemain").innerHTML = SnapShotValue;
			break;
		case "SkipOptin":
			if(typeof SnapShotValue === "number"){
			RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineRemain").insertAdjacentHTML('beforeend', "<span class='skip_opt_in' style='opacity: 0.4;'>"+(Skip_Mode == "HOST" && Players_ID[RoomMaster_ID] ? "":" skip⏩")+"</span>")
				const RTCLineWidth = RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine")
				RTCLineWidth.scrollLeft = RTCLineWidth.scrollWidth
			if(seeked_count != count && Object.keys(Players_ID).length <= document.getElementsByClassName("skip_opt_in").length){
				for(let i=0;i<document.getElementsByClassName("skip_opt_in").length;i++){
					document.getElementsByClassName("skip_opt_in")[i].style.display = "none"
				}
				seeked_count = count;
				player.seekTo((parseFloat(lyrics_array[count][0]) + player.difftime - 4)+(4-speed*4));
				stop_count = 0;
				playheadUpdate();
				replace_complete_area("Skip")
				if(Skip_Mode == "HOST"){
					SELECTOR_ACCESS_OBJECT['skip-guide'].textContent = ""
				}
			}
			}else{
			RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .RTCLine > .RTClineRemain").innerHTML = "";
			}
			break;
		case "miss":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCmiss").textContent = SnapShotValue +"ミス";
			break;
		case "moviePos":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCtime").textContent = SnapShotValue +"秒";
			break;
		case "score":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCscore").textContent = SnapShotValue +"点";
			break;
		case "type":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + uid + " > .RTCtype").textContent = SnapShotValue +"打";
			break;
		case "InputMode":
			RTCGamePlayPlayersStatusTableSelector.querySelector("#__" + uid + " > .InputMode").textContent = SnapShotValue
			break;
	}
	if(combating_mode != "Line" && (Update_Info == "score") || combating_mode == "Line" && Update_Info == "ClearTime"){
		//順位入れ替え
		BubbleSort(SnapShotValue,uid)
	}
}


function BubbleSort(SnapShotValue,uid){

	//順位入れ替え
	const users = document.getElementById("RTCGamePlayPlayersStatusTable").children;
	const users_column = users.length / 2
	var scores = {};
	var score_arr = []
	for (let i = 0; i < users.length; i+=2){
		const user_score = parseFloat(combating_mode != "Line" ? users[i].getElementsByClassName("RTCscore")[0].textContent : users[i].getElementsByClassName("RTCclear")[0].textContent);
		scores[i / 2] = user_score
		score_arr.push(user_score)
	}

	var tmp;
	let ranking
	//バブルソート
	for(let i = 0; i < users.length / 2; ++i){ //上位から
		for(var j = i; j < users.length / 2; ++j){
			if(scores[j] > scores[i]){
				users[j * 2 + 1].after(users[i * 2]);
				users[j * 2 + 1].after(users[i * 2]);
				users[i * 2].before(users[j * 2 - 1]);
				users[i * 2].before(users[j * 2 - 1]);
			}
		}
	}
	score_arr.sort(
		function(a,b){
			return (a < b ? 1 : -1);
		}
	);
	let Shift_rank = 0
	for (let i = 0; i < users.length; i+=2){
		const RTCrank = users[i].getElementsByClassName("RTCrank")[0]
		if(RTCrank){
			if(score_arr[ (i / 2)-1-Shift_rank] == score_arr[ (i / 2)]){
				Shift_rank++
			}
			RTCrank.textContent = ((i / 2) + 1 - Shift_rank) + "位";
			if(uid == myID && users[i].classList.value.indexOf("mine") > -1){
				ranking = (i / 2) + 1
				if(SnapShotValue == 0.00 && score){
					ranking = users_column
				}
			}
		}
	}
	if(score && combat_ranking_ViewMode == "Scroll"){
		if(Math.abs(ranking - rank) >= 1 || ranking <= 6){
			if(ranking > 6){
				document.getElementById("RTCGamePlayWrapper").scrollTo({
					top:(document.getElementsByClassName("mine")[1].querySelector(".RTCrank").clientHeight*(ranking-5)),

				})
			}else{
				document.getElementById("RTCGamePlayWrapper").scrollTo({
					top:(0),
				})
			}
			rank = ranking
		}
	}
}

var waitForSync = false;

/**
*@note lineが更新された ---
*/
function onLineUpdate(){
    clockSyncPlayer();
}


/**
*@note player line初めの同期処理 ---
*/
function clockSyncPlayer(){

    //もし、再生時間の一番遅い人に比べてTIME_ALLOWANCE以上進んでいたら待機
    var playerTimeMin = Number.MAX_VALUE;
    var myPlayerTime;
    var TIME_ALLOWANCE = 1.20;

    var now = new Date().getTime();
    var playerTimeStamps = {};
    var TIMEOUT_DIFF = 3000;

    firebase.database().ref('rooms/' + roomID).once('value').then(room => {
        firebase.database().ref('users/').once('value').then(users => {
            Object.keys(room.val().users).forEach(function(key){
                if(users.val()[key].state == "play"){
                    if(playerTimeMin > parseFloat(users.val()[key].status.moviePos)){
                        playerTimeMin = parseFloat(users.val()[key].status.moviePos);
                    }
                    playerTimeStamps[key] = users.val()[key].timeStamp;
                }
                else if(users.val()[key].state == "timeOut"){
                    document.querySelector("#__" + key + " > .RTCLine > .RTClineInput").innerHTML = " ";
                    document.querySelector("#__" + key + " > .RTCLine > .RTClineRemain").innerHTML = "タイムアウトしました。";
                }
            }, room.val().users);
            myPlayerTime = users.val()[myID].status.moviePos;

            //もしタイムアウトしている人がいれば、その人の状態をtimeOutへ
            Object.keys(playerTimeStamps).forEach(function(key){
                if(playerTimeStamps[key] < now -  TIMEOUT_DIFF){
//                     var updates = {};
//                     updates['/users/' + key + '/state'] = "timeOut";
//                     //もしその人がルームマスターなら自分がルームマスターになる。
//                     if(room.roomMaster == key){
//                      updates['/rooms/' + roomID + '/roomMaster'] = myID;
//                     }
//                     firebase.database().ref().update(updates);

//                     document.querySelector("#__" + key + " > .RTCLine > .RTClineInput").innerHTML = " ";
//                     document.querySelector("#__" + key + " > .RTCLine > .RTClineRemain").innerHTML = "タイムアウトしました。";
                }
            });

            if(myPlayerTime > parseFloat(TIME_ALLOWANCE) + playerTimeMin){
                waitForSync = true;
                player.pauseVideo();
                setTimeout(() => {
                    clockSyncPlayer();
                }, 10);
            }else{
                 waitForSync = false;
            }
        });
    });

}

/**
*@note ゲーム終了
*/
function endGames(){
	document.getElementById("RTCRoomMes").style.display = "block"
    document.getElementById("RTCRoomMes").innerHTML = "お疲れさまでした。続けて対戦する場合は更新ボダン(F5)を押してください。";
    firebase.database().ref('/rooms/' + roomID).on('child_changed', onUpdateRoomInfo);

	prevState = "result"
    var updates = {};
    updates['/rooms/' + roomID + '/state'] = "result";
    updates['/users/' + myID + '/state'] = "result";
    firebase.database().ref().update(updates);
}

/**
*@note ゲーム中処理 ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////







/////////////////////////////////////////////////////////////////////////////////////////////////

var isSECancel = false;

/**
*@note SE関連 ここから ---
*/
var SE_SET = {
   "enter":"https://soundeffect-lab.info/sound/button/mp3/decision5.mp3",
   "warning":"https://soundeffect-lab.info/sound/button/mp3/warning1.mp3",
    "exit":"https://soundeffect-lab.info/sound/button/mp3/decision23.mp3",
    "click":"https://soundeffect-lab.info/sound/button/mp3/cursor1.mp3",
    "cancel":"https://soundeffect-lab.info/sound/button/mp3/cancel2.mp3",

    "greet":"https://soundeffect-lab.info/sound/voice/mp3/game/swordwoman-greeting1.mp3",
    "chat":"https://soundeffect-lab.info/sound/various/mp3/bubble-burst1.mp3",
    "cngSong":"https://soundeffect-lab.info/sound/button/mp3/decision29.mp3",
 };

/**
*@note SEを鳴らす
*@param string SEname
*/
function playSE(SEname){
    if(isSECancel){return;}
    var se = new Audio();
    se.volume = (localStorage.getItem("volume_storage")/100)*(SEname == "greet"?0.5:1)
    se.src = SE_SET[SEname];
    se.play();
}


var matchconfirm_sound
var CountDown_sound //https://web.archive.org/web/20170618145501/http://soundeffect-lab.info/sound/button/mp3/cursor3.mp3
var countDownEnd_sound


function CountDown_sound_load(){
	var request_CountDown_sound = new XMLHttpRequest();
	request_CountDown_sound.open('GET', "https://dl.dropboxusercontent.com/s/hpn3k6msvnb2m3c/cursor3.mp3?dl=0", true);
	request_CountDown_sound.responseType = 'arraybuffer';
	request_CountDown_sound.onload = function() {
		CountDown_sound.decodeAudioData(request_CountDown_sound.response, function(buffer) {
			audio_buffer_CountDown_sound = buffer;
		}, function(){
			//エラー
		}
										  );
	};
	request_CountDown_sound.send();
};

function CountDown_sound_play(){
	let CountDown_sound_gain = CountDown_sound.createGain();
	let CountDown_sound_source = CountDown_sound.createBufferSource();
	CountDown_sound_source.buffer = audio_buffer_CountDown_sound;
	CountDown_sound_source.connect(CountDown_sound_gain);
	CountDown_sound_gain.connect(CountDown_sound.destination);
	CountDown_sound_gain.gain.value = (localStorage.getItem("volume_storage")/100)
	CountDown_sound_source.start(0);
}

function countDownEnd_sound_load(){
	var request_countDownEnd_sound = new XMLHttpRequest();
	request_countDownEnd_sound.open('GET', "https://dl.dropboxusercontent.com/s/pvzs4c3k9z4j923/decision1.mp3?dl=0", true);
	request_countDownEnd_sound.responseType = 'arraybuffer';
	request_countDownEnd_sound.onload = function() {
		countDownEnd_sound.decodeAudioData(request_countDownEnd_sound.response, function(buffer) {
			audio_buffer_countDownEnd_sound = buffer;
		}, function(){
			//エラー
		}
										  );
	};
	request_countDownEnd_sound.send();
};

function countDownEnd_sound_play(){
	let countDownEnd_sound_gain = countDownEnd_sound.createGain();
	let countDownEnd_sound_source = countDownEnd_sound.createBufferSource();
	countDownEnd_sound_source.buffer = audio_buffer_countDownEnd_sound;
	countDownEnd_sound_source.connect(countDownEnd_sound_gain);
	countDownEnd_sound_gain.connect(countDownEnd_sound.destination);
	countDownEnd_sound_gain.gain.value = (localStorage.getItem("volume_storage")/100)
	countDownEnd_sound_source.start(0);
}


function matchconfirm_sound_load(){
	var request_matchconfirm_sound = new XMLHttpRequest();
	request_matchconfirm_sound.open('GET', "https://dl.dropboxusercontent.com/s/25y0ey3wszmlgev/match-confirm.mp3?dl=0", true);
	request_matchconfirm_sound.responseType = 'arraybuffer';
	request_matchconfirm_sound.onload = function() {
		matchconfirm_sound.decodeAudioData(request_matchconfirm_sound.response, function(buffer) {
			audio_buffer_matchconfirm_sound = buffer;
		}, function(){
			//エラー
		}
										  );
	};
	request_matchconfirm_sound.send();
};

function matchconfirm_sound_play(){
	let matchconfirm_sound_gain = matchconfirm_sound.createGain();
	let matchconfirm_sound_source = matchconfirm_sound.createBufferSource();
	matchconfirm_sound_source.buffer = audio_buffer_matchconfirm_sound;
	matchconfirm_sound_source.connect(matchconfirm_sound_gain);
	matchconfirm_sound_gain.connect(matchconfirm_sound.destination);
	matchconfirm_sound_gain.gain.value = (localStorage.getItem("volume_storage")/100)*0.4
	matchconfirm_sound_source.start(0);
}
/**
*@note SE関連 ここまで ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////











/////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Toshi added code ここから  ---
* @note onPlayerStateChange; getScorePerChar;は既存関数書き換え
*/


let demo_play_flag = false
let BGM_time = -1
let BGM_time_flag = false

let skip_opt_in = false
let feedin_volume = -10
let volume_feedin



function getRoomKey(event){

firebase.database().ref('rooms/' + roomID).once('value').then(room => {
const PassWord = room.val().roomPassWord
if(isRoomMaster){
	let PassWord_Key = window.prompt( "パスワードを変更", PassWord )
if(PassWord_Key != null && PassWord_Key.length > 1) {
	var updates = {};
	updates['rooms/' + roomID + "/roomPassWord"] = PassWord_Key;
	firebase.database().ref().update(updates);
}else if(PassWord_Key == ""){
window.alert( "1文字以上のパスワードを設定してください。" )
}
}else{
	window.alert( "ルームパスワード: " + PassWord)
}

})
}
function RoomName_Change(event){
	if(/\n/.test(event.target.innerText)){
		document.activeElement.blur()
	}
	let event_target_id = event.target.innerText.replace(/\n/,"")
	event.target.textContent = event_target_id
if(event_target_id.length > 19){
event_target_id = event_target_id.slice(0,window.getSelection().focusOffset-1)+event_target_id.slice(window.getSelection().focusOffset)
document.getElementById("RoomNameArea").innerText = event_target_id
}
	var updates = {};
	updates['rooms/' + roomID + "/roomName"] = event_target_id;
	firebase.database().ref().update(updates);
}


        //ルームマスターの時はゲーム開始、非ルームマスターのときは準備完了ショートカットキー[Enter]

function ready_key(event){
	if(event.key == "Enter" && document.getElementById("RTCbtnGameStart") != null && document.getElementById("RTCbtnGameStart").disabled == false && isEnter && (document.activeElement.tagName != "INPUT" || document.activeElement.id == "ChatInput" && !document.getElementById("ChatInput").value)){
		if(isRoomMaster && Enter_flag){
			onClickBtnGameStart(event)
		}else{
			onClickBtnReady(event)
		}
	}
}

function battle_container_change(){
	if(combat_ranking_ViewMode == "Scroll"){
		combat_ranking_ViewMode = "Fixed"
		replace_complete_area("順位スクロール OFF")
	}else if(combat_ranking_ViewMode == "Fixed"){
		combat_ranking_ViewMode = "none"
		document.getElementById("RTCContainer").style.display = "none"
		document.querySelector('[class="wrapper row mt-5 w-80"]').parentNode.setAttribute("style","margin-top:250px!important;")
		replace_complete_area("順位非表示")
	}else{
		combat_ranking_ViewMode = "Scroll"
		document.getElementById("RTCContainer").style.display = "block"
		document.querySelector('[class="wrapper row mt-5 w-80"]').parentNode.removeAttribute("style")
		replace_complete_area("順位スクロール ON")
	}
	localStorage.setItem("combat_ranking_ViewMode",combat_ranking_ViewMode)
}

function add_clear_time(event){

const event_target_id = event.ref_.path.pieces_[1];
const line_number = +event.ref_.path.pieces_[4];
const line_clear_time = +event.node_.value_
	var updates = {};
			firebase.database().ref('users').once('value').then(room_user => {
				for (let room_user_key in Players_ID) {
					if(!isNaN(line_number)){
						if(room_user_key != event_target_id && eval("room_user.val()."+room_user_key+".status.ClearTime")[line_number]){
							if(eval("room_user.val()."+room_user_key+".status.ClearTime")[line_number] > line_clear_time){
								updates['/users/' + room_user_key + '/status/ClearTime/'+ (line_number)] = null;
							}else{
								updates['/users/' + event_target_id + '/status/ClearTime/'+ (line_number)] = null;
							}
						}
					}
				}
				firebase.database().ref().update(updates);
				firebase.database().ref('users').once('value').then(room_user_update => {
					for (let room_user_key in Players_ID) {
						RTCGamePlayPlayersStatusTableSelector.querySelector("#_" + room_user_key + " > .RTCclear").textContent = Object.keys(eval("room_user_update.val()."+room_user_key+".status.ClearTime")).length-1+"pt";
					}
				});
				})
}





/**
*Toshi added code ここまで  ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////





















/////////////////////////////////////////////////////////////////////////////////////////////////
/**
*Toshi added code プレイ中の処理を対戦用に変更 ここから  ---
*@note 以下の範囲のコードは対戦ON時のみ有効
*/

let last_combo_score = 0
let combat_ranking_ViewMode = "Scroll"
let status_updates = {}
let score_flag = false



/**
*Toshi added code プレイ中の処理 ここまで  ---
*/
/////////////////////////////////////////////////////////////////////////////////////////////////