従って、バイナリの最後のほうが切り捨てられる。
353058
@Override
	public final Object readObject(OInput in, Class<Object> clazz) throws IOException {
		UnsafeFieldAccessor currentProcessfeild = null; // エラー時のメッセージ出力用。
		
		try {
			
			Object data = TheUnsafe.unsafe.allocateInstance(clazz);
			
			int binarySize = in.readInt();
			
//			BAInputStream bais;
//			if( in.isUnderlayBAIn() ) {
//				BAInputStream underlay = in.getUnderlayBAIn();
//				bais = new BAInputStream(underlay.getBuf(), underlay.getPos(), binarySize);
//				in.skip(binarySize);
//			} else {
//				byte[] binary = new byte[binarySize];
//				in.readFully(binary);
//				bais = new BAInputStream(binary);
//			}

			// 項目数が少ない場合に対応するため、OIputStreamをブランチする。
			OInput ois = in.branch();
			in.skip(binarySize);
			
			// Beanクラスに項目追加があった場合、読み込み側で処理を打ち切る為に利用される
			int fieldCount = NaturalNumberIoHelper.readNaturalNumber(ois);
			int processedCount = 0;
			
			UnsafeFieldAccessor[] fieldList = UnsafeClassMetaDataRegistry.getFieldList(clazz);
			
			for(UnsafeFieldAccessor f : fieldList) {
				currentProcessfeild = f;
				
				processedCount += 1;
				if( processedCount > fieldCount) {
					// 現在のBeanのプロパティの数が、書き込まれたプロパティのサイズを超えている。これはクラスに項目追加があった場合。
					return data;
				}
				
				Class<?> c = f.getType();

				if(c == String.class) {
					String s = ois.readString();
					f.set(data, s);
				} else if(c.isPrimitive()) {

					if(c == Integer.TYPE){
						Integer i = ois.readInt();
						f.setInt(data, i);
					} else if(c == Long.TYPE) {
						Long l = ois.readLong();
						f.setLong(data, l);
					} else if(c == Short.TYPE) {
						Short s = ois.readShort();
						f.setShort(data, s);
					} else if(c == Boolean.TYPE) {
						Boolean b = ois.readBoolean();
						f.setBoolean(data, b);
					} else if(c == Double.TYPE) {
						Double d = ois.readDouble();
						f.setDouble(data, d);
					} else if(c == Float.TYPE) {
						Float flo = ois.readFloat();
						f.setFloat(data, flo);
					} else if(c == Character.TYPE) {
						Character l = ois.readChar();
						f.setChar(data, l);
					} else if(c == Byte.TYPE) {
						Byte l = ois.readByte();
						f.setByte(data, l);
					}
					
				} else {
					Object o = ois.readObject();
					f.set(data, o);
				}
			}
			
			return data;
		} catch (MarshalException e) {
			throw e;
		} catch (Exception e) {
			throw new MarshalException("バイナリ読み込みで例外発生 data=" + clazz + ", feild=" + currentProcessfeild ,e);
		}
		
	}
222005
function setFurikaeKyujitu(year, holidays) {
  if (year < 1973) {
    return;
  }
  var last = null;
  var furikae = [];
  var activeTime = new Date(1973, 4-1, 29).getTime(); // 施行前日の祝日から適用
  var flg = false;
  var keys = Object.keys(holidays);
  keys.push('1231');
  keys.forEach(md => {
    var date = new Date(year, md.slice(0, -2) * 1 - 1, md.slice(-2) * 1);
    if (flg) {
      last.setTime(last.getTime() + A_DAY);
      if (last.getTime() !== date.getTime()) {
        furikae.push((last.getMonth() + 1) * 100 + last.getDate());
        flg = false;
      }
    } else {
      flg = date.getDay() === 0 && activeTime <= date.getTime();
    }
    last = date;
  });
  furikae.forEach(x => holidays[x] = '振替休日');
}
163746
function( values, targetHTMLFilePath ){
        var deferred = Q.defer(),
            generatedCode;

        /**
         * テンプレート向けユーティリティ
         * リソースファイルへのパス記述をファイル相対形式で返却する
         * @param {String} resourcePath
         * @return {String}
         */
        function normalizePath( resourcePath ){
            return path.relative(
                path.dirname( path.resolve( process.cwd(), targetHTMLFilePath ) ),
                resourcePath
            ).split( path.sep ).join( "/" );
        }

        var resolvedDefaultValues = {};
        _.forEach( this.defaultValues, function( value, key ){
            resolvedDefaultValues[ key ] = _.template( value )( {
                __normalizePath__: normalizePath
            } );
        } );

        // テンプレート固有の（更新先HTML由来ではない）パラメータを追加
        values = _.assign( values, {
            __default__: resolvedDefaultValues,
            __normalizePath__: normalizePath
        } );

        try {
            generatedCode = this.processor( values );
        } catch( err ){
            deferred.reject( err );
            return deferred.promise;
        }

        deferred.resolve( generatedCode );
        return deferred.promise;
    }
133508
function tokenize(str) {
  var lines = str.split(LB_RE);
  var line;
  var tokens = [];

  // 空文字は無視します
  if (str.length === 0) { return tokens; }

  var isCGMD = false;
  // 全ての行をなめる
  while ((line = lines.shift()) !== undefined) {
    // CGMDのスタート / エンドでフラグを打つ
    if (CGMD_START_RE.exec(line.trim())) {
      isCGMD = true;
      tokens.push(new CGMD_Token());
      tokens[tokens.length - 1].addBody(line);
      continue;
    }
    if (CGMD_END_RE.exec(line.trim())) {
      isCGMD = false;
      tokens[tokens.length - 1].addBody(line);
      continue;
    }

    if (
      // ふつうのMDでありつつ
      isCGMD === false &&
      (
        // 最初か
        tokens.length === 0 ||
        // さっきまでCGMDを処理していたなら
        tokens[tokens.length - 1].isTypeCGMD()
      )
    ) {
      // 新しい区分にしてから
      tokens.push(new MD_Token());
    }

    // 中身を入れる
    tokens[tokens.length - 1].addBody(line);
  }

  // 全行見終わってまだこのフラグが立ってるなら閉じ忘れ
  if (isCGMD) {
    throw new Error('Missing close tag for CGMD!');
  }

  return tokens;
}
848469
function(){
		/* URLの種類からURLを取得する */
		var domain = (!pzpr.env.node ? document.domain : ''), url = "", pid = this.pid;
		if(!!domain){ domain += location.pathname;}
		else{ domain = "pzv.jp/p.html";}
		switch(this.type){
			case URL_PZPRV3:  url="http://"+domain+"?%PID%/"; break;
			case URL_KANPEN:  url="http://www.kanpen.net/%KID%.html?problem="; break;
			case URL_KANPENP: url="http://www.kanpen.net/%KID%.html?pzpr="; break;
			case URL_HEYAAPP: url="http://www.geocities.co.jp/heyawake/?problem="; break;
		}

		return url.replace("%PID%", pzpr.variety(pid).urlid)
				  .replace("%KID%", pzpr.variety(pid).kanpenid);
	}
98013
private String trim(final String str) {

        final int length = str.length();
        if(length == 0) {
            return str;
        }

        if(leftAlign) {
            if(str.charAt(0) != trimChar) {
                // 左端がトリム対象の文字出ない場合、処理終了
                return str;

            }

            // 左側から、trimCharに一致しない位置を探す
            for(int i=0; i < length; i++) {
                char c = str.charAt(i);
                if(c != trimChar) {
                    return str.substring(i);
                }
            }

            // 全ての文字がトリム対象の場合
            return "";

        } else {
            if(str.charAt(length - 1) != trimChar) {
                // 右端がトリム対象の文字出ない場合、処理終了
                return str;

            }

            // 右側から、trimCharに一致しない位置を探す
            for(int i=length - 1; i >= 0; i--) {
                char c = str.charAt(i);
                if(c != trimChar) {
                    return str.substring(0, i + 1);
                }
            }

            // 全ての文字がトリム対象の場合
            return "";

        }

    }
252318
private function path_resolve_in_html( $src ){

		// Simple HTML Parser を通したときに、
		// もとの文字セットが無視されて DEFAULT_TARGET_CHARSET (=UTF-8) に変換されてしまう問題に対して、
		// もとの文字セットを記憶 → UTF-8 に一時変換 → Simple HTML Parser → 最後にもとの文字セットに変換しなおす
		// という処理で対応した。
		$detect_encoding = mb_detect_encoding($src);


		// HTMLをパース
		$html = str_get_html(
			mb_convert_encoding( $src, DEFAULT_TARGET_CHARSET, $detect_encoding ) ,
			false, // $lowercase
			false, // $forceTagsClosed
			DEFAULT_TARGET_CHARSET, // $target_charset
			false, // $stripRN
			DEFAULT_BR_TEXT, // $defaultBRText
			DEFAULT_SPAN_TEXT // $defaultSpanText
		);

		if($html === false){
			// HTMLパースに失敗した場合、無加工のまま返す。
			$this->px->error('HTML Parse ERROR. $src size '.strlen($src).' byte(s) given; '.__FILE__.' ('.__LINE__.')');
			return $src;
		}

		$conf_dom_selectors = array(
			'*[href]'=>'href',
			'*[src]'=>'src',
			'form[action]'=>'action',
		);

		foreach( $conf_dom_selectors as $selector=>$attr_name ){
			$ret = $html->find($selector);
			foreach( $ret as $retRow ){
				$val = $retRow->getAttribute($attr_name);
				$val = $this->get_new_path($val);
				$retRow->setAttribute($attr_name, $val);
			}
		}

		$ret = $html->find('*[style]');
		foreach( $ret as $retRow ){
			$val = $retRow->getAttribute('style');
			$val = str_replace('&quot;', '"', $val);
			$val = str_replace('&lt;', '<', $val);
			$val = str_replace('&gt;', '>', $val);
			$val = $this->path_resolve_in_css($val);
			$val = str_replace('"', '&quot;', $val);
			$val = str_replace('<', '&lt;', $val);
			$val = str_replace('>', '&gt;', $val);
			$retRow->setAttribute('style', $val);
		}

		$ret = $html->find('style');
		foreach( $ret as $retRow ){
			$val = $retRow->innertext;
			$val = $this->path_resolve_in_css($val);
			$retRow->innertext = $val;
		}

		$src = $html->outertext;

		// もとの文字セットを復元
		$src = mb_convert_encoding( $src, $detect_encoding );

		return $src;
	}
1057461
function( HTMLCode ){

        var processedHTMLCode =
                HTMLCode
                    .replace( /<!-- InstanceBegin template[^>]+ -->/i, "" )
                    .replace( "<!-- InstanceEnd -->", "" ), // 重複を避けるため、あらかじめ削除。
            $ = cheerio.load( utils.activateInstanceTags( processedHTMLCode ), { decodeEntities: false } );

        // このテンプレートから生成されるHTMLコードに対し、出自を示すタグ<!-- InstanceBegin template -->を付与する。
        // また、このタグには、任意の属性を適用できるようプレースホルダ（__template_attr__）を設置する。
        // なお、このテンプレートが親テンプレートを持つ場合、すでに<!-- InstanceBegin 〜 -->記述を持つ可能性がある。
        // そのため、変数processedHTMLCodeの定義時において、あらかじめ<!-- InstanceBegin 〜 -->を削除している。
        $( "html" )
            .prepend( [
                "<!--",
                " InstanceBegin template=\"/" + this.id + "\"",
                "<%=",
                " typeof __template_attr__ !== 'undefined' ? __template_attr__: ",
                " typeof __default__.__template_attr__ !== 'undefined' ? __default__.__template_attr__: '' ",
                " %>",
                " -->"
            ].join( "" ) )
            .append( "<!-- InstanceEnd -->" );

        // InstanceEditableのうち、入れ子の親になっている要素のみを削除
        $( "InstanceEditable" ).each( function( index, elm ){
            var $this = $( elm ),
                hasNestedEditable = ~$this.html().indexOf( "<!-- TemplateBeginEditable " );

            if( hasNestedEditable ){
                $this.after( $this.contents() ).remove();
            }
        } );

        processedHTMLCode = utils.replaceWithPatterns(
            this.convertResourcePathFormat( $.html() ),
            {
                "<instanceeditable name=\"([^\"]+)\">[\\s\\S]*?</instanceeditable>": "<!-- InstanceBeginEditable name=\"$1\" --><% if( typeof $1 !== 'undefined' ){ %><%= $1 %><% } else { %><%= __default__.$1 %><% } %><!-- InstanceEndEditable -->",
                "<!-- TemplateBeginEditable name=\"([^\"]+)\" -->[\\s\\S]*?<!-- TemplateEndEditable -->": "<!-- InstanceBeginEditable name=\"$1\" --><% if( typeof $1 !== 'undefined' ){ %><%= $1 %><% } else { %><%= __default__.$1 %><% } %><!-- InstanceEndEditable -->"
            }
        );

        utils.log( this.id, "templateSrc", processedHTMLCode );

        return processedHTMLCode;
    }
553452
function(){
		/* "ものを動かしたように描画する"でなければinputLineと同じ */
		if(this.puzzle.execConfig('dispmove')){
			this.inputMoveLine();
			return;
		}
		
		var pos, border;
		if(!this.board.borderAsLine){
			pos = this.getpos(0);
			if(this.prevPos.equals(pos)){ return;}
			border = this.prevPos.getnb(pos);
		}
		else{
			pos = this.getpos(0.35);
			if(this.prevPos.equals(pos)){ return;}
			border = this.prevPos.getborderobj(pos);
		}
		
		if(!border.isnull){
			if(this.inputData===null){ this.inputData=(border.isLine()?0:1);}
			if     (this.inputData===1){ border.setLine();}
			else if(this.inputData===0){ border.removeLine();}
			border.draw();
		}
		this.prevPos = pos;
	}
262544
function render(req, res, data){
	var shohousen = new Shohousen();
	if( data["hakkou-kikan"] ){
		var hakkouKikan = data["hakkou-kikan"];
		shohousen.setHakkouKikan(hakkouKikan[0], hakkouKikan[1], hakkouKikan[2], hakkouKikan[3])
	}
	if( data["doctor"] ){
		shohousen.setDoctor(data["doctor"]);
	}
	if( data["koufu-date"] ){
		var koufuDate = data["koufu-date"];
		shohousen.setKoufuDate("" + koufuDate[0], "" + koufuDate[1], "" + koufuDate[2]);
	}
	if( data["hokensha-bangou"] ){
		shohousen.setHokenshaBangou("" + data["hokensha-bangou"]);
	}
	if( data["kubun-hihokensha"] ){
		shohousen.setKubunHihokensha();
	}
	if( data["kubun-hifuyousha"] ){
		shohousen.setKubunHifuyousha();
	}
	if( data["hihokensha"] ){
		shohousen.setHihokensha(data["hihokensha"]);
	}
	if( data["kouhi-1-futansha"] ){
		shohousen.setKouhi1Futansha("" + data["kouhi-1-futansha"]);
	}
	if( data["kouhi-1-jukyuusha"] ){
		shohousen.setKouhi1Jukyuusha("" + data["kouhi-1-jukyuusha"]);
	}
	if( data["kouhi-2-futansha"] ){
		shohousen.setKouhi2Futansha("" + data["kouhi-2-futansha"]);
	}
	if( data["kouhi-2-jukyuusha"] ){
		shohousen.setKouhi2Jukyuusha("" + data["kouhi-2-jukyuusha"]);
	}
	if( data["shimei"] ){
		shohousen.setShimei(data["shimei"]);
	}
	if( data["birthday"] ){
		var birthday = data["birthday"];
		shohousen.setBirthday("" + birthday[0], "" + birthday[1], "" + birthday[2]);
	}
	if( data["sex"] ){
		var sex = data["sex"].toUpperCase();
		if( sex === "M" ){
			shohousen.setSexMale();
		} else if( sex === "F" ){
			shohousen.setSexFemale();
		}
	}
	if( "futan-wari" in data ){
		shohousen.setFutanwari("" + data["futan-wari"]);
	}
	if( data["valid-upto"] ){
		var validUpto = data["valid-upto"];
		shohousen.setValidUptoDate("" + validUpto[0], "" + validUpto[1], "" + validUpto[2])
	}
	if( data["drugs"] ){
		shohousen.setDrugs(data["drugs"]);
	}
	var ops = shohousen.getOps();
	var drawerPage = JSON.stringify([ops]);
	var printManageUrl = "/printer/";
	res.end(indexTmpl.render({
		drawerPage: drawerPage, 
		printManageUrl: printManageUrl,
		// printServerPort: printServerPort,
		base: req.baseUrl
	})); 
}
261766
function setupDeveloperMenu(param) {
	var gdr = engineFiles.gameDriver;
	var defaultTotalTimeLimit = 85; // 85秒をデフォルトの制限時間としてあつかう。

	// loocalStorageにメニューの位置、サイズを保存している
	var config = {};
	if ("localStorage" in window) {
		var saved = JSON.parse(localStorage.getItem("akashic-sandbox-config"));
		if (saved) {
			config = saved;
		}
	}
	if (config.size == null) {
		config.size = {
			right: {width: "400px", height: "100%"},
			bottom: {width: "100%", height: "300px"}
		};
	}
	if (config.isPositionRight == null) {
		config.isPositionRight = true;
	}
	if (config.showGrid == null) {
		config.showGrid = false;
	}
	if (config.omitInterpolatedTick == null) {
		config.omitInterpolatedTick = false;
	}
	if (isNaN(parseInt(config.totalTimeLimit, 10))) {
		config.totalTimeLimit = defaultTotalTimeLimit;
	}
	if (config.warningEs6 == null) {
		config.warningEs6 = true;
	}
	if (config.sendsSessionParameter == null) {
		config.sendsSessionParameter = false;
	}
	if (config.mode == null) {
		config.mode = "single";
	}
	// ES6以降でサポートされるオブジェクトが使われている場合警告を出す。
	if (config.warningEs6) {
		warningEs6OnConsole();
	}

	var sandboxConfig = window.sandboxDeveloperProps.sandboxConfig;

	config.autoSendEvents = config.autoSendEvents || !!sandboxConfig.autoSendEventName;
	config.eventsToSend = !!sandboxConfig.autoSendEventName ? JSON.stringify(sandboxConfig.events[sandboxConfig.autoSendEventName]) : config.eventsToSend;

	var events = {};
	if (sandboxConfig.events) {
		Object.keys(sandboxConfig.events).forEach(function (name) {
			events[name] = JSON.stringify(sandboxConfig.events[name]);
		});
	}

	var props = window.sandboxDeveloperProps;
	var amflow = props.amflow;

	// 各viewの情報
	var views = {
		'general-view': {title: "General", show: true},
		'events-view': {title: "Events", show: false},
		'camera-view': {title: "Cameras", show: false},
		'e-view': {title: "E", show: false},
		'niconico-view': {title: "Niconico", show: false},
		'playlog-view': {title: "Replay", show: false},
		'snapshot-view': {title: "Snapshot", show: false}
	};

	// vue.jsにバインドするデータ
	var data = {
		showMenu: sandboxConfig.showMenu ? sandboxConfig.showMenu : false,
		players: [],
		selfId: props.sandboxPlayer.id,
		selfName: props.sandboxPlayer.name,
		path: props.path,
		gameId: props.gameId,
		events: events,
		cameras: [],
		focusingCameraIndex: undefined,
		inputPlayerName: null,
		inputPlayerId: null,
		config: config,
		entities: [], // {className: string, id: number, children: Array}
		entityRect: {
			enable: false,
			show: false,
			withChildren: false,
			rectStyle: {top: "0px", left: "0px", width: "0px", height: "0px"}
		},
		targetEntity: null,
		snapshots: null,
		snapshotPreview: null,
		profiler: {
			show: (window.location.search.indexOf("profiler=1") >= 0), // todo: リファクタリング時にクエリオプションのパースを統一する
			expand: false
		},
		isPaused: false,
		isReplay: param.isReplay,
		currentTime: 0,
		replayDuration: param.replayDuration,
		replayDone: false,
		playlog: {
			list: [] // {name: string, url: string}
		},
		views: views,
		isIchibaContent: function() {
			var environment = props.game._configuration.environment;
			if (!environment || !environment.niconico || !environment.niconico.supportedModes) {
				return false;
			}
			return environment.niconico.supportedModes.length > 0;
		}(),
		rankingGameState: {
			score: "N/A",
			playThreshold: "N/A",
			clearThreshold: "N/A"
		},
		remainingTime: "N/A",
		isStopGame: false,
		modeList: [
			{text: "ひとりで遊ぶ(single)", value: "single"},
			{text: "ランキング(ranking)", value: "ranking"}
		]
	};

	if (config.autoJoin && !param.isReplay) {
		// NOTE: この時点でgame._loadedにgame._start()がハンドルされている必要がある
		// スナップショットから復元時はloadedが発火しないのでJOINは行われない
		props.game._loaded.addOnce(function() {
			var p = props.sandboxPlayer;
			data.players.push({player: {id: p.id, name: p.name}, self: true});
			amflow.sendEvent([0 /* Join */,  3, p.id, p.name, null ]);
		});
	}

	if (config.autoSendEvents && !param.isReplay) {
		props.game._loaded.addOnce(function () {
			sendEvents();
		});
	}

	if (config.sendsSessionParameter && data.isIchibaContent && !param.isReplay) {
		var totalTimeLimit = parseInt(config.totalTimeLimit, 10);

		if (isNaN(totalTimeLimit)) {
			totalTimeLimit = defaultTotalTimeLimit;
		}
		// ランキング用イベントを送信する。
		var sessionParameters = {
			"mode": config.mode
		};
		if (config.mode === "ranking") {
			sessionParameters["totalTimeLimit"] = totalTimeLimit;
			// 前の仕様ではtotalTimeLimitより25秒程度短いgameTimeLimitが送られていたので、互換性のためにtotalTimeLimitと一緒に送っておく。
			sessionParameters["gameTimeLimit"] = totalTimeLimit - 25;
		}
		props.game._loaded.addOnce(function () {
			amflow.sendEvent([0x20, 0, "dummy", {
				"type": "start",
				"parameters": sessionParameters
			}]);
		});
		if (config.mode === "ranking") {
			var gameStartTime = Date.now();
			var intervalId = setInterval(function () {
				var currentRemainingTime = totalTimeLimit - (Date.now() - gameStartTime) / 1000;
				data.remainingTime = currentRemainingTime > 0 ? Math.ceil(currentRemainingTime) : 0;
			}, 1000 / props.game.fps);
			setTimeout(function () {
				data.remainingTime = 0;
				clearInterval(intervalId);
				if (config.stopsGameOnTimeout) {
					if (props.game && props.game.audio) {
						// 音を明示的に止める。
						Object.keys(props.game.audio).forEach(function (key) {
							props.game.audio[key].stopAll();
						});
					}
					props.driver.stopGame();
					// akashic-sandboxがゲームを止めたことをユーザーに明示するために、強制的にメニューを開いてメッセージを表示する。
					data.isStopGame = true;
					data.showMenu = true;
					var elements = document.getElementsByClassName("dev-menu-view");
					for (var i = 0; i < elements.length; i++) {
						var element = elements[i];
						data.views[element.id].show = element.id === "niconico-view";
						element.style.display = data.views[element.id].show ? "block" : "none";
					}
				}
			}, totalTimeLimit * 1000);
		}
	}

	// 歯車ボタン
	var devBtn = document.querySelector("#dev-btn");
	devBtn.addEventListener("click", function() {
		data.showMenu = !data.showMenu;
	});


	// 設定をlocalStorageに保存する関数
	function saveConfig() {
		if ("localStorage" in window) {
			localStorage.setItem("akashic-sandbox-config", JSON.stringify(config));
		}
	}

	// プレイヤーのStorageValueStoreを生成する
	function createStorageValueStore(playerId, keys) {
		var convertedKeys = [];
		keys.forEach(function(key) {
			var ck = {};
			for (var k in key) {
				ck[k] = key[k];
			}
			ck.userId = playerId;
			convertedKeys.push(ck);
		});
		var values = props.gameStorage.load(convertedKeys);
		return new g.StorageValueStore(convertedKeys, values);
	}

	// プレイヤーをジョインさせる関数
	function joinGame() {
		var playerId = data.inputPlayerId;
		var playerName = data.inputPlayerName;
		if (!playerId) {
			alert("Player IDを入力してください");
			return;
		}
		for (var i = 0; i < data.players.length; ++i) {
			if (data.players[i].player.id === playerId) {
				alert("Player ID: \"" + playerId + "\"は既に参加しています。");
				return;
			}
		}
		if (playerId === data.selfId && inputPlayerName !== data.selfName) {
			alert("Player ID: \"" + playerId + "\"のPlayer Nameは\"" + data.selfName + "\"になります。");
			playerName = data.selfName;
		}
		data.players.push({
			player: { id: playerId, name: playerName },
			self: (playerId === props.game.selfId)
		});
		data.inputPlayerId = data.inputPlayerName = null;
		amflow.sendEvent([0 /* Join */,  3, playerId, playerName, null ]);
	}

	// プロファイラーの各種設定
	// この値は次回の redrawProfilerCanvas() 呼び出し時に適用される
	var profilerSettings = {
		expand: data.profiler.expand,
		width: 170,
		margin: 5,
		padding: 5,
		align: "vertical", // 縦並び
		// align: "horizontal", // 横並び
		bgColor: "white",
		fontColor: "black",
		fontSize: 17,
		fontMaxColor: "deeppink",
		fontMinColor: "dodgerblue",
		fontMinMaxColor: "gray",
		graphColor: "lavender",
		graphWidth: 3,
		graphWidthMargin: 1,
		graphPadding: 5
	};

	// note: プロファイラー表示処理の範囲をわかりやすくするため {} で囲んでいる
	{
		var s = {};
		var updateProfilerConfig = function() {
			s = Object.create(profilerSettings);
		};

		var profilerData = {
			fps: {
				name: "fps",
				data: [],
				max: 0,
				min: Number.MAX_VALUE
			},
			skipped: {
				name: "skipped",
				data: [],
				max: 0,
				min: Number.MAX_VALUE
			},
			interval: {
				name: "interval",
				data: [],
				max: 0,
				min: Number.MAX_VALUE
			},
			frame: {
				name: "frame",
				data: [],
				max: 0,
				min: Number.MAX_VALUE
			},
			rendering: {
				name: "rendering",
				data: [],
				max: 0,
				min: Number.MAX_VALUE
			}
		};

		var profilerCanvas = document.getElementById("profilerCanvas");
		profilerCanvas.addEventListener("click", function() {
			toggleProfilerCanvasSize();
		});
		profilerCanvas.style.display = data.profiler.show ? "block" : "none";

		var profilerCanvasContext = profilerCanvas.getContext("2d");

		// todo: SimpleProfilerのコンストラクタパラメータにgetValueTriggerを与えるように修正
		props.driver._gameLoop._clock._profiler._calculateProfilerValueTrigger.add(function(value) {
			var deltaX;
			var deltaY;
			if (s.align === "vertical") {
				deltaX = 0;
				deltaY = s.height + s.margin;
			} else {
				deltaX = s.width + s.margin;
				deltaY = 0;
			}
			updateProfilerData(profilerData.fps,       value.framePerSecond,    deltaX * 0, deltaY * 0, 2);
			updateProfilerData(profilerData.skipped,   value.skippedFrameCount, deltaX * 1, deltaY * 1, 1);
			updateProfilerData(profilerData.interval,  value.rawFrameInterval,  deltaX * 2, deltaY * 2, 1);
			updateProfilerData(profilerData.frame,     value.frameTime,         deltaX * 3, deltaY * 3, 1);
			updateProfilerData(profilerData.rendering, value.renderingTime,     deltaX * 4, deltaY * 4, 1);
		});

		var updateProfilerData = function(profilerData, profileValue, x, y, fixed) {
			profilerData.data.unshift(profileValue.ave);
			drawGraph(profilerData, profileValue, x, y, fixed);
		};
		var drawText = function(text, x, y, color, maxWidth) {
			profilerCanvasContext.fillStyle = color;
			profilerCanvasContext.fillText(text, x, y, maxWidth);
		};
		var drawGraph = function(profilerData, profilerValue, x, y, fixed) {
			profilerCanvasContext.fillStyle = s.bgColor;
			profilerCanvasContext.fillRect(x, y, s.width, s.height);
			profilerCanvasContext.fillStyle = s.graphColor;
			var min = Number.MAX_VALUE;
			var max = 0;
			for (var i = 0; i < profilerData.data.length; ++i) {
				var offsetX = s.width - i * (s.graphWidth + s.graphWidthMargin) - s.graphWidth - s.graphPadding;
				var data = profilerData.data[i];
				if (data < min) {
					min = data;
				}
				if (data > max) {
					max = data;
				}
				if (offsetX < s.graphWidth + s.graphPadding / 2) {
					profilerData.data.pop();
					break;
				}
			}
			if (min < profilerData.min) profilerData.min = min;
			if (profilerData.max < max) profilerData.max = max;

			var areaHeight = s.height - s.graphPadding * 2;
			var rate = max > areaHeight ? areaHeight / max : 1;
			for (var i = 0; i < profilerData.data.length; ++i) {
				var offsetX = s.width - i * (s.graphWidth + s.graphWidthMargin) - s.graphWidth - s.graphPadding;
				var height = profilerData.data[i] * rate;
				profilerCanvasContext.fillRect(
					x + offsetX,
					y + s.height - height - s.graphPadding,
					s.graphWidth,
					height
				);
			}
			var valueOffsetX = s.width * 0.6;
			var maxWidth = valueOffsetX - s.padding;
			var maxValueWidth = (s.width - valueOffsetX) - s.padding;
			drawText(profilerData.name + ":", x + s.padding, y + s.padding + s.fontSize, s.fontColor, maxWidth);
			drawText(profilerValue.ave.toFixed(fixed), x + valueOffsetX, y + s.padding + s.fontSize, s.fontColor, maxValueWidth);
			drawText(max.toFixed(fixed), x + valueOffsetX, y + s.padding + s.fontSize * 2, s.fontMaxColor, maxValueWidth);
			drawText(min.toFixed(fixed), x + valueOffsetX, y + s.padding + s.fontSize * 3, s.fontMinColor, maxValueWidth);
			var min_max = " " + profilerData.min.toFixed(0) + "-" + profilerData.max.toFixed(0);
			drawText(min_max, x + s.padding, y + s.padding + s.fontSize * 2.5, s.fontMinMaxColor, maxWidth);
		};

		// profilerSettings の設定にもとづいたプロファイラーを描画する
		function redrawProfilerCanvas() {
			updateProfilerConfig();
			var width;
			var height;
			s.height = s.fontSize * 3 + s.padding * 2;
			if (s.align === "vertical") {
				width = s.width;
				height = (s.height + s.margin) * Object.keys(profilerData).length - s.margin;
			} else {
				width = (s.width + s.margin) * Object.keys(profilerData).length - s.margin;
				height = s.height;
			}
			profilerCanvas.width = width;
			profilerCanvas.height = height;
			if (s.expand) {
				profilerCanvas.style.width = width * 1.5 + "px";
				profilerCanvas.style.height = height * 1.5 + "px";
			} else {
				profilerCanvas.style.width = width + "px";
				profilerCanvas.style.height = height + "px";
			}
			profilerCanvasContext.font = s.fontSize + "px sans-serif";
		}

		var profilerCheckBox = document.getElementById("show-profiler");
		// プロファイラー情報の表示をトグル表示する関数
		function toggleProfiler() {
			if (!data.profiler.show) {
				profilerCanvas.style.display = "block";
				profilerCheckBox.checked = true;
			} else {
				profilerCanvas.style.display = "none";
				profilerCheckBox.checked = false;
			}
			data.profiler.show = !data.profiler.show;
		}

		// プロファイラー情報の拡縮をトグルする関数
		function toggleProfilerCanvasSize() {
			profilerSettings.expand = !s.expand;
			redrawProfilerCanvas();
		}

		profilerCheckBox.checked = data.profiler.show;
		redrawProfilerCanvas();
	}

	// g.Game.tickを上書きする。
	var originalTickFunc = props.game.tick;
	props.game.tick = function (advanceAge, omittedTickCount) {
		if (data.isIchibaContent && props.game.vars && props.game.vars.gameState) {
			// ユーザーに値の型も意識させるため、JSON.stringifyを使用する。
			data.rankingGameState.score = getJsonStringifiedValue(props.game.vars.gameState.score);
			data.rankingGameState.playThreshold = getJsonStringifiedValue(props.game.vars.gameState.playThreshold);
			data.rankingGameState.clearThreshold = getJsonStringifiedValue(props.game.vars.gameState.clearThreshold);
		}
		return originalTickFunc.apply(props.game, arguments);
	};

	// g.Camera2Dを上書き
	/**
	 * Akashicゲームコンテンツ内で生成されたg.Camera2Dの一覧を取得する手段が無いため、
	 * g.Camera2Dのコンストラクタを無理やり上書きしている。
	 */
	var camera2D = g.Camera2D;
	var cameras = [];
	function registerCamera(cam) {
		data.cameras.push({id: cam.id, name: cam.name, local: cam.local});
		cameras.push(cam);
	}
	g.Camera2D = function () {
		camera2D.apply(this, arguments);
		registerCamera(this);
	};
	// staticメンバを再現
	Object.keys(camera2D).forEach(function (key) {
		g.Camera2D[key] = camera2D[key];
	});
	// staticメンバを再現してもデシリアライズは正常に動作しない
	// (オリジナルのコンストラクタを使ってしまう)のでさらに無理やり上書きする。
	g.Camera2D.deserialize = function (ser, game) {
		var ret = camera2D.deserialize(ser, game);
		registerCamera(ret);
		return ret;
	};
	g.Camera2D.prototype = camera2D.prototype;

	// g.Game#focusingCameraをsetter/getter化することで、コンテンツ側からのfocusingCameraの変更を感知
	Object.defineProperty(props.game, "focusingCamera", {
		set: function(c) {
			data.focusingCameraIndex = cameras.indexOf(c);
		},
		get: function() {
			return cameras[data.focusingCameraIndex];
		}
	});

	// viewを表示する関数
	// v-showで上手くやるべきかもしれない
	function renderView(vm) {
		var viewElms = vm.$el.querySelectorAll(".dev-menu-view");
		for (var i = 0; i < viewElms.length; i++) {
			var el = viewElms[i];
			el.style.display = data.views[el.id].show ? "block" : "none";
		}
	}

	// g.Eから {className: string, id: number, children: Array} を作る
	function createEntityObject(e) {
		var obj = {id: e.id, className: e.constructor.name, children: []};
		if (e.children && e.children.length > 0) {
			e.children.forEach(function(c) {
				obj.children.push(createEntityObject(c));
			});
		}
		return obj;
	}

	// 親エンティティを辿り、掛けあわせたマトリックスを返す
	function parentsMatrix(e, focusingCamera) {
		if (e.parent && e.parent.getMatrix) {
			var m1 = e.parent.getMatrix();
			var m2 = parentsMatrix(e.parent, focusingCamera);
			if (m2) {
				return m1.multiplyNew(m2);
			}
			return m1;
		} else {
			if (focusingCamera) {
				return focusingCamera.getMatrix();
			}
			return undefined;
		}
	}

	// g.E#_calculateBoundingRectを改造したもので、hidden状態のエンティティの包含矩形の計算、子孫エンティティを計算対象に含めるかどうかの指定ができる
	// NOTE: g.E#_calculateBoundingRectが実装クラスによりオーバーライドされる可能性があるためakashic-engineにデバッグ用の包含矩形計算機能を入れる方が良い
	function calculateEntityBoundingRect(entity, parentsMatrix, withChildren) {
		var matrix = entity.getMatrix();
		if (parentsMatrix) {
			matrix = parentsMatrix.multiplyNew(matrix);
		}

		var thisBoundingRect = {left: 0, right: entity.width, top: 0, bottom: entity.height};

		var targetCoordinates = [
			{x: thisBoundingRect.left, y: thisBoundingRect.top},
			{x: thisBoundingRect.left, y: thisBoundingRect.bottom},
			{x: thisBoundingRect.right, y: thisBoundingRect.top},
			{x: thisBoundingRect.right, y: thisBoundingRect.bottom}
		];
		var convertedPoint = matrix.multiplyPoint(targetCoordinates[0]);
		var result = {left: convertedPoint.x, right: convertedPoint.x, top: convertedPoint.y, bottom: convertedPoint.y};
		for (var i = 1; i < targetCoordinates.length; ++i) {
			convertedPoint = matrix.multiplyPoint(targetCoordinates[i]);
			if (result.left > convertedPoint.x)
				result.left = convertedPoint.x;
			if (result.right < convertedPoint.x)
				result.right = convertedPoint.x;
			if (result.top > convertedPoint.y)
				result.top = convertedPoint.y;
			if (result.bottom < convertedPoint.y)
				result.bottom = convertedPoint.y;
		};
		if (withChildren && entity.children !== undefined) {
			for (var i = 0; i < entity.children.length; ++i) {
				var nowResult = calculateEntityBoundingRect(entity.children[i], matrix, true);
				if (nowResult) {
					if (result.left > nowResult.left)
						result.left = nowResult.left;
					if (result.right < nowResult.right)
						result.right = nowResult.right;
					if (result.top > nowResult.top)
						result.top = nowResult.top;
					if (result.bottom < nowResult.bottom)
						result.bottom = nowResult.bottom;
				}
			};
		}
		return result;
	}

	function updateEntityList() {
		var entities = props.game.scene().children;
		data.entities = [];
		entities.forEach(function(e) {
			data.entities.push(createEntityObject(e));
		});
	}

	function insertEventString (str) {
		data.config.eventsToSend = str;
	}

	function sendEventsWithValue(str) {
		var es = [];
		try {
			es = JSON.parse(str);
		} catch (e) {
			alert(e);
			console.log(e);
		}
		es.forEach(function (e) { amflow.sendEvent(e); });
	}

	function sendEvents() {
		if (!config.eventsToSend) {
			console.log("No events to send.");
			return;
		}
		sendEventsWithValue(config.eventsToSend);
	}

	function focusBoundingRect(id) {
		if (!data.entityRect.enable) {
			return;
		}
		var e = null;
		if (id < 0) {
			e = props.game._localDb[id];
		} else {
			e = props.game.db[id];
		}
		if (!e) {
			return;
		}
		// NOTE: fitToWindowすると破綻する
		var container = document.getElementById("container");
		var offsetTop = container ? container.offsetTop : 0;
		var rect = calculateEntityBoundingRect(e, parentsMatrix(e, props.game.focusingCamera), data.entityRect.withChildren);
		var s = data.entityRect.rectStyle;
		if (rect) {
			// 2 はフォーカス用divのボーダーサイズ
			s.top = offsetTop + (rect.top - 2) + "px";
			s.left = (rect.left - 2) + "px";
			s.width = (rect.right - rect.left) + "px";
			s.height = (rect.bottom - rect.top) + "px";
		}
		data.entityRect.show = true;
	}

	function unfocusBoundingRect() {
		data.entityRect.show = false;
		var s = data.entityRect.rectStyle;
		s.top = s.left = s.width = s.height = "0px";
	}

	function updateTargetEntity(id) {
		var e = null;
		if (id < 0) {
			e = props.game._localDb[id];
		} else {
			e = props.game.db[id];
		}
		if (e) {
			data.targetEntity = {
				className: e.constructor.name,
				id: id,
				local: e.local,
				touchable: e.touchable,
				visible: e.visible(),
				x: e.x,
				y: e.y,
				width: e.width,
				height: e.height,
				angle: e.angle,
				opacity: e.opacity,
				destroyed: e.destroyed()
			};
		} else {
			data.targetEntity = null;
		}
	}

	var SNAPSHOT_PREFIX = "akss:" + props.gameId + "/";
	var snapshots = {};
	var snapshotsList = [];

	// ゲームコンテンツからのスナップショット保存要求をハンドル
	var saveSnapshotOriginal = props.game.saveSnapshot;
	props.game.saveSnapshot = function(gameSnapshot) {
		// browser-engineのGame#saveSnapshot()を実行
		saveSnapshotOriginal.apply(props.game, arguments);

		if (!gameSnapshot) return;

		var time = new Date();
		var y = time.getFullYear();
		var m = time.getMonth();
		m = m < 10 ? "0" + m : m;
		var d = time.getDate();
		d = d < 10 ? "0" + d : d;
		var h = time.getHours();
		h = h < 10 ? "0" + h : h;
		var min = time.getMinutes();
		min = min < 10 ? "0" + min : min;
		var s = time.getSeconds();
		s = s < 10 ? "0" + s : s;

		var name = y + "-" + m + "-" + d + "-" + h + "-" + min + "-" + s;
		var snapshot = {
			age: props.game.age,
			randGenSer: props.game.random[0].serialize(),
			gameSnapshot: gameSnapshot,
			players: data.players
		};
		addSnapshotsList(name, snapshot);

		// LocalStorageに保存
		localStorage.setItem(SNAPSHOT_PREFIX + name, JSON.stringify(snapshot));
	};

	// LocalStorageに保存されているスナップショットの一覧
	for (i in localStorage) {
		if (i.indexOf(SNAPSHOT_PREFIX) !== -1) {
			addSnapshotsList(i.split("/")[1], JSON.parse(localStorage.getItem(i)));
		}
	}
	data.snapshots = snapshotsList;

	// スナップショットリストの追加 (Vue.js)
	function addSnapshotsList(name, data) {
		snapshots[name] = data;
		snapshotsList.push({
			name: name,
			data: JSON.stringify(data, null, "  ")
		});
	}

	// スナップショットの削除 (Vue.js + LocalStorage)
	function removeSnapshot(name) {
		localStorage.removeItem(SNAPSHOT_PREFIX + name);
		snapshotsList = snapshotsList.filter(function(e) {
			return e.name !== name;
		});
		delete snapshots[name];
		data.snapshots = snapshotsList;
	}

	// Grid表示
	var gridCheckBox = document.getElementById("show-grid");
	var gridCanvas = document.getElementById("gridCanvas");
	setupGrid();
	resizeGrid();
	drawGrid();
	function setupGrid() {
		if (config.showGrid === true) {
			gridCheckBox.checked = true;
			gridCanvas.style.display = "block";
		}
		gridCanvas.width = props.game.width;
		gridCanvas.height = props.game.height;
		gridCanvas.style.width = props.game.width + "px";
		gridCanvas.style.height = props.game.height + "px";
	}
	function resizeGrid() {
		var container = document.getElementById("container");
		var node = container.lastChild.firstChild;
		gridCanvas.style.transformOrigin = node.style.transformOrigin;
		gridCanvas.style.transform = node.style.transform;
	}
	function drawGrid() {
		var context = gridCanvas.getContext("2d");
		context.save();
		context.strokeStyle = "#CCC";
		context.setLineDash([3, 3]);
		drawGridLine(20, 20);
		context.strokeStyle = "#AAA";
		context.setLineDash([]);
		drawGridLine(100, 100);
		context.restore();

		function drawGridLine(gridWidth, gridHeight) {
			var x, y;
			context.beginPath();
			for (x = 0.5; x <= props.game.width; x += gridWidth) {
				context.moveTo(x, 0);
				context.lineTo(x, props.game.height);
			}
			for (y = 0.5; y <= props.game.height; y += gridHeight) {
				context.moveTo(0, y);
				context.lineTo(props.game.width, y);
			}
			context.stroke();
		}
	}
	function toggleGrid() {
		if (gridCheckBox.checked) {
			gridCanvas.style.display = "block";
			config.showGrid = true;
		} else {
			gridCanvas.style.display = "none";
			config.showGrid = false;
		}
		saveConfig();
	}

	var omitInterpolatedTickCheckBox = document.getElementById("omit-interpolated-tick");
	setupOmitInterpolatedTick();
	function setupOmitInterpolatedTick() {
		if (config.omitInterpolatedTick) {
			omitInterpolatedTickCheckBox.checked = true;
			changeDriverState({ loopConfiguration: { omitInterpolatedTickOnReplay: true } });
		}
	}
	function toggleOmitInterpolatedTick() {
		if (omitInterpolatedTickCheckBox.checked) {
			changeDriverState({ loopConfiguration: { omitInterpolatedTickOnReplay: true } });
			config.omitInterpolatedTick = true;
		} else {
			changeDriverState({ loopConfiguration: { omitInterpolatedTickOnReplay: false } });
			config.omitInterpolatedTick = false;
		}
		saveConfig();
	}

	// time 更新
	function updateCurrentTime() {
		data.currentTime = param.timeKeeper.now();
	}
	props.game._sceneChanged.add(function (scene) {
		if (!scene.update.contains(updateCurrentTime)) {
			scene.update.add(updateCurrentTime);
		}
	});

	var PLAYLOG_PREFIX = "akpl:" + props.gameId + "/";
	var playlogList = [];
	if (param.isReplay) {
		// プレイログ再生時はディベロッパーメニューを強制表示
		// note: views["general-view"].showがtrueかつ他のviewsのメンバのshowがfalseである、という前提条件で無理やり対応
		views["general-view"].show = false;
		views["playlog-view"].show = true;
		data.showMenu = true;
	}
	function savePlaylog() {
		var name = +new Date();
		var dump = amflow.dump();
		var jsonData = JSON.stringify({
			tickList: dump.tickList,
			startPoints: dump.startPoints,
			fps: props.game.fps
		});
		if (localStorage.getItem(PLAYLOG_PREFIX + name)) {
			if (!window.confirm("同名のリプレイ情報がすでに存在します。上書きしてもよろしいでしょうか？")) {
				return;
			}
			_removePlaylog(name);
		}
		localStorage.setItem(PLAYLOG_PREFIX + name, jsonData);
		var url = dumpPlaylog(name);
		data.playlog.list.push({name: name, url: url});
	}
	function reloadPlaylog(name) {
		var currentUrl = location.protocol + "//" + location.host + location.pathname;
		if (name) {
			window.location.href = currentUrl + "?playlog=" + name;
		} else {
			window.location.href = currentUrl;
		}
	}
	function changeDriverState(arg, callback) {
		props.driver.changeState(arg, function (err) {
			if (err) {
				console.log(err);
			}
			if (callback) {
				callback(err);
			}
		});
	}
	function rewindReplay() {
		param.timeKeeper.setTime(0);
		updateCurrentTime();
	}
	function playPauseReplay() {
		if (data.isPaused) {
			param.timeKeeper.start();
			data.isPaused = false;
		} else {
			param.timeKeeper.pause();
			data.isPaused = true;
		}
	}
	function onClickTimeProgress(ev) {
		var progress = document.getElementById("dev-menu-time-progress");
		var targetTime = Math.floor(ev.offsetX * progress.max / progress.offsetWidth);
		param.timeKeeper.setTime(targetTime);
	}
	function accelerateReplay() {
		param.timeKeeper.setRate(param.timeKeeper.getRate() * 2);
	}
	function decelerateReplay() {
		param.timeKeeper.setRate(param.timeKeeper.getRate() / 2);
	}
	function playFromHere() {
		if (props.amflow.dropAfter) {
			props.amflow.dropAfter(props.game.age);
		}
		props.driver.stopGame();
		props.driver.changeState({
			driverConfiguration: {
				executionMode: gdr.ExecutionMode.Active,
				playToken: gdr.MemoryAmflowClient.TOKEN_ACTIVE
			},
			loopConfiguration: {
				playbackRate: 1,  // 実行速度もリセットしておく
				loopMode: gdr.LoopMode.Realtime,
				delayIgnoreThreshold: 6,  // Ugh! GameLoopがデフォルト値にリセットする方法を提供するべき
				jumpTryThreshold: 90000
			}
		}, function (err) {
			if (err) {
				console.log(err);
				return;
			}
			data.isReplay = false;
			props.driver.setNextAge(props.game.age);
			props.driver.startGame();
		});
	}
	function removePlaylog(name) {
		if (!window.confirm("リプレイ情報を削除しますか？"))
			return;
		_removePlaylog(name);
	}
	function _removePlaylog(name) {
		localStorage.removeItem(PLAYLOG_PREFIX + name);
		playlogList = playlogList.filter(function(e) {
			if (e.name === name)
				window.URL.revokeObjectURL(e.url);
			return e.name !== name;
		});
		data.playlog.list = playlogList;
	}
	function dumpPlaylog(name) {
		var playlog = localStorage.getItem(PLAYLOG_PREFIX + name);
		if (!playlog) return;
		var blob = new Blob([ playlog ], { type : "application/x-download" });
		return URL.createObjectURL(blob);
	}
	var loader = document.getElementById("load-playlog-handler");
	loader.addEventListener("change", function (e) {
		var file = e.target.files[0];
		var reader = new FileReader();
		reader.readAsText(file);
		reader.onload = function (ev) {
			if (localStorage.getItem(PLAYLOG_PREFIX + file.name)) {
				if (!window.confirm("同名のリプレイ情報がすでに存在します。上書きしてもよろしいでしょうか？")) {
					return;
				}
				_removePlaylog(file.name);
			}
			localStorage.setItem(PLAYLOG_PREFIX + file.name, ev.target.result);
			var url = dumpPlaylog(file.name);
			data.playlog.list.push({name: file.name, url: url});
		};
	}, false);

	// LocalStorageに保存されているプレイログの一覧
	for (i in localStorage) {
		if (i.indexOf(PLAYLOG_PREFIX) !== -1) {
			var name = i.split("/")[1];
			var url = dumpPlaylog(name);
			playlogList.push({
				name: name,
				url: url
			});
		}
	}
	data.playlog.list = playlogList;

	function getJsonStringifiedValue(value) {
		try {
			var stringifiedValue = JSON.stringify(value);
			return stringifiedValue === undefined ? "undefined" : stringifiedValue;
		} catch (e) {
			return "N/A (circular reference)";
		}
	}

	Vue.component("entity-list-item", {
		template: "#entity-list-item-template",
		props: {
			model: Object,
			index: Number
		},
		data: function () {
			return {
				open: false
			};
		},
		computed: {
			hasChildren: function () {
				if (this.model.children && this.model.children.length > 0) {
					return true;
				}
				return false;
			}
		},
		methods: {
			toggle: function () {
				this.open = !this.open;
			},
			selectEntity: function() {
				updateTargetEntity(this.model.id);
			},
			focusEntity: function() {
				focusBoundingRect(this.model.id);
			},
			unfocusEntity: function() {
				unfocusBoundingRect();
			}
		}
	});

	var vm = new Vue({
		el: "#dev-menu",
		data: data,
		ready: function(v) {
			// v-show/v-ifだと一瞬メニューが見えてしまうため、".dev-menu-hide"を初期状態で付けている
			// それを外して表示制御をv-showに任せる
			var e = this.$el;
			e.className = e.className.replace(/dev-menu-hide/g, "");
			// interact.js によるリサイズ処理
			interact("#dev-menu")
				.resizable({
					preserveAspectRatio: true,
					edges: { left: true, top: true }
				})
				.on("resizemove", function (event) {
					if (data.config.isPositionRight) {
						data.config.size.right.width  = event.rect.width + "px";
					} else {
						data.config.size.bottom.height = event.rect.height + "px";
					}
					saveConfig();
				});
			renderView(this);
		},
		methods: {
			leaveGame: function(index) {
				var p = {id: data.players[index].player.id, name: data.players[index].player.name};
				data.players.$remove(data.players[index]);
				amflow.sendEvent([1 /* Leave */,  3, p.id ]);
			},
			toggleMenu: function() {
				data.showMenu = !data.showMenu;
			},
			closeMenu: function() {
				data.showMenu = false;
			},
			togglePosition: function() {
				data.config.isPositionRight = !data.config.isPositionRight;
				saveConfig();
			},
			changeView: function(target) {
				for (id in data.views) {
					data.views[id].show = false;
				}
				target.show = true;
				renderView(this);
			},
			toggleBackground: function() {
				var bg = document.body.style.backgroundColor;
				document.body.style.backgroundColor = bg ? "" : "black";
			},
			togglePreventDefault: function() {
				saveConfig();
			},
			toggleWarningEs6: function() {
				saveConfig();
			},
			toggleProfiler: toggleProfiler,
			fitToWindow: function() {
				// setOffsetしないとメニューにゲーム画面が被って、メニューサイズを変更しようとするとバグるのでとりあえず true
				window.sandboxDeveloperProps.utils.fitToWindow(true);
				resizeGrid();
			},
			revertSize: function(){
				window.sandboxDeveloperProps.utils.revertViewSize();
				resizeGrid();
			},
			captureScreen: 	function(e) {
				var cvs = document.getElementsByTagName("canvas");
				e.srcElement.setAttribute("href", cvs.item(1).toDataURL());
			},
			joinGame: joinGame,
			saveSnapshot: function() {
				// スナップショット要求の発火
				if (props.game.snapshotRequest) {
					props.game.snapshotRequest.fire();
				}
			},
			removeSnapshot: removeSnapshot,
			loadSnapshot: function(name) {
				console.log("snapshot loaded: " + name);
				var snapshot = snapshots[name];

				// developerメニューの把握するカメラを全リセット
				data.cameras = [];
				cameras = [];
				// プレイヤー情報を再現 (この復元はゲームコンテンツのプレイヤー情報の復元とは関係がない)
				data.players = snapshot.players;

				props.game._reset({
					age: snapshot.age,
					randGen: g.XorshiftRandomGenerator.deserialize(snapshot.randGenSer)
				});
				props.game._loadAndStart({ snapshot: snapshot.gameSnapshot });
			},
			previewSnapshot: function(index, name) {
				data.snapshotPreview = {
					name: name,
					data: snapshotsList[index].data
				};
			},
			savePlaylog: savePlaylog,
			reloadPlaylog: reloadPlaylog,
			rewindReplay: rewindReplay,
			playPauseReplay: playPauseReplay,
			onClickTimeProgress: onClickTimeProgress,
			accelerateReplay: accelerateReplay,
			decelerateReplay: decelerateReplay,
			playFromHere: playFromHere,
			removePlaylog: removePlaylog,
			setFocusingCamera: function(index) {
				var c = cameras[index];
				if (props.game.focusingCamera !== c) {
					props.game.focusingCamera = c;
				} else {
					props.game.focusingCamera = undefined;
				}
				// TODO: GAMEDEV-2414, GAMEDEV-2415
				props.game.modified = true;
			},
			updateEntityList: updateEntityList,
			consoleDump: function() {
				var e = data.targetEntity;
				if (e.local) {
					console.log(props.game._localDb[e.id]);
				} else {
					console.log(props.game.db[e.id]);
				}
			},
			onEventsToSendChanged: function() {
				saveConfig();
			},
			onAutoSendEventsChanged: function() {
				saveConfig();
			},
			insertEventString: insertEventString,
			sendEvents: sendEvents,
			sendEventsWithValue: sendEventsWithValue,
			onAutoJoinChanged: function() {
				saveConfig();
			},
			onSendsSessionParameterChanged: function() {
				saveConfig();
			},
			onModeChanged: function() {
				saveConfig();
			},
			onTotalTimeLimitChanged: function() {
				saveConfig();
			},
			onStopGameChanged: function() {
				saveConfig();
			},
			toggleGrid: toggleGrid,
			toggleOmitInterpolatedTick: toggleOmitInterpolatedTick
		}
	});
}
194225
function onClicksetPresetData(){
$("#onClicksetPresetDataBtn").prop('disabled', true);
    setPresetData().then(()=>{
        alert("書き込み完了");
        $("#onClicksetPresetDataBtn").prop('disabled', false);
        $("#onplayPresetDataBtn").prop('disabled', false);

    }).catch((e)=>{
        alert(e);
        $("#onClicksetPresetDataBtn").prop('disabled', false);
    })
}
519616
function(){
		this.list = {};

		/* 盤面表示設定 */
		this.add('font', 1, {option:[1,2]});					/* 文字の描画 1:ゴシック 2:明朝 */
		this.add('cursor', true);								/* カーソルの表示 */
		this.add('irowake', false);								/* 線の色分け */
		this.add('irowakeblk', false);							/* 黒マスの色分け */

		this.add('dispmove', true);								/* 線で動かすパズルで実際に動いたように描画 */
		this.add('disptype_yajilin',   1, {option:[1,2]});		/* yajilin: 表示形式 */
		this.add('disptype_pipelinkr', 1, {option:[1,2]});		/* pipelinkr: 表示形式 */
		this.add('disptype_bosanowa',  1, {option:[1,2,3]});	/* bosanowa: 表示形式 */
		this.add('snakebd', false);								/* hebi: へびの境界線を表示する */
		this.add('dispqnumbg', false);							/* yinyang: 問題のまるに背景色をつける */
		this.add('undefcell', true);							/* shugaku: 未確定マスはグレー表示にする */

		this.add('squarecell', true);							/* セルは正方形にする */

		/* 表示色の設定 */
		this.add('color_shadecolor', "");						/* 黒マスの表示色の表示 */
		this.add('color_bgcolor', "white");						/* 背景色の設定 */

		/* 入力方法設定 */
		this.add('use', (!pzpr.env.API.touchevent?1:2), {option:[1,2]});	/* 黒マスの入力方法 */
		this.add('use_tri', 1, {option:[1,2,3]});				/* shakashaka: 三角形の入力方法 */

		this.add('bgcolor', false);			/* slither 背景色入力 */
		this.add('singlenum', (!pzpr.env.API.touchevent));	/* hanare: 部屋に回答数字を一つだけ入力 */
		this.add('enline', true);			/* kouchoku: 線は点の間のみ引ける */
		this.add('lattice', true);			/* kouchoku: 格子点チェック */

		/* 回答お助け機能 */
		this.add('autocmp', true,  {variety:true});	/* 数字 or kouchokuの正解の点をグレーにする */
		this.add('autoerr', false, {variety:true});	/* hitori:ひとくれの重複した数字を表示, gokigen,wagiri:斜線の色分け */

		/* 正解判定 */
		this.add('multierr', false);		/* エラー判定で複数エラーを出力する */
		this.add('allowempty', false);		/* 盤面に線や黒マスがなくても正解と判定する */
		this.add('forceallcell', false);	/* fillomino: すべての数字が入っている時のみ正解とする */
		this.add('passallcell', true);		/* arukone: すべてのセルに線が通っている時のみ正解とする */

		/* EDITORのみ */
		this.add('bdpadding', true);		/* goishi: URL出力で1マス余裕を持って出力する */
		this.add('discolor', false);		/* tentaisho: 色分け無効化 */

		/* その他の特殊項目(保存なし) */
		this.add('uramashu', false, {volatile:true});		/* 裏ましゅにする */
	}
422843
function refresh($target) {
                var PREFIX = ["-webkit-", ""];
                var valid = function (prop) {
                    return (prop && "none" !== prop);
                };
                var dataUrl;
                for (var i = 0, n = PREFIX.length; i < n; i++) {
                    if (!valid(dataUrl)) {
                        dataUrl = $target.css(PREFIX[i] + "mask-image");
                        if (valid(dataUrl)) {
                            // iOS では url(data***); 内に '"' は入らない
                            var match = dataUrl.match(/(url\(data:image\/svg\+xml;)([\s\S]*)?(base64,[\s\S]*\))/);
                            if (match) {
                                dataUrl = match[1] + "bust=" + Date.now().toString(36) + ";" + match[3];
                            }
                            else {
                                dataUrl = null;
                            }
                        }
                    }
                    if (valid(dataUrl)) {
                        $target.css(PREFIX[i] + "mask-image", dataUrl);
                    }
                }
                return $target;
            }
38736
public function rewind()
	{
		//1行目はヘッダ行なので読み飛ばす
		$this->position = 1;
		
		if(!$this->lines){
			
			//CSVを読み込み
			$giscsv = new Dm_Geocoder_GISCSV($this->prefectureCode);
			$buf = $giscsv->read();
			
			//1行ごとに分解
			$ret = array();
			$lines = explode("\r\n", $buf);
			array_pop($lines);
			foreach ($lines as $line) {
				$ret[] = $line;
			}
			
			$this->lines = $ret;
		}
	}
850735
function countingDesumasuDearu(desumasuList, dearuList) {
        let desumasuCount = desumasuList.reduce((count, { matches }) => count + matches.length, 0);
        let dearuCount = dearuList.reduce((count, { matches }) => count + matches.length, 0);
        if (desumasuCount === 0 || dearuCount === 0) {
            return;
        }
        // ですます優先
        if (desumasuCount > dearuCount) {
            reportDesumaruDearuResult(dearuList, {
                desumasu: true
            });
        } else if (desumasuCount < dearuCount) {
            // である優先
            reportDesumaruDearuResult(desumasuList, {
                dearu: true
            });
        } else {
            // 同等の場合はですます優先
            reportDesumaruDearuResult(dearuList, {
                desumasu: true
            });
        }
    }
933114
public function execute(){
		$options = $this->form_endpoint->get_options();
		$action = @$this->query_options['action'];
		$data = $options['post_params'];

		$errors = $this->exdb->validate($this->table_name, $data);

		if( $action == 'write' ){
			if( count($errors) ){
				// validation でエラーが検出されたら、入力画面に戻る。
				return $this->input($data, $errors);
			}
			return $this->write($data);
		}elseif( $action == 'done' ){
			return $this->done();
		}elseif( $action == 'confirm' ){
			if( count($errors) ){
				// validation でエラーが検出されたら、入力画面に戻る。
				return $this->input($data, $errors);
			}
			return $this->confirm($data);
		}
		return $this->input($data);
	}