<bet_list>
    <style scoped>
    </style>

	<div if={ cur_race['race_status'] >= 90 } class="Race_Infomation_Box">本レースは中止となりました</div>
	<div if={ cur_race['race_status'] < 90 && Object.keys(race_horse).length <= 0 } class="Race_Infomation_Box">このレースは出走メンバーが確定しておりません</div>
	<virtual if={ cur_race['race_status'] < 90 && Object.keys(race_horse).length >= 1 }>

		<div id="TipstarModal"></div>

		<!-- 新規買い目パネルここから -->
		<div class="IpatVote">

			<!--virtual if={ bet_view.length > 0 }-->
				<div class="BetRaceEdit_Wrap" if={ !is_edit } >
					<!-- <a href="javascript:void(0)" onclick={ act_link_charge.bind(this) } class="Btn02">チャージ</a> -->
                    <!--　開発の方へ ↓ボタンの種類をチャージからレース選択へ変更しております。遷移 -->
                    <a href="javascript:void(0)" id="RaceChoiceBtn" class="Btn01 Btn01--2">レース選択</a>
					<a href="javascript:void(0)" onClick={ act_distribution.bind(this, 'all') } data-toggle="modal" data-target="#m-change_distribution" data-backdrop="false" class="Btn01">一括分配</a>
					<a href="javascript:void(0)" class="Btn01" onClick={ act_chenge_edit_mode.bind(this) }>変更・削除</a>
				</div><!-- /.BetRaceEdit_Wrap -->
				<div class="BetRaceEdit_Wrap" if={ is_edit } >
					<a href="javascript:void(0)" class="Btn01" onClick={ act_chenge_edit_mode.bind(this) }>キャンセル</a>
				</div><!-- /.BetRaceEdit_Wrap -->

				<div class="Selected_Table_Head">
					<div class="Selected_Table_Inner">
						<span>買い目</span>
						<span>購入金額</span>
						<span>想定払戻</span>
					</div><!-- /.Selected_Table_Inner -->
					<div class="Select" if={ is_edit }></div>
				</div>

                <div if={!is_ekyc && vote_mode == 'netkeirin'} class="errorMessageBox">
                    <div class="errorMessageInBtn" id="">
                        <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 11 11">
                            <g id="グループ_20979" data-name="グループ 20979" transform="translate(-28.76 -30.631)">
                              <path id="パス_3448" data-name="パス 3448" d="M34.26,30.631a5.5,5.5,0,1,0,5.5,5.5,5.506,5.506,0,0,0-5.5-5.5Zm0,8.708a.458.458,0,1,1,.458-.458.458.458,0,0,1-.458.458Zm.458-2.291a.458.458,0,0,1-.917,0V33.381a.458.458,0,1,1,.917,0Zm0,0" transform="translate(0)" fill="#fff"/>
                            </g>
                          </svg>
                          投票には本人確認が必要です
                          <span class="chevron"></span>
                    </div>
                    <div class="errorMessageContents patShortMoney">
                        <div class="errorMessageContentsInner">
                            <div class="inBtnWrap" onclick="location.href='{args.keirin_url}regist/ekyc/'">
                                <div class="inBtn inBtn2">本人確認へ</div>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- B-4-2 金額入力画面[カート/マネー不足] -->
                <div if={is_ekyc && args.sns_user_id != '' && point < total_bet_money && vote_mode == 'netkeirin'} class="errorMessageBox">
                    <div class="errorMessageInBtn" id="">
                        <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 11 11">
                            <g id="グループ_20979" data-name="グループ 20979" transform="translate(-28.76 -30.631)">
                              <path id="パス_3448" data-name="パス 3448" d="M34.26,30.631a5.5,5.5,0,1,0,5.5,5.5,5.506,5.506,0,0,0-5.5-5.5Zm0,8.708a.458.458,0,1,1,.458-.458.458.458,0,0,1-.458.458Zm.458-2.291a.458.458,0,0,1-.917,0V33.381a.458.458,0,1,1,.917,0Zm0,0" transform="translate(0)" fill="#fff"/>
                            </g>
                          </svg>
                          マネーが不足しています
                          <span class="chevron"></span>
                    </div>
                    <div class="errorMessageContents patShortMoney">
                        <div class="errorMessageContentsInner">
                            <dl class="detail">
                                <dt>投票マネー</dt>
                                <dd>{number_format(total_bet_money)}円</dd>
                            </dl>
                            <dl class="detail">
                                <dt>マネー</dt>
                                <dd>{number_format(point)}円</dd>
                            </dl>
                            <dl class="detail detail2">
                                <dt>不足マネー</dt>
                                <dd class="redText">{number_format(total_bet_money - point)}円</dd>
                            </dl>
                            <div class="inBtnWrap">
                                <div class="inBtn" onclick="{ charge.bind(this) }">チャージする</div>
                            </div>
                        </div>
                    </div>
                </div>

				<table class="RaceOdds_Result_Table03" if={ is_edit }>
					<tbody>
						<tr class="ActionBtn">
							<td class="Txt"><div><span>すべてを選択/クリア</span></div></td>
							<td class="BtnCell">
								<input class="All_Action" id="p-chk_all" type="checkbox" value="1" onClick={ act_kaime_select_all.bind(this) } checked="{ bet_select_all ? true : false }" />
								<label for="p-chk_all"></label>
							</td>
						</tr>
					</tbody>
				</table>

			<!--/virtual-->

			<div class="NoData_Msg" if={ bet_view.length == 0 }>
				<div class="Msg">買い目がありません。</div>
			</div>

			<virtual each={ shikibetu in disply_bet_order } >
				<div if={ disply_bet_view[shikibetu] } class="Type Type_BgColor0{ shikibetu }">{ disply_bet_label[shikibetu] }</div>
				<virtual each={ bet,bix in disply_bet_view[shikibetu] } >
					<div class={ (bet_select[bet.idx * 1000] ? 'BetTable color' : 'BetTable' ) + (disply_bet_view[shikibetu] ? ' ' + 'odds_' + shikibetu : '' ) }>
					<div class="Selected_Table">
						<div class="Selected_Table_Inner">
						<div class="BtnTrashBox01" onclick={ act_kaime_delete_trashbox.bind(this, bet.idx, -1) }><a href="javascript:void(0)"><span class="Icon_TrashBox"><svg xmlns="http://www.w3.org/2000/svg" width="16.716" height="17.924" viewBox="0 0 16.716 17.924"><title>捨てる</title><path d="M122.588,3162.3l-1.052-13.935h-1.549v-1.351h4.591v-2.638h7.534v2.638H136.7v1.351h-1.549L134.1,3162.3Zm1.253-1.351h9.007l.95-12.583H122.891Zm2.088-13.935h4.831v-1.287h-4.831Zm3.047,4.159h-1.263v6.967h1.263Zm-2.42,0h-1.262v6.967h1.262Zm4.839,0h-1.262v6.967H131.4Z" transform="translate(-119.987 -3144.372)" fill="#666" /></svg></span></a></div>

							<div class="BetKaime_Table">
								<div class={ ('0' !== bet.houshiki) ? 'kaime_view FormationType' : 'kaime_view' } id="select_kumiawase">
									<div class="Kenshu" if={ '0' != bet.houshiki && bet.shikibetu != '1'}>{ bet.houshiki_name }&nbsp;{ bet.is_multi ? 'マルチ': '' }</div>
									<div if={ '0' == bet.houshiki } class="Num">
										<div class="Shaban_InBox">
											<svg if={ my_mark[bet.kaime1] && shikibetu != 3 && shikibetu != 4  } class="Icon_Shirushi01 Icon_{ edit_kaime_mark(my_mark[bet.kaime1], true, shikibetu) }">
												<use xlink:href="/common/img/icon/icon_shirushi.svg#icon-{ edit_kaime_mark(my_mark[bet.kaime1], false, shikibetu) }"></use>
											</svg>
											<span class="Wakuban Waku{ (shikibetu == 3 || shikibetu == 4) ? '1' : bet.kaime1 }" if={ '' != bet.kaime1 }>{ bet.kaime1 }</span>
											<span class="Name" if={shikibetu !=3 && shikibetu !=4 && race_horse[bet.kaime1] != undefined }>{race_horse[bet.kaime1]['names']}</span>
										</div><!-- /.Shaban_InBox-->
										<virtual if={ '' != bet.kaime2 }>
										<span class="{ edit_kaime_class(bet.shikibetu) }"></span>
										<div class="Shaban_InBox">
											<svg if={ my_mark[bet.kaime2] && shikibetu != 3 && shikibetu != 4  } class="Icon_Shirushi01 Icon_{ edit_kaime_mark(my_mark[bet.kaime2], true, shikibetu) }">
												<use xlink:href="/common/img/icon/icon_shirushi.svg#icon-{ edit_kaime_mark(my_mark[bet.kaime2], false, shikibetu) }"></use>
											</svg>
											<span class="Wakuban Waku{ (shikibetu == 3 || shikibetu == 4) ? '1' : bet.kaime2 }">{ bet.kaime2 }</span>
											<span class="Name" if={shikibetu !=3 && shikibetu !=4 && race_horse[bet.kaime2] != undefined }>{race_horse[bet.kaime2]['names']}</span>
										</div><!-- /.Shaban_InBox-->
										</virtual>
										<virtual if={ '' != bet.kaime3 }>
										<span class="{ edit_kaime_class(bet.shikibetu) }"></span>
										<div class="Shaban_InBox">
											<svg if={ my_mark[bet.kaime3] && shikibetu != 3 && shikibetu != 4  } class="Icon_Shirushi01 Icon_{ edit_kaime_mark(my_mark[bet.kaime3], true, shikibetu) }">
												<use xlink:href="/common/img/icon/icon_shirushi.svg#icon-{ edit_kaime_mark(my_mark[bet.kaime3], false, shikibetu) }"></use>
											</svg>
											<span class="Wakuban Waku{ (shikibetu == 3 || shikibetu == 4) ? '1' : bet.kaime3 }">{ bet.kaime3 }</span></virtual>
											<span class="Name" if={shikibetu !=3 && shikibetu !=4 && race_horse[bet.kaime3] != undefined }>{race_horse[bet.kaime3]['names']}</span>
										</div><!-- /.Shaban_InBox-->
										</virtual>
									</div><!-- /.Num -->
									<div class="LabelWrap" if={ '0' != bet.houshiki } each={ row,ik in bet.ary_kaime }>
										<div if={ '2' != bet.houshiki } class="LabelArrow { (my_mark[row]) ? 'is_mark' : '' }">
											<span>{ edit_kaime_label(bet.shikibetu, bet.houshiki, ik) }</span>
										</div>
										<div if={ '2' == bet.houshiki } class="LabelArrow">
											<span>選択</span>
										</div>
										<div class="Num">
											<div class="Shaban_InBox" each={ uno in row }>
                                                <svg if={ my_mark[uno] && shikibetu != 3 && shikibetu != 4  } class="Icon_Shirushi01 Icon_{ edit_kaime_mark(my_mark[uno], true, shikibetu) }">
													<use xlink:href="/common/img/icon/icon_shirushi.svg#icon-{ edit_kaime_mark(my_mark[uno], false, shikibetu) }"></use>
												</svg>
												<span class="Wakuban Waku{ (shikibetu == 3 || shikibetu == 4) ? '1' : uno }">{ uno }</span>
											</div><!-- /.Shaban_InBox-->
										</div><!-- /.Num -->
									</div><!-- /.LabelWrap -->
									<virtual if={ '0' == bet.houshiki }>
										<span class="OddsData01" if={ bet_odds_list[bet['bet_id']] }>{ sprintf("%0.1f", bet_odds_list[bet['bet_id']][0]) }倍</span>
									</virtual>
                                    <!--
									<virtual if={ bet_odds_list[bet['bet_id']] && '0' !== bet.houshiki && bet_odds_list[bet['bet_id']].length > 1 }>
										<span class="OddsData01">{ edit_ary_maxmin(bet_odds_list[bet['bet_id']], 'min') }倍 ～ { edit_ary_maxmin(bet_odds_list[bet['bet_id']], 'max') }倍</span>
									</virtual>-->
								</div><!-- /.kaime_view -->
								<div class={ ('0' !== bet.houshiki) ? 'pay FormationType' : 'pay' }>
									<div class="FormationTypeWrap" if={ '0' !== bet.houshiki }>
										<ul class="FormationType" if={ '0' !== bet.houshiki }>
											<li>
												<span class="Txt01 InputMoneyWrap">
													各
													<span class="BetCountBtnWrap">
														<span class="BetCountBtn Plus" onClick={ act_money_change_btn.bind(this, 'p') }><span>+</span></span>
														<span class="BetCountBtn Minus" onClick={ act_money_change_btn.bind(this, 'm') }><span>-</span></span>
													</span>
													<input name="" min="1" max="10000" pattern="[0-9]*" class="InputMoney" type="text" onchange={act_change_money_single.bind(this) } onfocus={ act_select_input.bind(this, false) } onblur={act_select_input.bind(this, true)} value="{ edit_check_bet_money(bet.bet_money) }">00円
												</span>
											</li>
											<!--li><span class="Txt01">各{ number_format(bet.bet_money) }円</span></li-->
										</ul>
										<div class="AssumedOdds FormationType" if={ '0' !== bet.houshiki }>
											<dl class="PayData01">
												<dt><span class="kumiawase_kensu"><em>{bet.bet_count}</em>点</span> 計</dt>
												<dd class="Total">{ number_format(bet.bet_money_total) }円</dd>
											</dl>
											<!--virtual if={ bet_odds_list[bet['bet_id']] && '0' !== bet.houshiki && bet_odds_list[bet['bet_id']].length > 1 }>
												<dl class="PayData01">
													<dd>
														{ edit_ary_maxmin(bet.payback, 'min') }円 ～ { edit_ary_maxmin(bet.payback, 'max') }円
														<span class="Profit">( <span class="{ edit_payment_diff(edit_ary_maxmin(bet.payback, 'min'), total_bet_money) }">{ number_format(edit_ary_maxmin(bet.payback, 'min') - total_bet_money) }円</span> ～  <span class="{ edit_payment_diff(edit_ary_maxmin(bet.payback, 'max'), total_bet_money) }">{ number_format(edit_ary_maxmin(bet.payback, 'max') - total_bet_money) }円</span> )</span>
													</dd>
												</dl>
											</virtual-->
										</div><!-- /.AssumedOdds -->
									</div><!-- /.FormationTypeWrap -->
									<ul if={ '0' == bet.houshiki }>
										<li>
											<span class="Txt01 InputMoneyWrap">
												<span class="BetCountBtnWrap">
													<span class="BetCountBtn Minus" onClick={ act_money_change_btn.bind(this, 'm') }><span>-</span></span>
												</span>
												<input name="" min="1" max="10000" pattern="[0-9]*" class="InputMoney" type="text" onchange={act_change_money_single.bind(this) } onfocus={ act_select_input.bind(this, false) } onblur={act_select_input.bind(this, true)} value="{ edit_check_bet_money(bet.bet_money) }">00<br>円
												<span class="BetCountBtnWrap InputRight">
													<span class="BetCountBtn Plus" onClick={ act_money_change_btn.bind(this, 'p') }><span>+</span></span>
												</span>
											</span>
										</li>
									</ul>
								</div><!-- /.pay -->
								<div class="AssumedOdds" if={ '0' == bet.houshiki }>
									<div class="PayData01">
										{ ('0' == bet.houshiki) ? number_format(bet.payback)+'円' : '' }
										<span class="Profit">( <span class="{ edit_payment_diff(bet.payback, total_bet_money) }">{ number_format(bet.payback - total_bet_money) }円</span> )</span>
									</div>
								</div><!-- /.AssumedOdds -->

							</div><!-- /.BetKaime_Table -->

                            <div class="AssumptionBox" if={bet.houshiki !== '0' &&  bet_odds_list[bet['bet_id']] && bet_odds_list[bet['bet_id']].length > 1 }>
                                <dl class="AssumptionList">
                                    <dt>オッズ</dt>
                                    <dd>{ edit_ary_maxmin(bet_odds_list[bet['bet_id']], 'min') }倍 ～ { edit_ary_maxmin(bet_odds_list[bet['bet_id']], 'max') }倍</dd>
                                </dl>
                                <dl class="AssumptionList">
                                    <dt>想定払戻金</dt>
                                    <dd>
                                        { number_format(parseInt(edit_ary_maxmin(bet.payback, 'min'))) }円 ～ { number_format(parseInt(edit_ary_maxmin(bet.payback, 'max'))) }円
                                    </dd>
                                </dl>
                                <dl class="AssumptionList">
                                    <dt>収支</dt>
                                    <dd>
                                        <span class="Profit">( <span class="{ edit_payment_diff(edit_ary_maxmin(bet.payback, 'min'), total_bet_money) }">{ number_format(edit_ary_maxmin(bet.payback, 'min') - total_bet_money) }円</span> ～  <span class="{ edit_payment_diff(edit_ary_maxmin(bet.payback, 'max'), total_bet_money) }">{ number_format(edit_ary_maxmin(bet.payback, 'max') - total_bet_money) }円</span> )</span>
                                    </dd>
                                </dl>
                            </div>
							<div class="kaime_open" if={ bet['comb' ] } onClick={ act_kaime_open.bind(this, bet.idx) } }>
								<!--input class="disp_none" id="p-chk_open_{bet.idx}" type="checkbox" -->
								<label for="p-chk_open_{bet.idx}">
									<span if={ ! bet.open }>展開する</span>
									<span if={ bet.open } class="Open">展開を閉じる</span>
								</label>
							</div><!-- /.kaime_open -->
						</div><!-- /.Selected_Table_Inner -->
						<div if={ is_edit } class="Select" onClick={ act_kaime_select.bind(this, bet.idx, -1) }>
							<input class="BuyCheck_Select disp_none" type="checkbox" id="p-chk_sel_{bet.idx}" value="1" checked={ (bet_select[bet.idx * 1000]) ? true : false } onClick={ act_kaime_select.bind(this, bet.idx, -1) } />
							<!-- bet.idx={bet.idx} -->
							<label for="p-chk_sel_{bet.idx}" class="Check01Btn_Off"></label>
						</div><!-- /.Select -->
					</div><!-- /.Selected_Table -->

					<table class="RaceOdds_Result_Table02" if={ bet.open }>
						<tbody class="list">
                            <tr>
                                <div class="BetRaceEdit_Wrap" if={ bet.open } onClick={ act_distribution.bind(this, bet.idx) }><a href="javascript:void(0)" data-toggle="modal" data-target="#m-change_distribution" data-backdrop="false" class="Btn01">分配</a></div>
                            </tr>
							<tr each={ comb,bcix in bet.comb } class={ (bet_select[bet.idx * 1000 + bcix + 1]) ? 'bg-danger' : '' }>
								<td class="Open_Lavel"></td>
								<td class="Apart">
									<div class="Num">
										<virtual each={ row in edit_combination(comb, bet.shikibetu, bet.houshiki) }>
											<div class="Shaban_InBox">
                                                <svg if={ my_mark[row.no] && shikibetu != 3 && shikibetu != 4 } class="Icon_Shirushi01 Icon_{ edit_kaime_mark(my_mark[row.no], true, shikibetu) }">
													<use xlink:href="/common/img/icon/icon_shirushi.svg#icon-{ edit_kaime_mark(my_mark[row.no], false, shikibetu) }"></use>
												</svg>
												<span class="Wakuban Waku{ (shikibetu == 3 || shikibetu == 4) ? '1' : row.no }">{ row.no }</span>
                                                <span class="Name" if={shikibetu !=3 && shikibetu !=4 }>{ race_horse[row.no]['names'] }</span>
											</div><!-- /.Shaban_InBox-->
                                            <span class={ shikibetu===4 ? 'Kaime_Arrow' : ((1==row.type) ? 'Hyphen' : 'Kaime_Arrow' ) } if={ row.type> 0 }></span>
										</virtual>
									</div><!-- /.Num -->
                                    <span if={ bet.comb_odds[bcix] } class="OddsData01">{ sprintf("%0.1f", bet.comb_odds[bcix]) }倍</span>
								</td>
								<td class="Pay">
									<span class="InputMoneyWrap">
										<span class="BetCountBtnWrap">
											<span class="BetCountBtn Minus" onClick={ act_money_change_btn_child.bind(this, bet.bet_money, bet.idx, bcix + 1, 'm') }>-</span>
										</span>
										<input name="" min="1" max="10000" pattern="[0-9]*" class="InputMoney child_input" type="text" onfocus={ act_money_check.bind(this) } onchange={ act_money_change_child.bind(this, bet.idx, bcix + 1) } value="{ number_format( bet.bet_money / 100 ) }">00<br>円
										<span class="BetCountBtnWrap InputRight">
											<span class="BetCountBtn Plus" onClick={ act_money_change_btn_child.bind(this, bet.bet_money, bet.idx, bcix + 1, 'p') }>+</span>
										</span>
									</span>
								</td>
								<td class="AssumedOdds">
									<dl class="PayData01">
										<dd>
											<span>{ ('0' != bet.houshiki) ? number_format(bet.payback[bcix])+'円' : '' }</span> <span class="Profit">( <span class="{edit_payment_diff(bet.payback[bcix], total_bet_money)}">{ number_format(bet.payback[bcix] - total_bet_money) }円</span> )</span>
										</dd>
									</dl>
								</td>
								<td class="Select Select2" if={ is_edit }>
									<input class="BuyCheck_Select disp_none" type="checkbox" id="p-chk_sel_comb_{bcix}" value="1" checked={ (bet_select[bet.idx * 1000 + bcix + 1]) ? true : false } onClick={ act_kaime_select.bind(this, bet.idx, bcix + 1) } />
									<!-- bcix={bcix} -->
									<label for="p-chk_sel_comb_{bcix}" class="Check01Btn_Off"> </label>
								</td>
							</tr>
						</tbody>
					</table>
					</div><!-- /.BetTable -->
				</virtual><!-- endeach -->
			</virtual><!-- endeach -->

			<table class="RaceOdds_Result_Table03" if={ is_edit && bet_view.length > 0 }>
				<tbody>
					<tr class="ActionBtn">
						<td class="Txt"><div><span>すべてを選択/クリア</span></div></td>
						<td class="BtnCell">
							<input class="All_Action" id="p-chk_all_up" type="checkbox" value="1" onClick={ act_kaime_select_all.bind(this) } checked="{ bet_select_all ? true : false }" />
							<label for="p-chk_all_up"></label>
						</td>
					</tr>
				</tbody>
			</table>

            <ul if={vote_mode == 'netkeirin'} class="NoticeList">
                <li>※「投票」ボタンをタップ後、マネーを消費の上、返品、変更、撤回、解除等はお受けいたしません</li>
                <li>※車券は締切時刻まで購入可能な上、「投票」をタップ後、随時提供されます</li>
                <li>※<a href="{ args.keirin_url }/info/tokusho/?rf=footer#tab_02" class="textLink">特商法に基づく表記</a></li>
            </ul>

			<div class="InputFixedArea_Wrap" if={ bet_view.length > 0 }>
			<!--<div class={ args.is_appli ? 'InputFixedArea_Wrap' : 'InputFixedArea_Wrap AppBottomFixed' }>-->
				<div class="InputFixedArea01 {vote_mode == 'TIPSTAR' ? 'tipstar' : ''}" if={ show_bet_buttom }>
					<virtual if={ !is_edit }>
						<dl class="TotalBetDL">
							<!--dt>投票予定：{ bet_view.length }件 / </dt-->
							<dt>{ bet_view.length }組 { edit_bet_count_all() }点 / </dt>
							<dd> <span class="PrizeMoney" id="total_price">合計 { number_format(total_bet_money) }円</span> </dd>
						</dl>
						<div class="InputBtnBox">
							<button class="BetAddBtn" type="button" onClick={ act_change_mode.bind(this, bet_mode) }>買い目<br>追加</button>
							<!-- <button if={ ! args.is_appli } class="BetAddBtn" id="action_bet_{event_id}" onClick={ tipstar_bet_v2.bind(this, 'bet') } disabled={ is_active_button ? false : true }>TIPSTAR投票<span>へすすむ</span></button> -->
							<!-- <button if={ ! args.is_appli } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ netkeirin_bet.bind(this, 'bet') } disabled={ is_active_button ? false : true }>netkeirin投票<span>へすすむ</span></button> -->
                            <!--button if={ vote_mode == 'netkeirin' } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ netkeirin_bet.bind(this, 'bet') } disabled={ is_bet_disable() }>投票</button-->
                            <button if={ vote_mode == 'netkeirin' } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ check_passcode.bind(this, 'bet') } disabled={ is_bet_disable() }>投票</button>
                            <button if={ vote_mode == 'TIPSTAR' && args.is_appli } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ tipstar_bet_appli.bind(this, 'bet') } disabled={ is_active_button && !is_ban_user ? false : true }>TIPSTAR投票<span>へすすむ</span></button>
                            <button if={ vote_mode == 'TIPSTAR' && !args.is_appli } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ tipstar_bet_v2.bind(this, 'bet') } disabled={ is_active_button && !is_ban_user ? false : true }>TIPSTAR投票<span>へすすむ</span></button>
							<!--button if={ args.is_appli } class="ipat_dialog action_bet" id="action_bet_{event_id}" onClick={ tipstar_bet_appli.bind(this, 'bet') } disabled={ is_active_button ? false : true }>TIPSTAR投票<span>へすすむ</span></button-->
						</div>
					</virtual>
					<virtual if={ is_edit }>
						<dl class="TotalBetDL"> <dt>選択中：{ Object.keys(bet_select).length }点</dt>
						</dl>
						<div class="InputBtnBox">
							<button class="CheckBtn CheckChangeBtn" data-toggle="modal" data-target="#m-change_money" data-backdrop="false">金額変更</button>
							<button class="CheckBtn CheckDeleteBtn" type="button" onClick={ act_kaime_delete.bind(this) }>削除</button>
						</div>
					</virtual>
				</div>
			</div>
			<!-- 金額変更モーダル -->
			<div id="m-change_money" class="modal fade" aria-hidden="true">
				<div class="BatchInput_Form">
					<div class="BatchInput_Header">
						<div class="Title">金額入力</div>
						<div class="BatchInputValue">
							<input name="money" id="change_money_input" type="number" min=1 max=10000 pattern="[0-9]*" value="{ edit_check_bet_money(bet_money) }" onfocus="this.select();" onInput={act_input_money.bind(this) }/> <div>00<span>円</span></div>
						</div><!-- /.BatchInputValue -->
					</div><!-- /.BatchInput_Header -->
					<div class="Type_Btn">
						<ul>
                            <li><button class="Btn CanselBtn01" onClick={ act_change_money.bind(this, false) }>キャンセル</button></li>
							<li><button class="Btn SubmitBtn01" onClick={ act_change_money.bind(this, true) }>変更する</button></li>
						</ul>
					</div><!-- /.Type_Btn -->
					<div class="BatchInput_CloseBtn" onClick={ act_change_money.bind(this, false) }><span>閉じる</span></div>
				</div><!-- /.BatchInput_Form -->
			</div>

			<!-- 資金分配モーダル -->
			<div id="m-change_distribution" class="modal fade" aria-hidden="true">
				<div class="BatchInput_Form">
					<div class="BatchInput_Header">
                        <!-- 一括分配時テキスト -->
						<div class="Title">{ distribution_title }</div>
                        <!-- 一括分配時テキスト -->
                        <!-- フォーメーション分配時テキスト -->
						<!-- <div class="Title">資金分配</div> -->
                        <!-- フォーメーション分配時テキスト -->
                        <div class="tabContent Tab01">
                            <ul class="Player_Ranking Tab_Col2">
                                <li class="{ distribution_mode == 'bet' ? 'Active' : '' }">
                                    <a href="" onClick={ act_change_distribution_mode.bind(this, 'bet') }>投票額から分配</a>
                                </li>
                                <li class="{ distribution_mode == 'payback' ? 'Active' : '' }">
                                    <a href="" onClick={ act_change_distribution_mode.bind(this, 'payback') }>払戻額から分配</a>
                                </li>
                            </ul>
                        </div>
                        <!-- 投票額から分配時テキスト -->
                        <p if={ distribution_mode == 'bet' } class="BatchInput_Text">払戻額が均等になるように<br>投票額が分配されます</p>
                        <!-- 投票額から分配時テキスト --><!-- 投票額から分配 -->
                        <!-- 払戻額から分配時テキスト -->
                        <p if={ distribution_mode == 'payback' } class="BatchInput_Text">入力した払戻額になるように<br>投票額が分配されます</p>
                        <!-- 払戻額から分配時テキスト -->
						<div class="BatchInputValue">
                            <span class="BetCountBtnWrap"> <span class="BetCountBtn Plus" onClick={ act_money_change_btn.bind(this, 'p') }><span>+</span></span> <span class="BetCountBtn Minus" onClick={ act_money_change_btn.bind(this, 'm') }><span>-</span></span></span>
							<input name="money" id="change_money_input_distribution" type="number" min=1 max=10000 pattern="[0-9]*" value="{ edit_check_bet_money(bet_money) }" onfocus="this.select();" onInput={act_input_money.bind(this) }/> <div>00<span>円</span></div>
						</div><!-- /.BatchInputValue -->
					</div><!-- /.BatchInput_Header -->
					<div class="Type_Btn">
						<ul>
                            <li><button class="Btn CanselBtn01" onClick={ act_change_money.bind(this, false) }>キャンセル</button></li>
							<li>
                                <button class="Btn SubmitBtn01" onClick={ act_change_distribution.bind(this, true) }>適用する
                                </button>
                            </li>
						</ul>
					</div><!-- /.Type_Btn -->
					<div class="BatchInput_CloseBtn" onClick={ act_change_money.bind(this, false) }><span>閉じる</span></div>
				</div><!-- /.BatchInput_Form -->
			</div>

		</div><!-- /.IpatVote -->

	<div if={ !show_regist && is_tipstar_modal } class="HalfModal TipstarCoope">
		<div class="TipstarCoopeWrap">
			<div class="Title"><img src="{ args.cdn_keirin_url }/common/img/top/bnr_tipstar.png" class="Logo" alt="TIPSTAR"> 連携サービスとは</div>
			<div class="Introduction">
				<p class="Txt" if={ !args.is_appli }>netkeirinで作成した買い目データを、TIPSTARにカンタン送信・保存するサービスです。<br>
				※ご利用にはTIPSTARへのログインが必要です。</p>
				<p class="Txt" if={ args.is_appli }>netkeirinで作成した買い目データを、TIPSTARに送信いたします。ここから先はアプリ外に遷移し、ブラウザでTIPSTARをご利用ください。<br>
				※ご利用にはTIPSTARへのログインが必要です。
				</p>
				<img src="{ args.cdn_keirin_url }/common/img/race/img_tip_coope_01.png" class="FlowImg" alt="netkeirin→買い目データ→TIPSTAR">
			</div><!-- /.Introduction -->
			<div class="Dialog_Contents">
				<div class="Title">利用規約の確認</div>
				<p class="Txt">利用規約をご確認のうえ「同意する」へお進みください。</p>
				<div class="LinkBtn_04 mt10">
					<a href="{ args.keirin_url }/info/kiyaku/tipstar_kiyaku.html?rf=tip_bet" target="_blank" id="read_kiyaku">利用規約を読む</a>
				</div>
				<ul class="Dialog_Btn Col2 fc">
					<li class="Disagree"><button class="Btn Disagree" onclick="javascript:void(0)">同意しない</button></li>
					<!--li if={ !is_cahrge && !args.is_appli } class="Agree"><button class="SubmitBtn" id="tipstar_agree" onclick="{ tipstar_bet.bind(this, 'modal') }">同意する(旧環境)</button></li-->
					<li if={ !is_cahrge && !args.is_appli } class="Agree"><button class="SubmitBtn" id="tipstar_agree" onclick="{ tipstar_bet_v2.bind(this, 'modal') }" disabled={ is_active_button && !is_ban_user ? false : true }>同意する</button></li>
					<li if={ !is_cahrge && args.is_appli } class="Agree"><button class="SubmitBtn Agree" id="tipstar_agree" onclick="{ tipstar_bet_appli.bind(this, 'modal') }" disabled={ is_active_button && !is_ban_user ? false : true }>同意して進む<span>（ブラウザへ）</span></button></li>
					<!--li if={ !is_cahrge && !args.is_appli } class="Agree"><button class="SubmitBtn Agree" id="tipstar_agree" onclick="{ tipstar_bet_appli.bind(this, 'modal') }">同意して進む<span>（ブラウザへ）test</span></button></li-->
					<li if={ is_cahrge } class="Agree"><button class="SubmitBtn" id="tipstar_agree" onclick="{ tipstar_charge.bind(this) }">同意する</button></li>
				</ul>
			</div><!-- /.Dialog_Contents -->
			<div class="Check">
				<input type="checkbox" id="kiyaku_submit" name="kiyaku_submit" value="1">
				<label for="kiyaku_submit">今後この画面を表示しない</label>
			</div><!-- /.Check -->
		</div><!-- /.TipstarCoopeWrap -->
		<div class="HalfModal_CloseBtn"><span>閉じる</span></div>
	</div><!-- /.HalfModal -->

    <div class="addSyaken addSyaken--3" if={ bet_view.length == 0 }>
        <div class="text">買い目を選択してください</div>
        <div class="triangle"></div>
    </div>
    </virtual>

<div if={ show_regist } class="HalfModal bet_appAppeal">
    <div>
        <iframe if={ device == '1' } id="regist_frame" src="{ iframe_url }"></iframe>
        <div if={ device != '1' } class="SpInfoModalWrap app_appeal">
            <div class="Title"><img alt="netkeirin" src="{ args.cdn_keirin_url }/common/img/netkeirinlogo_illustver.svg" class="NetkeirinLogo01"></div>
            <div class="Dialog_Contents">
                <p class="Txt02 mb32">ご利用にはアカウント登録が必要です</p>
                <img src="{ args.cdn_keirin_url }/common/img/app_appeal_01.png" alt="アプリならインストールするだけでアカウント登録が完了!">
                <a href="https://netkeirin.onelink.me/zoXs/iyu84bes" class="RegistLinkBtn01 mb28">
                    アプリ無料ダウンロード
                </a>
                <p class="Txt02">車券投票には別途本人確認が必要となります</p>
            </div><!-- /.Dialog_Contents -->
        </div>
    </div>
    <div class="HalfModal_CloseBtn"><span>閉じる</span></div>
</div><!-- /.HalfModal -->

<div class="CenterModal commonRegister AfterVote" if={is_vote_error} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
	<div class="CenterModalContent">
	  <div class="contentInter">
		<div class="logo">
			<img src="{ args.cdn_url}/common/img/netkeirinlogo_illustver.svg" alt="netkeirin">
		</div>
		<p class="head">投票できませんでした</p>
		<p class="attention"><img src="{ args.cdn_url}/common/img/regist/regist02/icon_attention.svg" alt=""></p>
		<p class="attentionText" id="vote_error_msg"></p>

		<!-- レースメニュー -->
		<!-- race_bottom_menu2を読み込んでください↓ -->

		<div class="TodayRace_Slide" style="display: block;">
			<div class="Title_Sec">
				<h2>発走直前レース</h2>
				<div class="Title_BtnMore">
					<a href="{args.keirin_url}/race/race_list/?rf=toplive">競輪一覧</a>
				</div>
				<div class="Title_BtnMore">
					<a href="{args.keirin_url}/pist6/race_list/?rf=toplive">PIST6一覧</a>
				</div>
			</div>
			<!-- /.Title_Sec -->
			<div id="TodayRace_Live" class="TodayRace_SlideBox"></div>
			<!-- /.TodayRace_SlideBox -->
		</div>
	  </div>
	  <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}">
		<span>閉じる</span>
	  </div>
	</div>
</div>

<div class="CenterModal commonRegister Rejection" if={is_money_limit_error} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
    <div class="CenterModalContent">
        <div class="contentInter">
            <h2 class="Title">投票上限額の設定</h2>
            <div class="ChargeBox">
                <p class="img">
                    <img src="{args.cdn_url}/common/img/regist/icon/icon_attention.svg" alt="">            
                </p>
                <p class="text">投票できません</p>
        
                <p class="text2 text2-1">1日にご購入いただける上限金額を超えたため本日はご購入いただけません。</p>
                <table class="limitTable">
                    <tbody>
                    <tr>
                        <th>1日の投票上限額</th>
                        <td>{number_format(vote_setting['vote_limit_price'])}円</td>
                    </tr>
                    <tr>
                        <th>本日の投票額</th>
                        <td>{number_format(vote_setting['vote_total_price'])}円</td>
                    </tr>
                    <tr>
                        <th>残り可能な投票</th>
                        <td>{number_format(vote_setting['vote_remain_price'])}円</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}">
            <span>閉じる</span>
        </div>
    </div>
</div>
  

<div class="CenterModal commonRegister raceVoteLoading" if={is_voting} style="display: block;">
  <div class="CenterModal-bg">
  </div>
  <div class="CenterModalContent">
    <div class="contentInter">
    <p class="img">
      <img src="{args.cdn_url}/common/img/race/loading_animation.gif" alt="投票中">
    </p>
    <div class="textWrap">
      <p class="text__voting">投票中</p>
      <div class="stage">
        <div class="dot-flashing"></div>
      </div>
    </div>
    </div>
  </div>
</div>

<div class="addSyaken addSyaken--2" if={ bet_view.length > 0 && vote_money >= 100 }>
    <div class="icon">
        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
            <path id="パス_3448" data-name="パス 3448" d="M35.26,30.631a6.5,6.5,0,1,0,6.5,6.5,6.507,6.507,0,0,0-6.5-6.5Zm0,10.291a.542.542,0,1,1,.542-.542.542.542,0,0,1-.542.542Zm.542-2.708a.542.542,0,0,1-1.083,0V33.881a.542.542,0,0,1,1.083,0Zm0,0" transform="translate(-28.76 -30.631)" fill="#fff"/>
          </svg>
    </div>
    <div class="text">このレースには、{number_format(vote_money)}マネー投票しています</div>
    <div class="triangle"></div>
</div>

<div class="CenterModal commonRegister jsModalUnable unable" if={is_pist6_error} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
	<div class="CenterModalContent">
	  <div class="contentInter">
		<div class="logo">
			<img src="{args.cdn_url}/common/img/netkeirinlogo_illustver.svg" alt="netkeirin">
		</div>
		<p class="head">投票できません</p>
		<p class="attention"><img src="{args.cdn_url}/common/img/regist/icon/icon_attention.svg" alt="netkeirin"></p>
		<p class="text">PIST6の投票は<br>TIPSTAR投票のみ可能です。</p>
		<button class="btn modal-close" onclick="{changeBetMode.bind(this, 'TIPSTAR')}">TIPSTAR投票に切り替える</button>
	  </div>
	  <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}">
		<span>閉じる</span>
	  </div>
	</div>
</div>

<div class="CenterModal ChargeType_A-3-2-1 jsModalContainer" if={is_passcode_form} style="display: block;">
  <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
  <div class="CenterModalContent">
    <div class="ChargeTypeInner">
      <div class="ChargeBox">
        <p class="textInput">暗証番号を入力してください</p>
        <p class="errorText" if={is_passcode_error}>一定回数間違えるとロックされます</p>
        <!--form action="" method="post" id="passwordForm"-->
          <div class="AmountInput">
            <input onchange={act_input_passcode.bind(this)} type="password" name="currentPassword" id="jsInputPasswordCurrent" class="InputArea validate[required,custom[onlyNumberSp],maxsize[4]] { is_passcode_error ? 'InputAreaError' : '' }" maxlength="4" inputmode="numeric" oninput="this.value = this.value.replace(/[^0-9]/g, '')">
            <div class="errorPasswordText" if={is_passcode_error} style="display: block;">暗証番号が正しくありません</div>
          </div>
          <!--input type="submit" class="StartCharge jsSetNumber" onclick="{passcode_auth.bind(this)}" value="確定する"-->
          <input type="submit" class="StartCharge jsSetNumber" onclick="{netkeirin_bet.bind(this)}" value="確定する">
          <button class="ChangeBank modal-close" onclick="{closeDialog.bind(this)}">閉じる</button>
        <!--/form-->
        <p class="linkText"><a href="/regist/reset_passcode_email.html" target="_blank"><img src="{ args.cdn_url}/common/img/charge/contact.svg" alt="お問い合わせ">暗証番号が分からない場合</a></p>
      </div>
    </div>
    <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}"><span>閉じる</span></div>
  </div>
</div>

<div class="CenterModal ChargeType_A-3-2-2 jsModalContainer" if={is_passcode_lock} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
  <div class="CenterModalContent">
    <div class="ChargeTypeInner">
      <div class="ChargeBox">
        <p class="text">暗証番号をロック中です</p>
        <table class="ChargeAfterDetail">
          <tr>
            <th>解除予定</th>
            <td id="unlock_at_view">{unlock_at}</td>
          </tr>
        </table>
        <p class="linkText"><a href="/regist/support_main.html" target="_blank"><img src="{args.cdn_url}/common/img/charge/contact.svg" alt="お問い合わせ">お問い合わせ</a></p>
      </div>
    </div>
    <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}"><span>閉じる</span></div>
  </div>
</div>

<div class="CenterModal ChargeType_A-3-2-3 jsModalContainer" if={is_show_usage_limit && shoe_force_flag_popup == '0'} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
  <div class="CenterModalContent">
    <div class="ChargeTypeInner">
      <div class="ChargeBox">
        <p class="text">利用制限中</p>
        <div class="promptText">ただいま利用制限中です。</div>
        <div class="promptText2">【制限されている機能】<br><span>チャージ / 投票 / 精算</span></div>
      </div>
    </div>
    <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}"><span>閉じる</span></div>
  </div>
</div>

<div class="CenterModal ChargeType_A-3-2-3 jsModalContainer" if={vote_mode == 'netkeirin' && !is_show_usage_limit && shoe_force_flag_popup == '1'} style="display: block;">
    <div class="CenterModal-bg modal-close" onclick="{closeDialog.bind(this)}"></div>
  <div class="CenterModalContent">
    <div class="ChargeTypeInner">
      <div class="ChargeBox">
        <p class="text">投票停止中</p>
        <div class="promptText">ただいま投票停止中です。</div>
      </div>
    </div>
    <div class="CloseBtn modal-close" onclick="{closeDialog.bind(this)}"><span>閉じる</span></div>
  </div>
</div>

    <script>
     // $Id: ipat_sp.tag 436 2017-09-11 07:51:07Z ysimizu $
     "use strict"

     var self = this;
     self.args = self.opts;
     self.debug = true;
     self.param = null;
     if (self.debug) console.log('sel.args: %O', self.args);

     //self.selection_type = 2;	// 1: プルダウン,簡易表示 2: ボタン,俺プロ仕様

     // 0: 競車場選択(初期化)
     // 1: レース選択
     // 2: 式別選択(単勝,複勝...)
     // 3: 方式選択(通常,BOX,フォーメーション...)
     // 式別・方式による、車番ボタンの状態、印選択・全選択の使用可否・チェックルーチン、ラベル
     // 左から
     //   key:   1桁目: 式別  2桁目: 方式
     //   in:    軸が入力可能か否か  1: 可  0: 不可
     //   all:   印で選択、全選択ボタンが使用可能か否か 1: 可 0: 不可
     //   check: チェック関数
     //      0: なし
     //      'radio' : 単一選択(既に選択中の車番は選択解除)
     //      'nodupp': 他の軸の同一車番が選択不可
     //      'max'   : 番号の選択最大数チェック :n は引数
     //   label: 式別、方式による表題

     self.houshiki_attr = {
	     // 単勝
	     '11': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['1着','--','--']}, // 通常
	     '12': {in: [1,0,0], all: [0,0,0], check: [0,0,0], label: ['1着','--','--']}, // 通常
	     // 複勝
//	     '20': {in: [1,0,0], all: [0,0,0], check: ['radio',0,0], label: ['--','--','--']}, // 通常
	     // 枠複
	     '30': {in: [1,1,0], all: [0,0,0], check: ['radio','radio',0], label: ['枠1','枠2','--']}, // 通常
	     '31': {in: [1,1,0], all: [1,1,0], check: [0,0,0], label: ['枠1','枠2','--']},  // フォーメーション
	     '32': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
	     '33': {in: [1,1,0], all: [0,1,0], check: ['radio',0,0], label: ['軸','相手','--']},  // ながし
	     // 車連
//             '50': {in: [1,0,0], all: [0,0,0], check: ['max:2',0,0], label: ['--','--','--']}, // 通常
             '51': {in: [1,1,0], all: [1,1,0], check: [0,0,0], label: ['車1','車2','--']},  // フォーメーション
             '52': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
             '53': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['軸','相手','--']},  // ながし
	     // ワイド
             '70': {in: [1,0,0], all: [0,0,0], check: ['max:2',0,0], label: ['--','--','--']}, // 通常
             '71': {in: [1,1,0], all: [1,1,0], check: [0,0,0], label: ['車1','車2','--']},  // フォーメーション
             '72': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
             '73': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['軸','相手','--']},  // ながし
	     // 2車単
	     '60': {in: [1,1,0], all: [0,0,0], check: ['radio&nodupp','radio&nodupp',0], label: ['1着','2着','--']}, // 通常
	     '61': {in: [1,1,0], all: [1,1,0], check: [0,0,0], label: ['1着','2着','--']},  // フォーメーション
	     '62': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
	     '63': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['1着軸','相手','--']},  // 1着ながし
	     '64': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['2着軸','相手','--']},  // 2着ながし
	     // 3連複
             '80': {in: [1,1,1], all: [0,0,0], check: ['radio&nodupp','radio&nodupp','radio&nodupp'], label: ['車1','車2','車3']}, // 通常
             '81': {in: [1,1,1], all: [1,1,1], check: [0,0,0], label: ['車1','車2','車3']},   // フォーメーション
             '82': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']},  // BOX
             '83': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['軸','相手','--']},  // 軸1頭ながし
             '86': {in: [1,1,1], all: [0,0,1], check: ['radio&nodupp','radio&nodupp',0], label: ['軸1','軸2','相手']},   // 軸2頭ながし
	     // 3連単
             '90': {in: [1,1,1], all: [0,0,0], check: ['radio&nodupp','radio&nodupp','radio&nodupp'], label: ['1着 ','2着 ','3着']}, // 通常
             '91': {in: [1,1,1], all: [1,1,1], check: [0,0,0], label: ['1着 ','2着 ','3着']},   // フォーメーション
             '92': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
             '93': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['1着軸','相手','--']},  // 1着ながし
             '94': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['2着軸','相手','--']},  // 2着ながし
             '95': {in: [1,1,0], all: [0,1,0], check: ['radio&nodupp',0,0], label: ['3着軸','相手','--']},  // 3着ながし
             '96': {in: [1,1,1], all: [0,0,1], check: ['radio&nodupp','radio&nodupp'], label: ['1着軸','2着軸','相手']},   // 1,2着ながし
             '97': {in: [1,1,1], all: [0,0,1], check: ['radio&nodupp','radio&nodupp',0], label: ['1着軸','3着軸','相手']},   // 1,3着ながし
             '98': {in: [1,1,1], all: [0,0,1], check: ['radio&nodupp','radio&nodupp',0], label: ['2着軸','3着軸','相手']},   // 2,3着ながし
	     // 2枠単
	     '40': {in: [1,1,0], all: [0,0,0], check: ['radio&nodupp','radio&nodupp',0], label: ['1着','2着','--']}, // 通常
	     '41': {in: [1,1,0], all: [1,1,0], check: [0,0,0], label: ['1着','2着','--']},  // フォーメーション
	     '42': {in: [1,0,0], all: [1,0,0], check: [0,0,0], label: ['選択','--','--']}, // BOX
	     '43': {in: [1,1,0], all: [0,1,0], check: ['radio',0,0], label: ['1着軸','相手','--']},  // 1着ながし
	     '44': {in: [1,1,0], all: [0,1,0], check: ['radio',0,0], label: ['2着軸','相手','--']},  // 2着ながし

     };

     // 方式別チェック
     //  eq:1 １つのみ選択
     //  gt:1 １つ以上選択
     //  配列順は、軸に紐づく
     self.houshiki_check = {
	     // 単勝
	     '10': {chk: ['gt:1']}, // 通常
	     '11': {chk: ['gt:1']}, // 通常
	     '12': {chk: ['gt:1']}, // 通常
	     // 複勝
//	     '20': {chk: ['eq:1']}, // 通常
	     // 枠連
	     '30': {chk: ['eq:1','eq:1']}, // 通常
	     '31': {chk: ['gt:1','gt:1']}, // フォーメーション
	     '32': {chk: ['gt:2']}, // BOX
	     '33': {chk: ['eq:1','gt:1']}, // ながし
              // 2車複
	     '50': {chk: ['eq:1','eq:1']}, // 通常
	     '51': {chk: ['gt:1','gt:1']},  // フォーメーション
	     '52': {chk: ['gt:2']}, // BOX
	     '53': {chk: ['eq:1','gt:1']},  // ながし
	     // ワイド
             '70': {chk: ['eq:1','eq:1']}, // 通常
             '71': {chk: ['gt:1','gt:1']},  // フォーメーション
             '72': {chk: ['gt:2']}, // BOX
             '73': {chk: ['eq:1','gt:1']},  // ながし
	     // 2車単
	     '60': {chk: ['eq:1','eq:1']}, // 通常
	     '61': {chk: ['gt:1','gt:1']},  // フォーメーション
	     '62': {chk: ['gt:2']}, // BOX
	     '63': {chk: ['eq:1','gt:1']},  // 1着ながし
	     '64': {chk: ['eq:1','gt:1']},  // 2着ながし
	     // 3連複
             '80': {chk: ['eq:1','eq:1','eq:1']}, // 通常
             '81': {chk: ['gt:1','gt:1','gt:1']},   // フォーメーション
             '82': {chk: ['gt:3']},  // BOX
             '83': {chk: ['eq:1','gt:1']},  // 軸1頭ながし
             '86': {chk: ['eq:1','eq:1','gt:1']},   // 軸2頭ながし
	     // 3連単
             '90': {chk: ['eq:1','eq:1','eq:1']}, // 通常
             '91': {chk: ['gt:1','gt:1','gt:1']},   // フォーメーション
             '92': {chk: ['gt:3']}, // BOX
             '93': {chk: ['eq:1','gt:2']},  // 1着ながし
             '94': {chk: ['eq:1','gt:2']},  // 2着ながし
             '95': {chk: ['eq:1','gt:2']},  // 3着ながし
             '96': {chk: ['eq:1','eq:1','gt:1']},   // 1,2着ながし
             '97': {chk: ['eq:1','eq:1','gt:1']},   // 1,3着ながし
             '98': {chk: ['eq:1','eq:1','gt:1']},   // 2,3着ながし
	     // 枠単
	     '40': {chk: ['eq:1','eq:1']}, // 通常
	     '41': {chk: ['gt:1','gt:1']},  // フォーメーション
	     '42': {chk: ['gt:2']}, // BOX
	     '43': {chk: ['eq:1','gt:1']},  // 1着ながし
	     '44': {chk: ['eq:1','gt:1']},  // 2着ながし
     }

     // ボタン選択型 方式選択1
     self.houshiki_button1 = {
//	     '0': '通常',
	     '3': 'ながし',
	     '2': 'ボックス',
	     '1': 'フォーメーション',
     }
     // ボタン選択型 方式選択2
     self.houshiki_button2 = {
	     '6': { '3': '1着', '4': '2着' },
	     '8': { '3': '軸1', '6': '軸2' },
	     '9': { '3': '1着', '4': '2着','5': '3着','6': '1・2着', '7': '1・3着', '8': '2・3着' },
             '4': { '3': '1着', '4': '2着' },
     };

     // レース情報
     self.race_list = {}; // 出車表リスト
     self.cur_jyo_cd = ''; // 選択中の競車場
     //self.cur_jyo_name = ''; // 選択中の競車場名
     self.cur_race_id = ''; // 選択中のレースID
     self.cur_race_name = ''; // 選択中のレース名
     self.cur_race = {}; // 選択中のレース情報

     //
     self.shikibetu = {}; // 式別(単勝,複勝,...)
     self.cur_shikibetu = 9; // 選択中の式別
     self.select_shikibetu = {}; // 選択中の式別(複数選択対応)
     self.disp_shikibetu = {}; // 表示用の式別(ソートされている)
     self.houshiki = {}; // 方式(通常,フォーメーション,...)
     self.cur_houshiki = -1; // 選択中の方式
     self.disply_houshiki_label = {'1': 'フォーメーション', '2': 'ボックス'};
     self.data_number = [];
     self.data_number_v = [];
     self.btn_func = [];
     self.btn_func_stat = {all: [0, 0, 0], mark: [0, 0, 0]};
     self.mulit_attr = false; // マルチ(表示する/しない)
     self.mulit = false; // マルチ on,off

     self.btn_uno = {}; // 車番ボタン(選択中はtrue,falseで表現)
     self.btn_uno_disable = {}; // 選択できない車番ボタン
     self.btn_waku = {}; // 枠番ボタン(選択中はtrue,falseで表現)
     self.btn_waku_disable = {}; // 選択できない枠番ボタン

     self.max_uma = 0; // 車番(最大頭数)
     self.max_waku = 0; // 枠番(最大頭数)

     // 投票
     self.bet_money = 100; // 金額
     //self.race = {}; // 投票中のレース情報
     self.race_horse = {}; // 出走車データ
     self.waku_horse = {}; // 枠番順の出走車配列
     self.waku_list = {}; // 車番→枠番変換用

     self.bet_view = []; // 買い目、投票内容表示
     self.bet_select = {}; // 買い目、
     self.bet_select_all = false; //
     self.bet_count = {}; // 現在の買い目点数
     self.bet_odds_list = {}; //フォーメーション、流しのオッズ一覧
     self.disply_bet_view = {}; //表示用(券種ごとにまとめる)
     self.disply_bet_order = [1,9,6,8,5,4,3,7]; //['3連単','2車単','3連複','2車複','2枠単','2枠複','ワイド'];   // 順番
     self.disply_bet_label = {'1':'単勝','9':'3連単','6':'2車単','8':'3連複','5':'2車複','4':'2枠単','3':'2枠複','7':'ワイド'};
     self.isam_domain = ''; // 'ipat'+YYMMDD(開催日)
     self.isam_domain_mark = 'umark_';
     self.is_tipstar_modal = false; //tipstar遷移案内フラグ
     self.is_cahrge = false;

     self.my_mark = {};
     self.my_mark_label = {'0':'--','1':'◎','2':'○','3':'▲','4':'△','5':'☆','6':'注','98':'✓','99':'消'};

     self.total_bet_money = 0;
     self.odds = {}; // オッズデータ
     self.ijyo_waku_list = {};
     self.ijyo_list = {};
     self.select_bet_odds = {}; //選択中のオッズ
     self.select_max_odds = {};
     self.select_min_odds = {};

     self.is_odds_open = {}; //買い目一覧のオッズ表示
     self.select_odds_sort_mode = 'asc';
     self.is_edit = false; //買い目一覧の削除モード
     self.select_kaime = {}; //買い目一覧の組み合わせ選択
     self.select_odds = {};
     self.odds_update_timer = false;
     self.is_charge = false;
     self.show_regist = false;
     self.iframe_url = '';
     self.ts_data = {};
     self.device = self.args.device ? self.args.device : 1;
     self.is_active_button = false;
     if (self.debug) console.log('is_active_button <- false');
     self.distribution_mode = 'bet';
     self.distribution_title = '';
     self.vote_mode = self.args.vote_mode;
     self.is_ekyc = false;
     self.is_ban_user = false; // 利用停止ユーザ
     self.is_show_usage_limit = false; // 利用制限中の表示
     self.point = 0;
     self.is_vote_error = false;
     self.is_money_limit_error = false; // マネー投票の金額制限エラー
     self.is_voting = false;
     self.vote_money = 0;
     self.is_pist6_error = false;
     self.is_passcode_form = false;
     self.passcode = '';
     self.is_passcode_lock = false
     self.unlock_at = '';
     self.is_passcode_error = false;
     self.shoe_force_flag_popup = '0'; // 強制投票停止フラグ用のポップアップ表示フラグ
     self.show_bet_buttom = true; // 投票ボタンの表示フラグ
     self.vote_setting = {};
     self.on('update', function() {
         //	     console.error('self.update()');
     });
     self.on('updated', function() {
         //	     console.error('self.updated()');
     });


     // 下記、edit_xxxxx関数は、HTMLテンプレートのレンダリング時(riot=update)に動作する

     //--------------------------------------------------
     edit_kaime_label( s, h, line_no )
     {
	     var id = sprintf("%1d%1d", s,h);
	     if(undefined !== self.houshiki_attr[id]){
	         return self.houshiki_attr[id]['label'][line_no];
	     }
	     return '';
     }

     //--------------------------------------------------
     edit_combination( comb, s, h )
     {
	     var val = comb.split(/-/);
	     var ret = [];
	     for(var i=0; i < val.length; i++){
	         var row = {};
	         row['no'] = parseInt(val[i]);	// '0'サプレス
	         if(6 == s || 9 == s){	// 車単、３連単
		         row['type'] = 2;	// 車番の間(矢印)
	         }else{
		         row['type'] = 1;	// 車番の間(ハイフン)
	         }
	         if(i == val.length - 1){
		         row['type'] = -1;
	         }
	         ret.push( row );
	     }
	     //	 console.error('s:%s h: %s ret: %O',s,h,ret);
	     return ret;
     }

     //--------------------------------------------------
     number_format(num)
     {
        if(typeof num !== 'number') {
            return num; // 数値以外はそのまま返す
        }
        return num.toString().replace(/(\d+?)(?=(?:\d{3})+$)/g, function(x) {
            return x + ',';
        });
     }
     replace_newline_br(string)
     {
        return string.replace(/\n/g, '<br>');
     }


    /*
        * 特定の順番にソートしてから、keyと値を反転させる
        *      ※どうやら、jsは数値文字列indexだけだと、ブラウザで勝手に数値の昇順にソートすると思われる。
    */
    disp_sorted_shikibetsu()
    {

        if (!self.shikibetu) return false;

        const order = ['3連単','2車単','3連複','2車複','2枠単','2枠複','ワイド','単勝'];   // 順番
        var sorted_shikibetsu = Object.entries(self.shikibetu).sort(function(a, b){ return order.indexOf(a[1]) - order.indexOf(b[1]) });
        var flip_shikibetsu = {};
        for (var [key, value] of sorted_shikibetsu) {
            flip_shikibetsu[value] = key;
        }

        return flip_shikibetsu;
     }

    edit_ary_maxmin(arr, mode)
    {
        if(mode == 'max'){
            var ret = arr.reduce(function(a, b) {
                return Math.max(a, b);
            });
        }else{
            var ret = arr.reduce(function(a, b) {
                return Math.min(a, b);
            });
        }
        return sprintf("%0.1f", ret);
    }

    edit_payment_diff(payback, total)
    {
        if((payback - total) < 0){
            return 'minus';
        }else{
            return 'plus';
        }
    }

    //--------------------------------------------------
    edit_kaime_class(shikibetu)
    {
        if(4 == shikibetu || 6 == shikibetu || 9 == shikibetu){	// 枠単,2車単,３連単
            // 馬番の間(矢印)
            return 'Kaime_Arrow'
        }else{
            // 馬番の間(ハイフン)
            return 'Hyphen';
        }
    }

    //--------------------------------------------------
    edit_kaime_mark(mark, upper, shikibetu)
    {
        //if(shikibetu == 3 || shikibetu == 4){
        //    return '';
        //}
        var mark_list = {
             1: 'honmei',
             2: 'taikou',
             3: 'kurosan',
             4: 'shirosan',
             5: 'hoshi',
             98: 'check',
             99: 'keshi'
        }
        if(mark_list[mark]){
            if(upper){
                return mark_list[mark].substring(0, 1).toUpperCase() + mark_list[mark].substring(1);
            }else{
                return mark_list[mark];
            }
        }else{
            return '';
        }
    }

     edit_check_bet_money(bet_money)
     {
          if(bet_money < 0){
              return '';
          }else{
              return bet_money / 100;
          }
     }

    edit_bet_count_all()
    {
        var bet_count_all = 0;
        for(var i = 0; i < self.bet_view.length; i++){
            if(self.bet_view[i]['comb']){
                bet_count_all += self.bet_view[i]['comb'].length;
            }else{
                bet_count_all += 1;
            }
        }
        console.log(bet_count_all);
        return bet_count_all;
    }

    is_bet_disable(){
        console.log('is_bet_disable');
        var now = new Date();
        var year = self.cur_race_id.substr(0, 4);
        var month = self.cur_race_id.substr(4, 2);
        var day = self.cur_race_id.substr(6, 2);
        var time = self.cur_race['close'].split(':');
        var endtime = new Date(year,month - 1,day,time[0],time[1]);
        var race_date = new Date(year,month - 1,day);
        console.log('now : ', now);
        console.log('endtime : ', endtime);
        if(!self.cur_race['sale_status'] || self.cur_race['sale_status'] <= 0){
            // 無効
            return true;
        }
        if(now.getTime() >= endtime.getTime()){
            // 無効
            return true;
        }
        if(self.is_active_button && self.args.sns_user_id != '' && self.is_ekyc && self.point >= self.total_bet_money && self.is_ban_user == false && self.cur_race['force_flag'] != '1'){
            // 有効
            return false;
        }else{
            // 無効
            return true;
        }
    }

    changeBetMode(vote_mode)
    {
        if(vote_mode == 'netkeirin' || vote_mode == 'TIPSTAR'){
            const now = new Date();
            now.setDate(now.getFullYear() + 1);
            document.cookie = "vote_mode=" + vote_mode + "; path=/; expires=" + now.toUTCString() + "; domain=" + self.args.cookie_domain;
            self.vote_mode = vote_mode;
            self.args.obs.trigger('change_vote_mode_event', vote_mode);
            self.update();
        }
    }

    act_select_input(show_flg)
    {
        console.log('act_select_input : ', show_flg);
        self.show_bet_buttom = show_flg;
    }

    // モーダルの閉じる
    closeDialog()
    {
        console.log('closeDialog');
        if(self.is_vote_error) {
            self.is_vote_error = false;
        }
        if(self.is_pist6_error) {
            self.is_pist6_error = false;
        }

        if(self.is_passcode_lock) {
            self.is_passcode_lock = false;
        }
        if(self.is_passcode_form) {
            self.is_passcode_form = false;
        }
        if(self.is_show_usage_limit) {
            self.is_show_usage_limit = false;
        }
        if(self.shoe_force_flag_popup == '1') {
            self.shoe_force_flag_popup = '0';
        }
        if(self.is_money_limit_error) {
            self.is_money_limit_error = false;
        }

        self.is_passcode_error = false;
        self.update();
    }

    /*
      * 画面初期化(mount)
      */
     self.on('mount', function() {
	     if (self.debug)  console.log('mount %s', self.args.tag_name);
	     self.args.obs.trigger('tag_mounted', {tag: self.args.tag_name});
     });

    shared_obs.on('tipstar_send_flg', function(e) {
        console.log('tipstar_send_flg : ', e);
        if(e == 'true'){
            self.is_active_button = true;
        }else if(e == 'false'){
            self.is_active_button = false;
            console.log('is_active_button <- false');
        }
        self.update();
    });

    shared_obs.on('change_vote_mode', function(e) {
        console.log('change_vote_mode : ', e);
        self.vote_mode = e;
        if(e == 'netkeirin'){
            self.get_pasonal_data(function(){
                self.update();
                //render完了の通知をnarabi_yosoに通知(ipat_sp_v2 → editor.html → narabi_yoso)
                self.args.obs.trigger('ipat_sp_render_comp');
                self.list_mark_check();
            });
        }else{
            self.http_tipstar_api(self.cur_race_id, function(ret){
                self.ts_data = ret;
                self.is_active_button = true;
                if (self.debug) console.log('is_active_button <- true');
                self.get_ekyc_statue(function(){
                    self.update();
                    //render完了の通知をnarabi_yosoに通知(ipat_sp_v2 → editor.html → narabi_yoso)
                    self.args.obs.trigger('ipat_sp_render_comp');
                    self.list_mark_check();
                });
            });
        }
    });

    shared_obs.on('update_points', function(e) {
        console.log('bet_list update_points : ', e);
        self.point = e;
        self.update();
    });


     /*
      * 画面表示(parent -> trigger -> render_xxxx)
      */
     self.args.obs.on('render_' + self.args.tag_name, function(p) {
	     if (self.debug) console.log('render_%s start p: %O', self.args.tag_name, p);
	     self.param = p;

	     // 各種、初期化
	     self.race_list = {}; // 出車表リスト
	     self.cur_jyo_cd = ''; // 選択中の競車場
	     //self.cur_jyo_name = ''; // 選択中の競車場名
	     self.cur_race_id = ''; // 選択中のレースID
	     self.cur_race_name = ''; // 選択中のレース名
	     self.cur_race = {}; // 選択中のレース情報
	     self.cur_shikibetu = 9; // 選択中の式別
	     self.cur_houshiki = -1; // 選択中の方式
	     self.bet_view = [];
	     self.active_syaban = []; //選択可能車番
	     self.active_wakuban = []; //選択可能枠番

	     self.event_id = 'no_set';
	     var event_id_list = {
	         'race' : true,
	         'bet_btn' : true,
	         'odds' : true,
	         'myodds' : true
	     };
	     if(event_id_list[p['rf']]){
	     	self.event_id = p['rf'];
	     }
         //オッズのアップデート停止
         if(self.odds_update_timer){
         	console.log('clearInterval');
             clearInterval(self.odds_update_timer);
         }

	     self.show_data(p);
     });

     // 行・列変換
     var transpose = function(a) {
	     return Object.keys(a[0]).map(function(c) {
	         return a.map(function(r) {
		         return r[c];
	         });
	     });
     }

     /*
      * データ取得、編集
      *  URLパラメータ date   : 日時(必須)
      *                race_id: レースID(省略可)
      *                         レースID指定時は、競車場、 レース番号が選択状態
      *                         レースID省略時は、競車場、 レース番号が未選択状態
      */
     self.show_data = function(p) {
	     if (self.debug) console.log('self.show_data');

	     if (self.debug) console.log('is_active_button <- false');
         self.is_active_button = false;
	     self.kaisai_mode = 'keirin';
	     if(p['race_id'] !== undefined && p['race_id'].substr(8, 2) == '91'){
	         self.kaisai_mode = 'pist6';
	     }
         // 買い目一覧では並び予想は非表示
         self.args.obs.trigger('narabi_show_event', 'hide');
	     var ipat = new IpatDataModel();
	     self.shikibetu = ipat.get_shikibetu();
         if(self.kaisai_mode == 'keirin'){
             //単勝削除
             delete self.shikibetu[1];
         }else{
             //pist6の時は枠系削除
             delete self.shikibetu[3];
             delete self.shikibetu[4];
         }
         self.disp_shikibetu = self.disp_sorted_shikibetsu();

        // 全選択・クリア、印で選択を初期化
        self.select_shikibetu = {};
        //self.select_shikibetu[self.cur_shikibetu] = true;
        self.btn_func_stat = {all: [0, 0, 0], mark: [0, 0, 0]};
        self.btn_uno = {};
        self.btn_waku = {};
        self.select_bet_odds = {};
        self.select_kaime = {};
        self.select_odds = {};

	     var tmp_h = ipat.get_houshiki();
	     self.houshiki = {};
	     for (var key in tmp_h) {
	         var s = key.substr(0, 1);
	         var h = key.substr(1, 1);
	         if (undefined === self.houshiki[s]) {
		         self.houshiki[s] = {};
	         }
	         self.houshiki[s][h] = tmp_h[key];
	     }

	     var api = new AplApiRace(self.args.api_url, true, 'json'/*, true*/);

	     var year = '';
	     if (undefined !== p['date']) {
	         year = p['date'].substr(0, 4);
	     } else {
	         console.error("empty parameter 'date'");
	         return false;
	     }
	     var date = p['date'];

	     self.isam_domain = sprintf("bet_%s", p['race_id']);
	     if (self.debug) console.log('self.isam_domain: %s', self.isam_domain);

         // レース一覧を取得
         api.get('AplRace', {'kaisai_date': date, 'syusai': 'all'}, function(ary_race) {
//         api.get('AplRace', {'kaisai_date': date, 'syusai': self.kaisai_mode}, function(ary_race) {
	         var selected_race = {};
	         for (var i = 0; i < ary_race.length; i++) {
	             self.race_list[ary_race[i].jyo_cd] = ary_race[i].list;

	             if (undefined !== p['race_id']) {
		             for (var idx in ary_race[i].list) {
		                 var row = ary_race[i].list[idx];
		                 if (row['race_id'] == p['race_id']) {
			                 selected_race = row;
		                 }
		             }
	             }
	         }
	         if (self.debug) console.log('self.race_list: %O', self.race_list);

	         if (undefined !== p['race_id']) {
	             // race_id 指定あり、選択状態を再現
	             if (self.debug) console.log('selected_race: %O', selected_race);

	             // 競車場
	             self.act_jyo(selected_race['jyo_cd'], selected_race['jyo']);
	             // レース番号
	             self.act_race(selected_race['race_id'], selected_race['race_name'], selected_race['jyoken']);
	         } else {
	             self.update();
                 //self.args.obs.trigger('render_comp');
	         }
         });

     }

     /*
      * 印を取得(local stolage)
      */
    self.get_shutuba_mark = function(race_id, fn) {
        if (self.debug) console.log('self.get_shutuba_mark(%s)', race_id);

        var cart = new NDCartApi(self.args.cart_url, 'json');
        var group_id = sprintf("SensyuMark_%s", race_id);

        // リスト取得
        cart.get_item_list(group_id, function(data) {
            if ('OK' == data.status) {
            var mark = {};
            // 出馬表の印は、馬番でなく通番
            for (var seq in data.data) {
                var val = data.data[seq]['_cd'].split(/_/);
                if ('0' == val[1])
                continue; // 印を消してもカートに存在
                mark[seq] = val[1];
            }
            self.my_mark = mark;
            if (self.debug) console.log('self.my_mark: %O', self.my_mark);
                    if(undefined !== fn){
                        fn();
                    }
            }
        });

     }

     /*
      * レースデータ切替え
      */
     self.change_race_horse = function(race_id, fn) {
	     if (self.debug) console.log('self.change_race_horse(%s)', race_id);

	     var api = new AplApiRace(self.args.api_url, true, 'json'/*, true*/);

	     // 出走車情報取得
	     api.get('AplRaceHorse', {'race_id': race_id}, function(data) {
                 if (self.debug) console.log('=============AplRaceHorse=============');
                 if (self.debug) console.log(data);
             var rh = {};
	         for (var i = 0; i < data.length; i++) {
		         if ('' == data[i]['syaban']) {
		             alert('出車表に車番がない');
		         }
		         rh[data[i]['syaban']] = data[i];
	         }
	         self.race_horse = rh;
	         if (self.debug) console.log('self.race_horse: %O', self.race_horse);

	         var ary_waku = {};
	         var tmp_active_waku_list = {};
	         for (var u in self.race_horse) {
		         var w = self.race_horse[u]['wakuban'];
		         if (undefined === ary_waku[w]) {
		             ary_waku[w] = {};
		         }
		         ary_waku[w][self.race_horse[u]['syaban']] = {
//		             seq: self.race_horse[u]['seq'],
		             syaban: self.race_horse[u]['syaban'],
		             name: self.race_horse[u]['name'],
		             sales_sts: self.race_horse[u]['sales_sts'],
		             fuken: self.race_horse[u]['fuken'],
		             age: self.race_horse[u]['age'],
		             graduate: self.race_horse[u]['graduate'],
		             kyu: self.race_horse[u]['kyu'],
		             han: self.race_horse[u]['han'],
		             rating: self.race_horse[u]['rating']
		         };
		         if(self.race_horse[u]['sales_sts'] == '1' || self.race_horse[u]['sales_sts'] == '3'){
		             self.ijyo_list[self.race_horse[u]['syaban']] = true;
                     if(self.ijyo_waku_list[w] === undefined){
                         self.ijyo_waku_list[w] = {};
                     }
                     self.ijyo_waku_list[w][self.race_horse[u]['syaban']] = true;
		         }else{
		             self.active_syaban.push(self.race_horse[u]['syaban']);
		             tmp_active_waku_list[w] = true;
		         }
		         self.waku_list[self.race_horse[u]['syaban']] = w;
	         }
		     self.active_wakuban = Object.keys(tmp_active_waku_list);

	         self.waku_horse = ary_waku;

	         // 最大車番を求める
	         self.max_waku = Object.keys(self.waku_horse).length;
	         if(self.debug) console.log('self.max_waku: %s',self.max_waku);
	         if (self.debug) console.log('self.waku_horse: %O', self.waku_horse);
	         fn();
	     });
     }

     /*
      * 車番ボタンリセット
      *  line: 対象となる行 (-1は、全て)
      */
     self.reset_uno = function(line, mode) {
	     if (self.debug) console.log('self.reset_uno(%s,%s)', line, mode);

	     //self.btn_uno = {};
	     for (var i = 0; i < 3; i++) {
	         if (line < 0 || (line >= 0 && i == line)) {
		         self.btn_uno_disable[i] = {};
	         }
	         for (var j = 0; j <= self.max_uma; j++) {
		         if (1 == mode) {
		             // 1: 全てをenable
		             self.btn_uno_disable[i][j] = false;
		         } else {
		             // 0: 全てをdiasble
		             self.btn_uno_disable[i][j] = true;
		         }
	         }
	     }
     }

     /*
      * 競車場選択
      */
     self.act_jyo = function(jyo_cd, jyo_name) {
	     if (self.debug) console.log('self.act_jyo(%s,%s)', jyo_cd, jyo_name);

	     self.cur_jyo_cd = jyo_cd;
	     //self.cur_jyo_name = jyo_name;

	     self.cur_race_id = ''; // レース選択クリア
	     self.cur_race_name = '';
     }

     /*
      * レース番号選択
      */
     self.act_race = function(race_id, race_name, jyoken, ev) {
	     if (self.debug) console.log('self.act_race(%s,%s,%s)', race_id, race_name, jyoken);

	     if (undefined !== ev) {
	         console.log('self.act_race :%O', ev);
	     }

	     if (undefined !== ev)
	         ev.preventUpdate = true;

	     // !! ここ重要 メニュー選択した段階では、riot update()しない 出走車データ取得(非同期)が完了してから、ev.preventUpdate = false でriot update()する でないと配列(self.race_horse)が完成していないので、不定となる。

	     self.cur_shikibetu = -1; // 式別クリア
	     self.cur_houshiki = -1; // 方式クリア

	     self.cur_race_id = race_id;
	     self.cur_race_name = ('' != race_name) ? race_name : jyoken;

	     for (var key in self.race_list[self.cur_jyo_cd]) {
	         var row = self.race_list[self.cur_jyo_cd][key];
	         if (race_id == row['race_id']) {
		         self.cur_race = self.race_list[self.cur_jyo_cd][key];
	         }
	     }
         self.shoe_force_flag_popup = self.cur_race['force_flag'];
	     self.max_uma = self.cur_race['tosu'];
        if(self.cur_race['jyo_cd'] >= '90'){
            self.max_uma = Object.keys(self.race_horse).length;
        }

         //         console.error('self.cur_race',self.cur_race);
         //         console.error('self.max_uma',self.max_uma);

	     self.data_number = []; // 車番作成
	     for (var i = 0; i < 3; i++) {
	         self.data_number[i] = [];
	         for (var j = 1; j <= self.max_uma; j++) {
		         self.data_number[i][j] = true;
	         }
	     }
	     self.data_number_v = transpose(self.data_number);

	     if (self.debug) console.log('self.cur_race: %O', self.cur_race);
	     if (self.debug) console.log('self.max_uma: %s', self.max_uma);

	     var ipat = new IpatDataModel();
	     self.shikibetu = ipat.get_shikibetu();
         if(self.kaisai_mode == 'keirin'){
             //単勝削除
             delete self.shikibetu[1];
         }else{
             //pist6の時は枠系削除
             delete self.shikibetu[3];
             delete self.shikibetu[4];
         }
         self.disp_shikibetu = self.disp_sorted_shikibetsu();
	     self.change_race_horse(race_id, function() {
         if (undefined !== ev)
	         ev.preventUpdate = false;

	         var api = new AplApiRace(self.args.api_url, true, 'json'/*, true*/);

	         // オッズ取得
	         api.get('AplRaceOdds', {'race_id': race_id}, function(odds_data) {
                     if (self.debug) console.log('=============AplRaceOdds=============');
                     if (self.debug) console.log(odds_data);

		         for (var i = 1; i <= 9; i++) {
		             self.odds[i] = {};
		             if (undefined === odds_data['list_' + i]) {
			             continue;
		             }
		             for(var j = 0; j < odds_data['list_' + i].length; j++) {
			             var oval = odds_data['list_' + i][j];
			             self.odds[i][oval[0]] = [oval[1], oval[2], oval[3]];
		             }
		         }

		         //	     console.error('self.odds: %O',self.odds);
		         if (self.debug) console.log('self.odds: %O', self.odds);
		         self.render_bet_list();
		         if(self.args.odds_update){
					//self.odds_auto_update();
		         }
                 // フッターの状態更新update_tags
                 self.args.obs.trigger('update_tag', {'update_tag_name': 'footer_fixed'}, query);

                 self.get_shutuba_mark(self.cur_race_id, function(){
                    if(self.vote_mode == 'netkeirin'){
                        //ボタンを有効にする(html上は無効)
                        self.is_active_button = true;
                	    if (self.debug) console.log('is_active_button <- true');
                        self.get_pasonal_data(function(){
                            // 先に表示させる
                            self.update();
                            //render完了の通知をnarabi_yosoに通知(ipat_sp_v2 → editor.html → narabi_yoso)
                            self.args.obs.trigger('ipat_sp_render_comp');
                            self.list_mark_check();
                            self.get_votes_money(self.cur_race_id, function(vote_money){
                                self.vote_money = vote_money;
                                self.update();
                                //render完了の通知をnarabi_yosoに通知(ipat_sp_v2 → editor.html → narabi_yoso)
                                self.args.obs.trigger('ipat_sp_render_comp');
                                self.list_mark_check();
                            });
                        });
                    }else{
                        self.http_tipstar_api(self.cur_race_id, function(ret){
                            self.ts_data = ret;
                            self.is_active_button = true;
                            if (self.debug) console.log('is_active_button <- true');
                            self.get_ekyc_statue(function(){
                                self.update();
                                //render完了の通知をnarabi_yosoに通知(ipat_sp_v2 → editor.html → narabi_yoso)
                                self.args.obs.trigger('ipat_sp_render_comp');
                                self.list_mark_check();
                            });
                        });
                    }
                 });
	         });
	     });
     }

     //------------------------------------------------------------
     self.make_bet = function( bet_money, shikibetu )
     {
	     if(self.debug) console.log('self.make_bet(%s)',bet_money);

	     if (bet_money < 0) {
	         // 金額が未入力、あるいは正しくありません
	         return -1;
	     }
	     var btn_uno = self.btn_uno;
	     if(shikibetu == 3 || shikibetu == 4){
	         btn_uno = self.btn_waku;
	     }

	     var ukey = Object.keys(btn_uno);
	     if(ukey.length < 1){
	         //	車番が正しく、選択されていません(未選択)
	         return -2;
	     }

	     if(shikibetu <= 0){
	     	return -2;
	     }

	     var err = self.check_umaban_selection(shikibetu);
	     if (err) {
	         //	車番が正しく、選択されていません
	         return -2;
	     }

	     var kaime = [];
	     var kaime_id = '';

	     // 選択中の車番ボタンから買い目を作成

	     for (var i in btn_uno) {
	         var row = btn_uno[i];
	         var k = [];
	         for (var uno in row) {
		         if (true == row[uno]) {
		             k.push(uno);
		         }
	         }
	         if (k.length < 1) {

	         } else if (k.length > 1) {
		         if ('0' == self.cur_houshiki) {
		             kaime.push(k.join('_'));
		         } else {
		             kaime.push(k.join('-'));
		         }
	         } else {
		         kaime.push(k);
	         }
	     }
	     if('3' == shikibetu && '0' == self.cur_houshiki){
	         var w_chk = {};
	         for (var w in self.waku_horse) {
		         var num = Object.keys(self.waku_horse[w]).length;
		         if (num > 1) {
		             w_chk[w] = true;
		         }
	         }
	         var w1 = kaime[0][0] || 0;
	         var w2 = kaime[1][0] || 0;
	         //	     console.error('w_chk: ',w_chk);
	         //	     console.error('w1: %s w2: %s',w1,w2);
	         if(w1 == w2){
		         if(! w_chk[w1] || ! w_chk[w2]){
		             return -2;
		         }
	         }
	     }
console.log('kaime: %O', kaime);
	     if (kaime.length > 1) {
	         kaime_id = kaime.join('_');
	     } else {
	         kaime_id = kaime.join('');
	     }


        //単複多点買対応(単複で買目が複数ある場合はkaime_id作り直し)
        var tanpuku_multi = [];
        if(kaime[0].length > 1){
            tanpuku_multi = kaime_id.split(',');
        }

	     // 17.12.3 枠連、３連複の通常買いが車番の昇順でない件
	     if( ('3' == shikibetu || '7' == self.cur_shikibetu)
	      && '0' == self.cur_houshiki ){
	         var val = kaime_id.split(/_/);
	         val.sort(function(a,b){
		         if( parseInt(a) < parseInt(b) ) return -1;
		         if( parseInt(a) > parseInt(b) ) return 1;
		         return 0;
	         });
	         kaime_id = val.join('_');
	         //	     console.error('kaime_id: %O',kaime_id);
	     }

	     // マルチ
	     if (self.multi) {
	         kaime_id += '_1';
	     }
	     if (self.debug) console.log('kaime: %O kaime_id: %s', kaime, kaime_id);

	     // 買い目コード作成
	     var year = self.cur_race_id.substr(0, 4);
	     var month = self.cur_race_id.substr(4, 2);
	     var day = self.cur_race_id.substr(6, 2);
	     var date = new Date(year, month - 1 , day);
	     var youbi_cd = date.getDay();
	     var jyo_cd = self.cur_race_id.substr(8, 2);

	     var race_no = parseInt(self.cur_race_id.substr(10, 2));
	     var houshiki = self.cur_houshiki;
	     //if(shikibetu == 1){
	     //	//単勝選択時は通常扱いにする
	     //	houshiki = 0;
	     //}
	     var bet_id = sprintf("a%1s-%1s-%1s_b%1s_c%s_%s", youbi_cd, jyo_cd, race_no, shikibetu, houshiki, kaime_id);
	     var bet_info =  self.bet_gen(bet_id, bet_money);
	     bet_info['open'] = 0;
	     return bet_info;
     }

     /*
      * 金額入力
      */
     self.act_input_money = function(ev) {
	     if (self.debug) console.log('self.act_input_money(%s)', ev.target.value);
	     self.bet_money = ev.target.value * 100;
     }

     /*
      * 買い目一覧表示
      */
     self.render_bet_list = function() {
	     if (self.debug) console.log('self.render_bet_list');

	     self.bet_view = [];
	     self.total_bet_money = 0;
	     self.bet_odds_list = [];
	     self.disply_bet_view = {};
	     // 買い目取得(local)
	     var ndisam = new NDIsam();
	     var list = ndisam.list(self.isam_domain);
	     if(false === list){
	         console.error('isam empty..');
	         return;
	     }

	     for (var bet_no in list) {
	         var bet_info = self.bet_gen(list[bet_no]['bet_id'], list[bet_no]['bet_money']);
	         // オッズ配当計算
	         if ('0' == bet_info['houshiki']) {
		         // 通常(バラ買い)
		         var key = '';
		         if ('1' == bet_info['shikibetu'] || '2' == bet_info['shikibetu']) {
		             key = sprintf("%02d", bet_info['kaime1']);
		         } else if ('3' == bet_info['shikibetu'] || '4' == bet_info['shikibetu'] || '5' == bet_info['shikibetu'] || '6' == bet_info['shikibetu'] || '7' == bet_info['shikibetu']) {
		             key = sprintf("%02d%02d", bet_info['kaime1'], bet_info['kaime2']);
		         } else if ('8' == bet_info['shikibetu'] || '9' == bet_info['shikibetu']) {
		             key = sprintf("%02d%02d%02d", bet_info['kaime1'], bet_info['kaime2'], bet_info['kaime3']);
		         }
		         var payback = 0;
		         if (undefined === self.odds[bet_info['shikibetu']]){
		             if(self.debug) console.error('empty odds shikibetu: %s',bet_info['shikibetu']);
		         }else if (undefined === self.odds[bet_info['shikibetu']][key]){
		             if(self.debug) console.error('unkown key : %s', key);
		             payback = 0;
		         } else {
		             var payback = self.odds[bet_info['shikibetu']][key][0] * bet_info['bet_money'];
		             payback = Math.round(payback);
		             if(self.bet_odds_list[bet_info['bet_id']] === undefined){
		                 self.bet_odds_list[bet_info['bet_id']] = [];
		             }
		             self.bet_odds_list[bet_info['bet_id']].push(self.odds[bet_info['shikibetu']][key][0]);
		         }
		         bet_info['payback'] = payback;
	         } else {
		         // 以外(組合せ買い)
		         bet_info['payback'] = [];
		         bet_info['comb_odds'] = [];
		         for (var i = 0; i < bet_info['comb'].length; i++) {
		             var val = bet_info['comb'][i].split(/-/);
		             var comb_odds = '';
		             var key = '';
		             for (var j = 0; j < val.length; j++) {
			             key += sprintf("%02d", val[j]);
		             }
		             if (undefined === self.odds[bet_info['shikibetu']]){
			             if(self.debug) console.error('empty odds shikibetu: %s',bet_info['shikibetu']);
		             }else if(undefined === self.odds[bet_info['shikibetu']][key]){
			             if(self.debug) console.error('unkown key : %s', key);
			             payback = 0;
			             comb_odds = '0.0';
		             } else {
			             payback = self.odds[bet_info['shikibetu']][key][0] * bet_info['bet_money'];
			             payback = Math.round(payback);
			             comb_odds = self.odds[bet_info['shikibetu']][key][0];
			             if(self.bet_odds_list[bet_info['bet_id']] === undefined){
			                 self.bet_odds_list[bet_info['bet_id']] = [];
			             }
			             self.bet_odds_list[bet_info['bet_id']].push(self.odds[bet_info['shikibetu']][key][0]);
		             }
		             //if (self.debug) console.log('payback: %s:', payback);
		             bet_info['payback'].push(payback);
			         bet_info['comb_odds'].push(comb_odds);
		         }
	         }
	         bet_info['bet_no'] = bet_no;
	         bet_info['open'] = 0;
	         self.bet_view.push(bet_info);
	         self.disply_bet_view = self.make_bet_view_obj();
	         // 総合計金額
	         self.total_bet_money += parseInt(bet_info['bet_money_total']);
	     }
        // フッターの状態更新update_tags
        self.args.obs.trigger('update_tag', {'update_tag_name': 'footer_fixed'}, query);

	     if (self.debug) console.log('self.total_bet_money: %s', self.total_bet_money);
	     if (self.debug) console.log('self.bet_view: %O', self.bet_view);
	     if (self.debug) console.log('self.bet_odds_list: %O', self.bet_odds_list);
     }

     /*
      * 式別・方式別の車番選択、妥当性チェック
      */
     self.check_umaban_selection = function(shikibetu) {
	     if (self.debug) console.log('self.check_umaban_selection');

	     var umaban_num = [0, 0, 0];
	     // 選択中の車番ボタンを行毎にカウント
	     for (var i in self.btn_uno) {
	         var row = self.btn_uno[i];
	         for (var uno in row) {
		         if (true == row[uno]) {
		             umaban_num[i]++;
		         }
	         }
	     }
	     var key = sprintf("%1d%1d", shikibetu, self.cur_houshiki);

	     if (self.debug) console.log('umaban_num: %O', umaban_num);
	     if (self.debug) console.log('key: %s', key);

	     var ary_rule = self.houshiki_check[key]['chk'];
	     //	 console.error('ary_rule: %O',ary_rule);
	     var err = false;
	     for (var i = 0; i < ary_rule.length; i++) {
	         var r = ary_rule[i].split(/:/);
	         // r[0] = ルール  'eq:1' １つのみ                'gt:1' １つ以上
	         if ('eq' == r[0]) {
		         if (umaban_num[i] != r[1]) {
		             err = true;
		         }
	         } else if ('gt' == r[0]) {
		         if (umaban_num[i] < r[1]) {
		             err = true;
		         }
	         }
	     }

	     if (self.debug) console.log('err: %s', err);
	     return err;
     }


    self.set_bet = function(odds_flg){
        console.log('self.set_bet', self.select_kaime);
        for(var shikibetu in self.select_shikibetu){
            if(!odds_flg && !self.select_kaime[shikibetu]){
                continue;
            }
            var bet_info = self.make_bet(self.bet_money, shikibetu);
            if(-1 == bet_info){
                self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
                return false;
            }else if(-2 == bet_info){
                //self.err_info_swal('車番が正しく、選択されていません。', false);
                //return false;
            }
            if(bet_info['bet_count'] < 1){
                self.err_info_swal('組み合わせがありません。', false);
                return false;
            }else{
                if (bet_info['bet_money'] <= 0) {
                    self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
                    return false;
                }
            }
            if(bet_info != -2){
                var ndisam = new NDIsam();
                // 投票管理番号を生成 (キーは現在時刻、ミリ秒まで)
                var bet_no = sprintf("%s_%s_%s",self.cur_race_id,CybozuLabs.MD5.calc(Date.now()),self.set_bet_count);
                self.set_bet_count++;
                bet_info['bet_no'] = bet_no;
                var ret = ndisam.replace(self.isam_domain, bet_no, {
                    bet_id: bet_info['bet_id'],
                    bet_money: self.bet_money
                });
                if(ret){
                    self.bet_view.push(bet_info);
                }
            }
        }
    }

     //------------------------------------------------------------
     self.bet_gen = function(bet_id, bet_money) {
	     if (self.debug) console.log('self.bet_gen(%s,%s)', bet_id, bet_money)

	     if(undefined === bet_id){
	         return {};
	     }

	     var part = bet_id.split(/_/);
	     var s = part[1].substr(1, 1);
	     var h = part[1].substr(1, 1) + part[2].substr(1, 1);

	     var ipat = new IpatDataModel();
	     var info = [];
	     var waku_check = []; // 枠連の場合は、複数頭の枠番号を配列で渡す

	     for (var w in self.waku_horse) {
	         var num = Object.keys(self.waku_horse[w]).length;
	         if (num > 1) {
	         	for(var key in self.waku_horse[w]){
	         		var ijyo_check = false;
	         		if(self.waku_horse[w][key]['sales_sts'] == '1' || self.waku_horse[w][key]['sales_sts'] == '3'){
	         			ijyo_check = true;
	         			break;
	         		}
	         	}
	         	if(!ijyo_check){
		         	waku_check.push(w);
	         	}
	         }
	     }
	     if (self.debug) console.log('waku_check: %O',waku_check);
	     info = ipat.cvt_bet(bet_id, bet_money, waku_check);
	     // 競車場、レース番号
	     var p = part[0].split(/-/);
	     var ary_jyo = {
	         1: '札幌',
	         2: '函館',
	         3: '福島',
	         4: '新潟',
	         5: '東京',
	         6: '中山',
	         7: '中京',
	         8: '京都',
	         9: '阪神',
	         a: '小倉'
	     };
	     info['race_name'] = sprintf("%s %02dR", ary_jyo[p[1]], p[2]);

	     if ('0' == h.substr(1, 1)) {
	         var str = '';
	         if ('1' == info['shikibetu'] || '2' == info['shikibetu']) {
		         str = sprintf("%d", info['kaime1']);
	         } else if ('3' == info['shikibetu'] || '4' == info['shikibetu'] || '5' == info['shikibetu'] || '6' == info['shikibetu'] || '7' == info['shikibetu']) {
		         str = sprintf("%d-%d", info['kaime1'], info['kaime2']);
	         } else if ('8' == info['shikibetu'] || '9' == info['shikibetu']) {
		         str = sprintf("%d-%d-%d", info['kaime1'], info['kaime2'], info['kaime3']);
	         }
	         info['kumi_name'] = str;
	     }

	     // 17.10.28
	     info['ary_kaime'] = [];
	     for(var i=1; i<=3; i++){
	         if('' != info['kaime'+i]){
		         var val = info['kaime'+i].split(/-/);
		         info['ary_kaime'].push(val);
	         }
	     }
	     return info;
     }

     /*
      * 組合せ買い目の展開(表示・非表示)
      */
     self.act_kaime_open = function(bix) {
	     if (self.debug) console.log('self.act_kaime_open(%s)', bix);

	     if (self.bet_view[bix]['open']) {
	         self.bet_view[bix]['open'] = 0;
	     } else {
	         self.bet_view[bix]['open'] = 1;
	     }
     }

     /*
      * 買い目の選択
      */
     self.act_kaime_select = function(bix, bcix) {
	     if (self.debug) console.log('self.act_kaime_select(%s,%s)', bix, bcix);

	     var sel = 'c';
	     if (bcix < 0) { // 親を選択
	         sel = 'p';
	         bcix = 0;
	     }

	     // トグルの動作
	     if (self.bet_select[bix * 1000 + bcix]) {
	         delete self.bet_select[bix * 1000 + bcix]; // 選択を解除する
	     } else {
	         // 別の組合せの選択を解除する(ToDo)
	         for (var key in self.bet_select) {
		         var p = Math.floor(key / 1000);
		         var c = Math.floor(key % 1000);
		         console.error('p: %s c: %s',p,c);
		         if('c' == sel) {
		             if(bix == p)	continue;
		             //console.log('remove child: %s',key);
		             delete self.bet_select[key]; // 選択を解除する
		         }
		         if ('p' == sel) { // 親を選択の場合
		             if(c != 0){
			             //console.log('remove parent: %s',key);
			             delete self.bet_select[key]; // 選択を解除する
		             }
		         }
	         }
	         if ('c' == sel) { // 子を選択の場合
			     self.bet_select_all = false; //全選択解除
		         var p = Math.floor(bcix / 1000);
		         //console.log('remove my parent: %s',(p+1) * 1000);
		         delete self.bet_select[p  * 1000]; // その親の選択も解除
	         }

	         self.bet_select[bix * 1000 + bcix] = true; // 選択済みにする
	     }
        // 親の買い目の選択状況確認
        var parent_count = 0;
        var chile_count = 0;
        for (var key in self.bet_select) {
            var c = Math.floor(key % 1000);
            if (c == 0) {
                parent_count++;
            }
        }
        if(parent_count == self.bet_view.length){
           self.bet_select_all = true; //全選択
        }else{
           self.bet_select_all = false; //全選択解除
        }

	     if (self.debug) console.log('self.bet_select: %O', self.bet_select);
     }

     /*
      * 買い目の全選択・全選択解除
      */
     self.act_kaime_select_all = function() {
	     if (self.debug) console.log('self.act_kaime_select_all()');

	     if (false === self.bet_select_all) { // 全解除
	         self.bet_select_all = true;
	         for (var i = 0; i < self.bet_view.length; i++) {
		         self.bet_select[i * 1000] = true;
	         }
	     } else {
	         self.bet_select_all = false;
	         self.bet_select = {};
	     }
	     if (self.debug) console.log('self.bet_select: %O', self.bet_select);
     }

     /*
      * 買い目の金額変更
      */
     self.act_change_money = function(exec) {
	     if (self.debug) console.log('self.act_change_money(%s)', exec);
	     	console.log(self.bet_money);
            console.log(self.bet_select);
	     if (exec) {
	         // 18.6.1 小数点で入力可能な不具合 1 -> 100
	         var chk_money = self.bet_money / 100;
	         if(Math.round(chk_money) !== chk_money || chk_money < 1) {
		         //alert("\n金額が未入力、あるいは正しくありません。\n");
		         return false;
	         }

	         var c = 0;
	         var p = 0;
	         for (var key in self.bet_select) {
		         var id = Math.floor(key / 1000);
		         var mod = Math.floor(key % 1000);
		         if (mod == 0) {
		             p++;
		         } else {
		             c++;
		         }
	         }
	         if (self.debug) console.log('p: %s c: %s', p, c);

	         if (p > 0) {
		         // 買い目金額変更(local)
		         var ndisam = new NDIsam();

		         for (var key in self.bet_select) {
		             var id = Math.floor(key / 1000);
		             var up_data = {
			             bet_id: self.bet_view[id]['bet_id'],
			             bet_money: self.bet_money
		             };
		             ndisam.replace(self.isam_domain, self.bet_view[id]['bet_no'], up_data);
		         }
		         self.render_bet_list();
		         self.bet_select = {};
		         self.bet_money = -1;
		         self.is_edit = false;
                 self.bet_select_all = false;
                 self.bet_select = {};
                 self.update();
                 self.list_mark_check();
	         } else if (c > 0) {
                self.err_info_swal("買い目が展開されますが、よろしいですか？", function(){
                    self.change_money_bet_child();
                    self.render_bet_list();
                    self.bet_select = {};
                    self.bet_money = -1;
                    self.is_edit = false;
                    self.update();
                    self.list_mark_check();
                });
	         }
	     }
	     $('#m-change_money').modal('hide'); // モーダル非表示
         $('#m-change_distribution').modal('hide'); // モーダル非表示(資金分配)
         $('body').removeClass('modal-open');
         $('#m-change_distribution').removeClass('in'); // モーダル非表示(資金分配)
     }

     /*
      * 資金分配(投票額から分配)
      */
    self.act_change_distribution = function(exec) {
        if (self.debug) console.log('self.act_change_distribution(%s)', exec);
        console.log(self.distribution_list);
        if(exec === false){
            $('#m-change_money').modal('hide'); // モーダル非表示
            $('#m-change_distribution').modal('hide'); // モーダル非表示(資金分配)
            $('body').removeClass('modal-open');
            $('#m-change_distribution').removeClass('in'); // モーダル非表示(資金分配)
            return false;
        }else if(self.distribution_list.length <= 0){
            self.err_info_swal('買い目がありません', false);
            $('#m-change_money').modal('hide'); // モーダル非表示
            $('#m-change_distribution').modal('hide'); // モーダル非表示(資金分配)
            $('body').removeClass('modal-open');
            $('#m-change_distribution').removeClass('in'); // モーダル非表示(資金分配)
            return false;
        }

        var bet_count_all = 0;
        for(var i = 0; i < self.distribution_list.length; i++){
            if(self.distribution_list[i]['comb']){
                bet_count_all += self.distribution_list[i]['comb'].length;
            }else{
                bet_count_all += 1;
            }
        }

        if(self.bet_money <= 0){
            self.err_info_swal('金額を正しく入力してください', false);
            $('#m-change_money').modal('hide'); // モーダル非表示
            $('#m-change_distribution').modal('hide'); // モーダル非表示(資金分配)
            $('body').removeClass('modal-open');
            $('#m-change_distribution').removeClass('in'); // モーダル非表示(資金分配)
            return false;
        }else if(self.distribution_mode == 'bet' && bet_count_all > self.bet_money / 100){
            var info = sprintf("分配に必要な最低投票額を入力してください。(%s円以上)", bet_count_all * 100);
            self.err_info_swal(info, false);
            $('#m-change_money').modal('hide'); // モーダル非表示
            $('#m-change_distribution').modal('hide'); // モーダル非表示(資金分配)
            $('body').removeClass('modal-open');
            $('#m-change_distribution').removeClass('in'); // モーダル非表示(資金分配)
            return false;
        }

        var distribution_obj = {};
        var is_popup = false;
        for(var bet_info of self.distribution_list){
            if(bet_info['houshiki'] != '0'){
                is_popup = true;
            }
            if(bet_info.comb){
                for(var key in bet_info.comb){
                    var odds_key = bet_info.comb[key].replace(/-/g, '');
                    var bet_key = sprintf("%s_%s", bet_info['shikibetu'], bet_info.comb[key]);
                    distribution_obj[bet_key] = bet_info;
                }
            }else{
                var kumi = bet_info['kumi_name'].split('-');
                var kumi_list = kumi.map(function(val){
                    return sprintf("%02d", val);
                });
                var bet_key = sprintf("%s_%s", bet_info['shikibetu'], kumi_list.join('-'));
                distribution_obj[bet_key] = bet_info;
            }
        }
        var add_new_bet_item = self.distribution_mode == 'bet' ? self.calc_distribution_bet(distribution_obj) : self.calc_distribution_payback();
        if(add_new_bet_item === false) {
            return false;
        }

        $('#m-change_distribution').modal('hide'); // モーダル非表示
        if(is_popup){
            self.err_info_swal("買い目が展開されますが、よろしいですか？", function(){
                //親の買い目を削除
                var ndisam = new NDIsam();
                for(var bet_info of self.distribution_list){
                    var del_bet_no = bet_info['bet_no'];
                    ndisam.remove(self.isam_domain, del_bet_no);
                }

                //ローカルストレージに入れる
                var part = self.distribution_list[0]['bet_id'].split(/_/);
                var new_part = [part[0], '', 'c0'];// 方式=通常
                self.set_storage(new_part, add_new_bet_item);
                self.render_bet_list();
                self.bet_select = {};
                self.bet_money = -11;
                self.is_edit = false;
                self.update();
            });
        }else{
            //親の買い目を削除
            var ndisam = new NDIsam();
            for(var bet_info of self.distribution_list){
                var del_bet_no = bet_info['bet_no'];
                ndisam.remove(self.isam_domain, del_bet_no);
            }

            //ローカルストレージに入れる
            var part = self.distribution_list[0]['bet_id'].split(/_/);
            var new_part = [part[0], '', 'c0'];// 方式=通常
            self.set_storage(new_part, add_new_bet_item);
            self.render_bet_list();
            self.bet_select = {};
            self.bet_money = -11;
            self.is_edit = false;
            self.update();
        }

     }

     /*
      * 資金分配(投票額から分配)
      */
    self.calc_distribution_bet = function(distribution_obj){
        console.log('self.calc_distribution_bet : %O', distribution_obj);
        var todd = 0;
        var add_new_bet_item = {};
        var tmp_bet_total = 0;
        var distribution_odds_list = {};

        for(var distribution_key in distribution_obj){
            var bet_info = distribution_obj[distribution_key];
            if(bet_info.comb){
                for(var key in bet_info.comb){
                    var odds_key = bet_info.comb[key].replace(/-/g, '');
                    var odds = 0;
                    var bet_key = sprintf("%s_%s", bet_info['shikibetu'], bet_info.comb[key]);
                    if(distribution_odds_list[bet_key]){
                        continue;
                    }
                    if(self.odds[bet_info['shikibetu']][odds_key] && parseInt(self.odds[bet_info['shikibetu']][odds_key][0]) >= 1){
                        var odds = self.odds[bet_info['shikibetu']][odds_key][0];
                    }else{
                        $('#m-change_distribution').hide(); // モーダル非表示
                        self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                        return false;
                    }
                    distribution_odds_list[bet_key] = parseInt(odds);
                    todd += 1 / odds;
                }
            }else{
                var kumi = bet_info['kumi_name'].split('-');
                var odds_key = '';
                odds_key = kumi.map(function(val){
                    return sprintf("%02d", val);
                });
                var bet_key = sprintf("%s_%s", bet_info['shikibetu'], odds_key.join('-'));
                if(distribution_odds_list[bet_key]){
                    continue;
                }
                odds_key = odds_key.join('');
                var odds = 0;
                if(self.odds[bet_info['shikibetu']][odds_key] && self.odds[bet_info['shikibetu']][odds_key][0] >= 1){
                    var odds = self.odds[bet_info['shikibetu']][odds_key][0];
                }else{
                    $('#m-change_distribution').hide(); // モーダル非表示
                    self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                    return false;
                }
                distribution_odds_list[bet_key] = parseInt(odds);
                //オッズチェックを入れる
                todd += 1 / odds;
            }
        }

        var check_odds = {};
        for(var distribution_key in distribution_obj){
            var bet_info = distribution_obj[distribution_key];
            if(bet_info.comb){
                for(var key in bet_info.comb){
                    var odds_key = bet_info.comb[key].replace(/-/g, '');
                    if(self.odds[bet_info['shikibetu']][odds_key] && self.odds[bet_info['shikibetu']][odds_key][0] >= 1){
                        var odds = self.odds[bet_info['shikibetu']][odds_key][0];
                    }else{
                        $('#m-change_distribution').hide(); // モーダル非表示
                        self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                        return false;
                    }
                    var bet_key = sprintf("%s_%s", bet_info['shikibetu'], bet_info.comb[key]);
                    if(check_odds[bet_key]){
                        continue;
                    }
                    var temp_bet_money = parseInt( self.bet_money ) / ( todd * odds );
                    if(temp_bet_money < 100){
                        temp_bet_money = 1;
                    }else{
                        temp_bet_money = Math.floor( temp_bet_money / 100 );
                    }
                    temp_bet_money = Math.floor(temp_bet_money) * 100;
                    tmp_bet_total += temp_bet_money;
                    if(add_new_bet_item[bet_key]){
                        add_new_bet_item[bet_key] += temp_bet_money;
                    }else{
                        add_new_bet_item[bet_key] = temp_bet_money;
                    }
                    check_odds[bet_key] = 1;
                }
            }else{
                var kumi = bet_info['kumi_name'].split('-');
                var kumi_list = kumi.map(function(val){
                    return sprintf("%02d", val);
                });
                var odds_key = kumi_list.join('');
                var odds = 0;
                if(self.odds[bet_info['shikibetu']][odds_key] && self.odds[bet_info['shikibetu']][odds_key][0] >= 1){
                    var odds = self.odds[bet_info['shikibetu']][odds_key][0];
                }else{
                    $('#m-change_distribution').hide(); // モーダル非表示
                    self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                    return false;
                }
                var bet_key = sprintf("%s_%s", bet_info['shikibetu'], kumi_list.join('-'));
                if(check_odds[bet_key]){
                    continue;
                }
                var temp_bet_money = parseInt( self.bet_money ) / ( todd * odds );
                if(temp_bet_money < 100){
                    temp_bet_money = 1;
                }else{
                    temp_bet_money = Math.floor( temp_bet_money / 100 );
                }
                temp_bet_money = Math.floor(temp_bet_money) * 100;
                tmp_bet_total += temp_bet_money;
                var bet_key = sprintf("%s_%s", bet_info['shikibetu'], kumi_list.join('-'));
                if(add_new_bet_item[bet_key]){
                    add_new_bet_item[bet_key] += temp_bet_money;
                }else{
                    add_new_bet_item[bet_key] = temp_bet_money;
                }
                check_odds[bet_key] = 1;
            }
        }
        var diff = self.bet_money - tmp_bet_total;
        if(diff == 0){
            return add_new_bet_item;
        }
        if(diff >= 0){
            //差分がプラスの時はオッズが一番低い組み合わせで調整
            var ret = Object.keys(distribution_odds_list).reduce(function(a, b){
                return distribution_odds_list[a] < distribution_odds_list[b] ? a : b;
            });
            //多い時はマイナスの数値を足してるから加算だけでOK
            add_new_bet_item = self.diff_adjustment(add_new_bet_item, distribution_odds_list, diff, 'p');
            //add_new_bet_item[ret] += diff;
        }else{
            //差分がマイナスの時
            var adjust = Math.abs(diff);
            add_new_bet_item = self.diff_adjustment(add_new_bet_item, distribution_odds_list, adjust, 'm');
        }
        return add_new_bet_item;
    }

     /*
      * 資金分配(払戻から分配)
      */
    self.calc_distribution_payback = function(){
        console.log('self.calc_distribution_payback');
        var add_new_bet_item = {};
        for(var bet_info of self.distribution_list){
            if(bet_info.comb){
                for(var key in bet_info.comb){
                    var odds_key = bet_info.comb[key].replace(/-/g, '');
                    var odds = 0;
                    if(self.odds[bet_info['shikibetu']][odds_key] && self.odds[bet_info['shikibetu']][odds_key][0] >= 1){
                        odds = self.odds[bet_info['shikibetu']][odds_key][0];
                    }else{
                        $('#m-change_distribution').hide(); // モーダル非表示
                        self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                        return false;
                    }
                    var temp_bet_money = parseInt( self.bet_money ) / odds;
                    if(temp_bet_money < 100){
                        temp_bet_money = 1;
                    }else{
                        temp_bet_money = Math.ceil( temp_bet_money / 100 );
                    }
                    temp_bet_money = Math.ceil(temp_bet_money) * 100;
                    add_new_bet_item[sprintf("%s_%s", bet_info['shikibetu'], bet_info.comb[key])] = temp_bet_money;
                }
            }else{
                var kumi = bet_info['kumi_name'].split('-');
                var kumi_list = kumi.map(function(val){
                    return sprintf("%02d", val);
                });
                var odds_key = kumi_list.join('');
                var odds = 0;
                if(self.odds[bet_info['shikibetu']][odds_key] && self.odds[bet_info['shikibetu']][odds_key][0] >= 1){
                    odds = self.odds[bet_info['shikibetu']][odds_key][0];
                }else{
                    $('#m-change_distribution').hide(); // モーダル非表示
                    self.err_info_swal('オッズがない買い目が含まれているため資金分配できません', false);
                    return false;
                }
                var temp_bet_money = parseInt( self.bet_money ) / odds;
                if(temp_bet_money < 100){
                    temp_bet_money = 1;
                }else{
                    temp_bet_money = Math.ceil( temp_bet_money / 100 );
                }
                temp_bet_money = Math.ceil(temp_bet_money) * 100;
                add_new_bet_item[sprintf("%s_%s", bet_info['shikibetu'], kumi_list.join('-'))] = temp_bet_money;
            }
        }
        return add_new_bet_item;
    }

    self.diff_adjustment = function(add_new_bet_item, distribution_odds_list, adjust, mode){
        console.log('self.diff_adjustment add_new_bet_item : %O, distribution_odds_list : %O, adjust %d', add_new_bet_item, distribution_odds_list, adjust);
        if(mode == 'm'){
            var sort_list = Object.keys(distribution_odds_list).sort(function(a,b){
                if( distribution_odds_list[a] < distribution_odds_list[b] ) return 1;
                if( distribution_odds_list[a] > distribution_odds_list[b] ) return -1;
                return 0;
            });
        }else{
            var sort_list = Object.keys(distribution_odds_list).sort(function(a,b){
                if( distribution_odds_list[a] > distribution_odds_list[b] ) return 1;
                if( distribution_odds_list[a] < distribution_odds_list[b] ) return -1;
                return 0;
            });
        }

        var total_adjust = 0;
        var tmp_money = 0;
        for(var key of sort_list){
            if(add_new_bet_item[key] > 100){
                if(mode == 'm'){
                    add_new_bet_item[key] -= 100;
                }else{
                    add_new_bet_item[key] += 100;
                }
                total_adjust += 100;
                if(adjust <= total_adjust){
                    return add_new_bet_item;
                    //break;
                }
            }
        }
        return self.diff_adjustment(add_new_bet_item, distribution_odds_list, adjust - total_adjust, mode);
    }
     /*
      * 資金分配(投票額から分配)
      */
    self.act_change_distribution_mode = function(mode) {
        if (self.debug) console.log('self.act_change_distribution_mode(%s)', mode);
        self.distribution_mode = mode;
     }

     /*
      * 買い目の削除
      */
     self.act_kaime_delete = function() {
	     if (self.debug) console.log('self.act_kaime_delete()');

	     var c = 0;
	     var p = 0;
	     for (var key in self.bet_select) {
	         var id = Math.floor(key / 1000);
	         var mod = Math.floor(key % 1000);
	         if (mod == 0) {
		         p++;
	         } else {
		         c++;
	         }
	     }
	     if (self.debug) console.log('p: %s c: %s', p, c);

	     if (p > 0) {
	         // 親レコードの削除
            self.err_info_swal("本当に削除してもよろしいですか？", function(){
                // 買い目削除(local)
                var ndisam = new NDIsam();
                for (var key in self.bet_select) {
                    var id = Math.floor(key / 1000);
                    console.log(id);
                    ndisam.remove(self.isam_domain, self.bet_view[id]['bet_no']);
                }
                self.render_bet_list();
                self.bet_select = {};
                self.is_edit = false;
                self.bet_select_all = false;
                self.update();
            });
	     } else if (c > 0) {
            self.err_info_swal("本当に削除してもよろしいですか？", function(){
                self.delete_bet_child();
                self.render_bet_list();
                self.bet_select = {};
                self.is_edit = false;
                self.bet_select_all = false;
                self.update();
            });
	     }
     }

     /*
      * 買い目削除(ゴミ箱)
      */
     self.act_kaime_delete_trashbox = function(bix, bcix) {
        if (self.debug) console.log('self.act_kaime_delete_trashbox()');
        // 親レコードの削除
        self.err_info_swal("本当に削除してもよろしいですか？", function(){
            // 買い目削除(local)
            var ndisam = new NDIsam();
            ndisam.remove(self.isam_domain, self.bet_view[bix]['bet_no']);
            // 削除した買い目の選択を削除
            self.act_kaime_select(bix, bcix);
            self.render_bet_list();
            self.bet_select = {};
            self.is_edit = false;
            self.bet_select_all = false;
            self.update();
        });
     }

     /*
      * 組合せ買い(フォーメーション、BOX,流し)の展開形を部分的に削除する
      */
     self.delete_bet_child = function() {
	     if (self.debug) console.log('self.delete_bet_child');

	     var del_c = {};
	     var p_id = -1;
	     for (var key in self.bet_select) {
	         p_id = Math.floor(key / 1000);
	         var c_id = Math.floor(key % 1000);
	         del_c[c_id - 1] = true;
	     }
	     if (self.debug) console.log('del_c: %O', del_c);

	     var add_c = [];
	     for (var i = 0; i < self.bet_view[p_id]['comb'].length; i++) {
	         var kaime = self.bet_view[p_id]['comb'][i];
	         if(self.debug) console.log('kaime: %s',kaime);
	         if (!del_c[i]) {
		         add_c.push(kaime);
	         }
	     }
	     if (self.debug) console.log('add_c: %O', add_c);

	     // 新たな買い目コードを作成
	     var part = self.bet_view[p_id]['bet_id'].split(/_/);
	     if (self.debug) console.log('part: %O', part);

	     var new_part = [part[0], part[1], ''];
	     var del_bet_no = self.bet_view[p_id]['bet_no'];
	     if (self.debug) console.log('del_bet_no: %s', del_bet_no);

	     new_part[2] = 'c0'; // 方式=通常

	     // 買い目取得(local)
	     var ndisam = new NDIsam();
	     ndisam.remove(self.isam_domain, del_bet_no);
	     for (var i = 0; i < add_c.length; i++) {
	         // 10が1となるバグ、暫定
	         //	     new_part[3] = add_c[i].replace(/0/g, '');
	         //	     new_part[3] = new_part[3].replace(/-/g, '_');
	         var ary_val = add_c[i].split(/-/);
	         for(var x=0; x<ary_val.length; x++){
		         ary_val[x] = parseInt(ary_val[x]);
	         }
	         new_part[3] = ary_val.join('_');
	         //	     console.error('new_part[3]: %s',new_part[3]);
	         var bet_id = new_part.join('_');
	         if (self.debug) console.log('bet_id: %s', bet_id);

	         // 投票管理番号を生成 (キーは現在時刻、ミリ秒まで)
	         var str_rand = Date.now() + i;
	         if(self.debug) console.log('str_rand: %s',str_rand);
	         var bet_no = sprintf("%s_%s",self.cur_race_id,CybozuLabs.MD5.calc(str_rand));
	         // 買い目を保存(local)
	         var bet_money = self.bet_view[p_id]['bet_money'];
	         //		 console.log('bet_id: %s bet_money: %s bet_no: %s',bet_id,bet_money,bet_no);
	         ndisam.replace(self.isam_domain, bet_no, {
		         bet_id: bet_id,
		         bet_money: bet_money
	         });
	     }
     }

     /*
      * 組合せ買い(フォーメーション、BOX,流し)の展開形を部分的に金額変更する
      */
     self.change_money_bet_child = function() {
	     if (self.debug) console.log('self.change_money_bet_child');
	     if (self.debug) console.log('self.bet_select: %O',self.bet_select);

	     var del_c = {};
	     var p_id = -1;
	     for (var key in self.bet_select) {
	         p_id = Math.floor(key / 1000);
	         var c_id = Math.floor(key % 1000);
	         del_c[c_id - 1] = true;
	     }
	     if (self.debug) console.log('del_c: %O p_id: %s', del_c,p_id);

	     var add_c = {};
	     for (var i = 0; i < self.bet_view[p_id]['comb'].length; i++) {
	         var kaime = self.bet_view[p_id]['comb'][i];
	         if(self.debug) console.log('kaime: %s',kaime);
	         if (del_c[i]) {
		         // 選択されていたら、変更後金額
		         add_c[kaime] = self.bet_money;
	         } else {
		         // 未選択は、元の金額
		         add_c[kaime] = self.bet_view[p_id]['bet_money'];
	         }
	     }
	     if (self.debug) console.log('add_c: %O', add_c);


	     // 新たな買い目コードを作成
	     var part = self.bet_view[p_id]['bet_id'].split(/_/);
	     if (self.debug) console.log('part: %O', part);

	     var new_part = [part[0], part[1], ''];
	     var del_bet_no = self.bet_view[p_id]['bet_no'];
	     if (self.debug) console.log('del_bet_no: %s', del_bet_no);

	     new_part[2] = 'c0'; // 方式=通常

	     var ndisam = new NDIsam();
         //親の買い目を削除
	     ndisam.remove(self.isam_domain, del_bet_no);
	     console.log(add_c);

	     // 買い目取得(local)
	     var ndisam = new NDIsam();
	     ndisam.remove(self.isam_domain, del_bet_no);
	     console.log(add_c);
	     var i = 0;
	     for (var key in add_c) {
	         // 10が1となるバグ、暫定
	         //	     new_part[3] = key.replace(/^0/g, '');
	         //	     new_part[3] = new_part[3].replace(/-/g, '_');
	         var ary_val = key.split(/-/);
	         for(var x=0; x<ary_val.length; x++){
		         ary_val[x] = parseInt(ary_val[x]);
	         }
	         new_part[3] = ary_val.join('_');
	         //	     console.error('new_part[3]: %s',new_part[3]);
	         var bet_id = new_part.join('_');
	         if (self.debug) console.log('bet_id: %s', bet_id);

	         // 投票管理番号を生成 (キーは現在時刻、ミリ秒まで)
	         var str_rand = Date.now() + i;
	         if(self.debug) console.log('str_rand: %s',str_rand);
	         var bet_no = sprintf("%s_%s",self.cur_race_id,CybozuLabs.MD5.calc(str_rand));
             console.log('bet_no: ',bet_no);
	         // 買い目を保存(local)
	         var bet_money = add_c[key];
	         if (self.debug) console.log('bet_id: %s bet_money: %s bet_no: %s', bet_id, bet_money, bet_no);
	         ndisam.replace(self.isam_domain, bet_no, {
		         bet_id: bet_id,
		         bet_money: bet_money
	         });
	         i++;
	     }
     }

    /*
     * tipstarに投票をする
     */
    self.tipstar_bet_v2 = function(type) {

        if (self.debug) console.log('self.tipstar_bet_v2');
        if (self.is_active_button == false){
            if (self.debug) console.log('self.tipstar_bet_v2 cancelled!!');
            return;
        }

        if(!self.cur_race['sale_status'] || self.cur_race['sale_status'] <= 0){
            self.err_info_swal('このレースは発売時間外です。', false);
            return;
        }

        var now = new Date();
        var year = self.cur_race_id.substr(0, 4);
        var month = self.cur_race_id.substr(4, 2);
        var day = self.cur_race_id.substr(6, 2);
        var time = self.cur_race['close'].split(':');
        var endtime = new Date(year,month - 1,day,time[0],time[1]);
        var race_date = new Date(year,month - 1,day);
        if(now.getTime() <= race_date.getTime()){
            self.err_info_swal('このレースは投票時間外です', false);
            return;
        }

//        if(now.getTime() >= endtime.getTime()){
//            self.err_info_swal('このレースの投票は締め切りました。', false);
//            return;
//        }

        //ログイン必須
        if(!self.args.sns_user_id){
            self.show_registor_popup();
            return;
        }

        //PC確認(tipstar.jsから抜粋)
        //if(!matchSmallLayout().matches) {
        //     modalTipstarShow("tipstar_pc.html");
        //     return;
        //}

        if(self.ts_data['ts_race_id']){
            var ts_race_id = self.ts_data['ts_race_id'];
        }else{
            self.err_info_swal('TIPSTAR情報の取得に失敗しました', false);
            return;
        }

        if(self.ts_data['ts_channel_id']){
            var raceChannelId = self.ts_data['ts_channel_id'];
        }else{
            self.err_info_swal('TIPSTAR情報の取得に失敗しました', false);
            return;
        }

        var tipstar_bet = self.make_tipstar_bet_v2(ts_race_id);
        console.log('self.ts_data : %O', self.ts_data);
        console.log('ts_race_id : %s', ts_race_id);
        console.log('raceChannelId : %s', raceChannelId);
        console.log('tipstar_bet : %O', tipstar_bet);
        if(now.getTime() >= endtime.getTime()){
            self.err_info_swal('このレースの投票は締め切りました。', false);
            return;
        }

        var raceType = self.cur_race_id.substr(8,2) <= 90 ? 'keirin' : 'pistsix';

//        return;
        if(!tipstar_bet){
            return;
        }

        //tip遷移案内確認
        if(IsMcShow && type == 'bet'){
            //モーダル表示
            self.is_tipstar_modal = true;
            self.update();
            self.show_tipstar_modal();
            return;
        }
        if(type == 'modal'){
            //cookieセット
            checkModalNone();
        }

        var url_raceType = self.cur_race_id.substr(8,2) <= 90 ? 'keirin' : 'pist6';
        var raceType = self.cur_race_id.substr(8,2) <= 90 ? 'keirin' : 'pistsix';

//        //テスト中(tipstarの向き先変更)
//        const tipstarOrigin = self.args.tipstar_url;
//        var tipstar_bet_url = sprintf("%s/netkeirin/%s/channels/%s/%s/connect", tipstarOrigin, url_raceType, raceChannelId, ts_race_id);
//        console.log(tipstar_bet_url);
//        self.tab = window.open(tipstar_bet_url);
        self.tab = window.open();

        //投票状態・買い目をDBに保存
        //user_bet_sessionTBLに挿入
        //bet_id = yyyymmdd + 00000001(8桁 + 8桁)
        var ndisam = new NDIsam();
        var list = ndisam.list(self.isam_domain);
        var ary_bet = [];
        if(false !== list){
            for(var bet_key in list){
                ary_bet.push({bet_id: list[bet_key]['bet_id'], money: list[bet_key]['bet_money']});
            }
        }

        var _data = {};
        _data.output = 'json';
        _data.mode = 'add';
        _data.bet_list = ary_bet;
        _data.race_id = self.cur_race_id;
        _data.device = self.args.device;
        _data.user_id = self.args.user_id;
        $.ajax({
            type     : 'POST',
//            type     : 'get',
            url      : self.args.keirin_url + '/bet/api_post_tipstar_bet.html',
            data     : _data,
            dataType : _data.output,
            success  : function( ret ){
                console.log(ret);
                if(ret['status'] == 'OK'){
                    self.bet_id = ret['bet_id'];
                    const tipstarOrigin = self.args.tipstar_url;
                    //const tipstarOrigin = 'https://zrace.sp.netkeiba.com';
                    //var tipstar_bet_url = tipstarOrigin + '/race/tipstar_dev.html';
                    var tipstar_bet_url = sprintf("%s/netkeirin/%s/channels/%s/%s/connect", tipstarOrigin, url_raceType, raceChannelId, ts_race_id);
                    console.log(tipstar_bet_url);
                    self.tab.location = tipstar_bet_url;
                    self.tipstar_tickets_sent = false;
                    self.bet_complete_requested = false;
                    const eventListenerCallback = (e) => {
                        if (e.origin !== tipstarOrigin) {
                            return;
                        }
                        if (e.data.action === "RequestNetKeirinTickets") {
                            var _data = {};
                            _data.output = 'json';
                            _data.mode = 'update';
                            _data.bet_id = self.bet_id;
                            $.ajax({
                                type     : 'POST',
//                                type     : 'get',
                                url      : self.args.keirin_url + '/bet/api_post_tipstar_bet.html',
                                data     : _data,
                                dataType : _data.output,
                                success  : function( ret ){
                                    console.log(ret);
                                    if(ret['status'] == 'OK'){
                                        //買い目作り直し(不具合の暫定対応)
                                        if(self.ts_data['ts_race_id']){
                                            var ts_race_id = self.ts_data['ts_race_id'];
                                        }else{
                                            self.err_info_swal('TIPSTAR情報の取得に失敗しました', false);
                                            return;
                                        }
                                        if(self.ts_data['ts_channel_id']){
                                            var raceChannelId = self.ts_data['ts_channel_id'];
                                        }else{
                                            self.err_info_swal('TIPSTAR情報の取得に失敗しました', false);
                                            return;
                                        }
                                        var tipstar_bet = self.make_tipstar_bet_v2(ts_race_id);
                                        if(!tipstar_bet){
                                            return;
                                        }
                                        var bet_complete_url = sprintf("%sbet/api_post_tipstar_bet.html?mode=complete&bet_id=%s&device=%s", self.args.keirin_url, self.bet_id, self.args.device);
                                        var bet_complete_api_url = sprintf("%sbet/api_post_bet_complete.html", self.args.keirin_url);
                                        console.log('bet_complete_url : %s', bet_complete_url);
                                        console.log('bet_complete_api_url : %s', bet_complete_api_url);
                                        // MEMO: messageに任意のJSONをいれる
                                        self.tab.postMessage({
                                            action: 'SendNetKeirinTickets',
                                            message: {
                                                betId: self.bet_id, // NetKeirin側の投票ID
                                                bet_id: self.bet_id,
                                                netkeibaId: self.args.sns_user_id,
                                                raceId: ts_race_id, // ※PISTSIXのraceIdはTIPSTAR APIからpistsixレース一覧を取得し該当のレース情報から突合したものを送って欲しいです
                                                raceType: raceType,
                                                cartBlocks: tipstar_bet,
                                                bet_complete_url: encodeURI(bet_complete_url),
                                                bet_complete_api_url: encodeURI(bet_complete_api_url),
                                                redirect_url: encodeURI(sprintf("%sshushi/?bet_id=%s", self.args.keirin_url, self.bet_id)),
                                            },
                                        }, tipstarOrigin);
                                        self.tipstar_tickets_sent = true;
                                        //オッズのアップデート停止
                                        if(self.odds_update_timer){
                                            clearInterval(self.odds_update_timer);
                                        }
                                        //セットインターバル(500ms,購入完了状態を確認,api_post_tipstar_bet check, キーがbet_id)
                                        self.count = 0;
                                        self.bet_status_flag = false;
                                        self.check_bet_status();
                                    }
                                },
                                error  : function(XMLHttpRequest, textStatus, errorThrown){
                                    console.log('XMLHttpRequest: %O',XMLHttpRequest);
                                    console.log('textStatus: %s',textStatus);
                                }
                            });
                        } else if (self.tipstar_tickets_sent && !self.bet_status_flag) {
                            console.log('tipstar postMessage:', e.data);
                            if (self.is_tipstar_purchase_complete_message(e.data)) {
                                self.request_tipstar_bet_complete();
                            }
                        }
                    }
                    window.addEventListener("message", eventListenerCallback);
                }
            },
            error  : function(XMLHttpRequest, textStatus, errorThrown){
                console.log('XMLHttpRequest: %O',XMLHttpRequest);
                console.log('textStatus: %s',textStatus);
            }
        });
    }


    /*
     * TIPSTAR用の買い目作成
     */
    self.make_tipstar_bet_v2 = function(ts_race_id) {
        if (self.debug) console.log('self.make_tipstar_bet_v2');
        var odds_type = {
             '1' : 'tanshou', //単勝(PIST6のみ)
             '3' : 'niwakufuku', //枠複
             '4' : 'niwakutan', //枠単
             '5' : 'nishafuku', //２車複
             '6' : 'nishatan', //２車単
             '7' : 'wide', //ワイド
             '8' : 'sanrenfuku', //３連複
             '9' : 'sanrentan', //３連単
        };
        var PurchaseTicketCartBlockKind = {
            '1' : 'formation',
            '2' : 'formationMulti',
            '3' : 'bara',
        };
        var ndisam = new NDIsam();
        var list = ndisam.list(self.isam_domain);
        if(!list || Object.keys(list).length <= 0){
            self.err_info_swal('買い目がありません', false);
            return false;
        }
        var ipat = new IpatDataModel();
        var waku_check = []; // 枠連の場合は、複数頭の枠番号を配列で渡す
        for (var w in self.waku_horse) {
            var num = Object.keys(self.waku_horse[w]).length;
            if (num > 1) {
                waku_check.push(w);
            }
        }

        var betItems = [];
        for (var bet_no in list) {
            var info = ipat.cvt_bet(list[bet_no]['bet_id'], list[bet_no]['bet_money'], waku_check);
            //金額チェック
            var chk_money = list[bet_no]['bet_money'] / 100;
            if(Math.round(chk_money) !== chk_money || chk_money < 1) {
                self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
                return false;
            }

            var bet_list = []; //買い目の組み合わせ格納用
            var betFormation = []; //選択した車番格納用

            if(info['houshiki'] == 0 || info['houshiki'] == 1){
                //通常 or フォーメーション
                for(var i = 1; i <= 3; i++){
                    if(info[sprintf('kaime%s', i)]){
                        var bet_num = info[sprintf('kaime%s', i)].split('-').map(str => parseInt(str));
                        betFormation.push(bet_num);
                    }
                }
            }else if(info['houshiki'] == 2){
                //ボックス
                var max = 2;
                if(info['shikibetu'] == 8 || info['shikibetu'] == 9){
                    max = 3;
                }else if(info['shikibetu'] == 1){
                    max = 1;
                }
                for(var i = 1; i <= max; i++){
                    var bet_num = info['kaime1'].split('-').map( str => parseInt(str));
                    betFormation.push(bet_num);
                }
            }else{
                //ながし
                if(!info['is_multi']){
                    var first = [];
                    var second = [];
                    var third = [];
                    var betFormation = [];
                    if(info['shikibetu'] == 7 || info['shikibetu'] == 5){
                        //ワイド、2車複
                        first.push(info['kaime1']);
                        second = info['kaime2'].split('-');
                    }else if(info['shikibetu'] == 8){
                        //3連複
                        if(info['houshiki'] == 3){
                            //1頭軸
                            first.push(info['kaime1']);
                            second = info['kaime2'].split('-');
                            third = info['kaime2'].split('-');
                        }else if(info['houshiki'] == 6){
                            //2頭軸
                            first.push(info['kaime1']);
                            second = info['kaime2'].split('-');
                            third = info['kaime3'].split('-');
                        }
                    }else{
                        var tmp_kaime = info['comb'].map(function(kaime){
                            var num = kaime.split('-').map(function(k, idx){
                                return parseInt(k.replace(/^0/, ''));
                            });
                            return num;
                        });
                        for(var idx = 0; idx < tmp_kaime.length; idx++){
                            var tmp_num = tmp_kaime[idx];
                            for(var i = 0; i < tmp_num.length; i++){
                                var num = tmp_num[i];
                                if(i == 0){
                                    if(!first.includes(num)){
                                       first.push(num);
                                    }
                                }else if(i == 1){
                                    if(!second.includes(num)){
                                        second.push(num);
                                    }
                                }else{
                                    if(!third.includes(num)){
                                        third.push(num);
                                    }
                                }
                            }
                        }
                    }

                    betFormation[0] = first;
                    if(second.length >= 1){
                        second.sort(function(a,b){
                            if( parseInt(a) < parseInt(b) ) return -1;
                            if( parseInt(a) > parseInt(b) ) return 1;
                            return 0;
                        });
                        betFormation[1] = second;

                    }
                    if(third.length >= 1){
                        third.sort(function(a,b){
                            if( parseInt(a) < parseInt(b) ) return -1;
                            if( parseInt(a) > parseInt(b) ) return 1;
                            return 0;
                        });
                        betFormation[2] = third;
                    }
                }else{
                    if(info['shikibetu'] == 9){
                        //3連単
                        if(info['houshiki'] == 3){
                            //1着流し
                            betFormation = self.make_bet_formation(info['kaime1'], info['kaime2'], info['kaime2']);
                        }else if(info['houshiki'] == 4){
                            //2着流し
                            betFormation = self.make_bet_formation(info['kaime2'], info['kaime1'], info['kaime2']);
                        }else if(info['houshiki'] == 5){
                            //3着流し
                            betFormation = self.make_bet_formation(info['kaime2'], info['kaime2'], info['kaime1']);
                        }else if(info['houshiki'] == 6){
                            //1,2着流し
                            betFormation = self.make_bet_formation(info['kaime1'], info['kaime2'], info['kaime3']);
                        }else if(info['houshiki'] == 7){
                            //1,3着流し
                            betFormation = self.make_bet_formation(info['kaime1'], info['kaime3'], info['kaime2']);
                        }else if(info['houshiki'] == 8){
                            //2,3着流し
                            betFormation = self.make_bet_formation(info['kaime3'], info['kaime1'], info['kaime2']);
                        }
                    }else if(info['shikibetu'] == 6 || info['shikibetu'] == 4){
                        //2車単,枠単
                        if(info['houshiki'] == 3){
                            //1着流し
                            betFormation = self.make_bet_formation(info['kaime1'], info['kaime2'], null);
                        }else if(info['houshiki'] == 4){
                            //2着流し
                            betFormation = self.make_bet_formation(info['kaime2'], info['kaime1'], null);
                        }
                    }
                }
            }

            if(info['comb']){
                //買い目をばらす
                var tmp_ts_bet = info['comb'].map(function(kaime){
                    var betNumbers = kaime.split('-').map(function(k){
                        return parseInt(k.replace(/^0/, ''));
                    });
                    var ts_bet = {
                        'betCount': list[bet_no]['bet_money'] / 100,
                        'betNumbers': betNumbers,
                    };
                    return ts_bet;
                });
                bet_list = bet_list.concat(tmp_ts_bet);
            }else{
                var ts_kaime = [];
                ts_kaime.push(parseInt(info['kaime1']));
                if(info['kaime2']){
                    ts_kaime.push(parseInt(info['kaime2']));
                }
                if(info['kaime3']){
                    ts_kaime.push(parseInt(info['kaime3']));
                }
                var tmp_ts_bet = {
                    'betCount': list[bet_no]['bet_money'] / 100,
                    'betNumbers': ts_kaime,
                };
                bet_list.push(tmp_ts_bet);
            }
            var kind = 'formation';
            if(info['houshiki'] == 0){
                //通常
                kind = 'bara';
            }else if(info['is_multi'] || info['houshiki'] == 2){
                //ボックスもマルチ扱いにする
                kind = 'formationMulti';
            }
            var cartBlocks = {
                'kind' : kind,
                'betFormation' : betFormation,
                'purchaseTicketCartItems' : bet_list,
                'betType' : odds_type[info['shikibetu']]
            };
            betItems.push(cartBlocks);
        }
        return betItems;
    }


    /*
     * netkeirinシステム投票用の買い目作成
     *
     * return: betItems
     */
    self.make_netkeirin_bet = function() {
        if (self.debug) console.log('self.make_netkeirin_bet');
        var ndisam = new NDIsam();
        var list = ndisam.list(self.isam_domain);
        if(!list || Object.keys(list).length <= 0){
            self.err_info_swal('買い目がありません', false);
            return false;
        }
        var race_id = self.cur_race_id;
        var device = self.args.device;
        var votes = [];
        for (var bet_index in list) {
            var bet_val = list[bet_index];
            var voteItem = {
                "id": bet_val.bet_id,
                "money": bet_val.bet_money
            };
            votes.push(voteItem);
        }

        var betItems = {
            "race_id": race_id,
            "votes": votes,
            "device": device
        };

        if (self.debug) console.log(betItems);
        return betItems;
    }


    /*
     * TIPSTARのレース情報取得
     */
    self.http_tipstar_api = function(race_id, fn){
        console.log('self.http_tipstar_api');
        var jyo_cd = race_id.substr(8,2);
        var race_num = race_id.substr(10,2).replace(/^0/, '');
        var kaisai_mode = jyo_cd <= 90 ? 'keirin' : 'pistsix';
        var tipstar_data = {};
        var storage_key = sprintf("ts_kaisai_%s_%s", kaisai_mode, race_id.substr(0, 8));
        var storage_data = JSON.parse(sessionStorage.getItem(storage_key));
        var ts_race_info = false;
        var data_expire = 600; //10分キャッシュ
        console.log('storage : %O', storage_data);

        var now = new Date().getTime();
        if(storage_data && now <= storage_data['expire_ms']){
            ts_race_info = storage_data['ts_data'];
        }

        if(ts_race_info && Array.isArray(ts_race_info)){
            console.log('get_storage');
            self.get_tipstar_id(race_id, ts_race_info, function(ts_data){
                fn(ts_data);
            });
        }else{
            //var api_url = sprintf('%s/%s/race_info_list', self.args.tipstar_api_url, kaisai_mode);
            // 2025/4/7 APIエンドポイント変更 n.matsu
            var api_url = (kaisai_mode=="keirin")
                           ?sprintf('%s/%s/race_info_list/v2', self.args.tipstar_api_url, kaisai_mode)
                           :sprintf('%s/%s/race_info_list', self.args.tipstar_api_url, kaisai_mode);
            console.log(api_url);
            $.ajax({
                type     : 'get',
                url      : api_url,
                dataType : 'json',
                success  : function( ret ){
                    console.log('http_data : %O', ret);
                    if(ret && Array.isArray(ret)){
                        var expire_ms = new Date().getTime();
                        expire_ms = expire_ms + (data_expire * 1000);
                        var data = {
                            'expire_ms' : expire_ms,
                            'ts_data' : ret
                        }
                        sessionStorage.setItem(storage_key, JSON.stringify(data));
                        self.get_tipstar_id(race_id,ret, function(ts_data){
                            fn(ts_data);
                        });
                    }
                },
                error  : function(XMLHttpRequest, textStatus, errorThrown){
                    console.log('XMLHttpRequest: %O',XMLHttpRequest);
                    console.log('textStatus: %s',textStatus);
                    console.log('errorThrown: %s',errorThrown);
                }
            });
        }
    }

    /*
     * TIPSTARのレースID,チャンネルID取得
     */
    self.get_tipstar_id = function(race_id, ts_data, fn){
        console.log('self.get_tipstar_id');
        var jyo_cd = race_id.substr(8,2);
        var race_num = race_id.substr(10,2).replace(/^0/, '');
        var kaisai_mode = jyo_cd <= 90 ? 'keirin' : 'pistsix';
        var tipstar_data = {};

        if(ts_data.length <= 0){
            fn(tipstar_data);
        }
        if(kaisai_mode == 'keirin'){
            ts_data.forEach(function(val, key){
                var VelodromeId = val.currentKeirinRace.velodrome.keirinVelodromeId;
                if(VelodromeId == jyo_cd){
                    tipstar_data['ts_channel_id'] = val.keirinRaceChannelId;
                    val.keirinRaceInfos.forEach(function(race, idx){
                        if(race.raceNumber == race_num){
                            tipstar_data['ts_race_id'] = race.keirinRaceId;
//                            fn(tipstar_data);
                        }
                    });
                }
            });
        }else{
            ts_data.forEach(function(val, key){
                var VelodromeId = val.currentPistsixRace.velodrome.pistsixVelodromeId;
//                if(VelodromeId == jyo_cd){
                if(VelodromeId == 32){
                    tipstar_data['ts_channel_id'] = val.pistsixRaceChannelId;
                    val.pistsixRaceInfos.forEach(function(race, idx){
                        if(race.raceNumber == race_num){
                            tipstar_data['ts_race_id'] = race.pistsixRaceId;
                            //break;
                            //fn(tipstar_data);
                        }
                    });
                }
            });
        }
        fn(tipstar_data);
    }

    self.make_bet_formation = function(kaime1, kaime2, kaime3){
        console.log('self.make_bet_formation : ', kaime1, kaime2, kaime3);
        var formation = [];
        formation[0] = kaime1.split('-');
        formation[1] = kaime2.split('-');
        if(kaime3){
            formation[2] = kaime3.split('-');
        }
        return formation;
    }

    self.tipstar_charge = function(){
        console.log('self.tipstar_charge');
        var location_url = sprintf("%s/charge", self.args.tipstar_url);
        console.log(location_url);
        window.open(location_url, '_blank');
        //location.href = location_url;
    }

    self.act_change_mode = function(mode){
        //買い目追加
        console.log(self.param);
        var query = '?m=mark_sheet';
        for(var key in self.param){
            if(key == 'm'){
                continue;
            }
            query += sprintf("&%s=%s", key, self.param[key]);
        }

        self.args.obs.trigger('narabi_show_event', 'show');
        self.select_shikibetu = {};
        self.cur_houshiki = -1;
        var topOffset = $(".IpatVote").offset().top;
        $(window).scrollTop(topOffset);
        route(query);
    }

     /*
      * 金額入力
      */
     self.act_change_money_single = function(ev) {
		if (self.debug) console.log('self.act_change_money_single(%O)', ev);

		if (ev) {
	    	// 18.6.1 小数点で入力可能な不具合 1 -> 100
	    	var chk_money = ev.target.value;
	    	if(Math.ceil(chk_money) !== parseInt(chk_money) || chk_money < 1) {
				self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
                self.render_bet_list();
                //self.update();
				return false;
	    	}

			var bet_id = ev.item.bet.bet_no;
			var kaime = ev.item.bet.bet_id;
			self.bet_money = ev.target.value * 100;
            if(self.bet_money <= 0){
                self.bet_money = 100;
            }
			// 買い目金額変更(local)
			var ndisam = new NDIsam();
			ndisam.replace(self.isam_domain, bet_id, {bet_id: kaime, bet_money: self.bet_money});
			self.render_bet_list();
			self.bet_select = {};
			self.bet_money = -1;
	    }else{
	    	self.is_change_money = false;
	    }
        self.update();
        self.list_mark_check();
	 }

     /*
      * 金額変更ボタン
      */
     self.act_money_change_btn = function(act, ev) {
		if (self.debug) console.log('self.act_money_change_btn(%O)', ev);

		if (ev.item && !ev.item.comb) {
			//親選択
	 		var bet_id = ev.item.bet.bet_no;
	 		var kaime = ev.item.bet.bet_id;
	 		if(act == 'm'){
	 			self.bet_money = ev.item.bet.bet_money - 100;
	 		}else{
	 			self.bet_money = ev.item.bet.bet_money + 100;
	 		}
            if(self.bet_money <= 0){
                self.bet_money = 100;
            }
	    	// 18.6.1 小数点で入力可能な不具合 1 -> 100
	    	var chk_money = self.bet_money / 100;
	    	if(Math.round(chk_money) !== chk_money || chk_money < 0) {
	    	//if(Math.round(chk_money) !== chk_money || chk_money < 1) {
				//self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
				return false;
	    	}
			// 買い目金額変更(local)
			var ndisam = new NDIsam();
			ndisam.replace(self.isam_domain, bet_id, {bet_id: kaime, bet_money: self.bet_money});
			self.render_bet_list();
			self.bet_select = {};
			self.bet_money = -1;
		}else{
            if(self.bet_money <= 0){
                self.bet_money = 100;
            }
			if(act == 'm'){
				self.bet_money -= 100;
			}else{
				self.bet_money += 100;
			}
		}
        self.update();
        self.list_mark_check();
	 }

     /*
      * 金額変更ボタン
      */
    self.act_money_change_btn_child = function(bet_money, bix, bcix, act) {
        if (self.debug) console.log('self.act_money_change_btn_child');
        //子選択
            if(act == 'm'){
                self.bet_money = bet_money - 100;
            }else{
                self.bet_money = bet_money + 100;
            }
            if(self.bet_money <= 0){
                self.bet_money = 100;
            }
            var chk_money = self.bet_money / 100;
            if(Math.round(chk_money) !== chk_money || chk_money < 0) {
            //if(Math.round(chk_money) !== chk_money || chk_money < 1) {
                //self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
                return false;
            }

        self.err_info_swal("買い目が展開されますが、よろしいですか？", function(){

            self.act_kaime_select(bix, bcix);
            self.change_money_bet_child();
            self.render_bet_list();
            self.bet_select = {};
            self.bet_money = -1;
            self.update();
        });
    }

     /*
      * 金額変更(入力)
      */
    self.act_money_change_child = function(bix, bcix, ev) {
        if (self.debug) console.log('self.act_money_change_child', ev.target.value);
    	var chk_money = ev.target.value;
    	if(Math.ceil(chk_money) !== parseInt(chk_money) || chk_money < 1) {
			self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
            self.render_bet_list();
            //self.update();
			return false;
    	}

        self.chk_money = ev.target.value;
         //if(self.chk_money < 1){
         if(self.chk_money <= 0){
            self.chk_money = 1;
             //self.err_info_swal('金額が未入力、あるいは正しくありません。', false);
             //return false;
         }
        //子選択
        self.err_info_swal("買い目が展開されますが、よろしいですか？", function(){
            self.bet_money = self.chk_money * 100;
            self.act_kaime_select(bix, bcix);
            self.change_money_bet_child();
            self.render_bet_list();
            self.bet_select = {};
            self.bet_money = -1;
            self.update();
        });
    }

    self.act_money_check = function(ev){
        if (self.debug) console.log('self.act_money_check', ev.target.value);
        self.before_money = 0;
        if(ev.target.value){
            self.before_money = ev.target.value;
        }
        ev.target.select();
    }

    self.act_input_passcode = function(ev){
        if (self.debug) console.log('self.act_input_passcode', ev.target.value);
        self.passcode = 0;
        if(ev.target.value){
            self.passcode = ev.target.value;
        }
        ev.target.select();
    }


     /*
      * swalの共通関数
      */
    self.err_info_swal = function(err_msg, fn) {
       if(!err_msg){
           return;
       }
       var option = {title: err_msg}

       if(fn){
           option['showCancelButton'] = true;
           option['cancelButtonText'] = 'やめる';
//           option['confirmButtonText'] = '展開する';
       }
        swal.fire(option).then(function(ret){
            if(true == ret.value && fn){
               fn();
            }else{
                if(self.before_money){
                    console.log(self.before_money);
                    $('.child_input').val(self.before_money);
                }
            }
        });
    }

    self.login_error = function(){
        swal.fire({
            title: "<p class='login'>ご利用には連携サイト「netkeiba.com」のアカウント登録が必要です。</p>\n<p class='to-account'>すでにnetkeiba.comをご利用中の方はログインをお願いいたします。</p>",
            confirmButtonText: 'netkeibaID登録',
        }).then(function(ret){
            if(true == ret.value){
                $(window).on('message', function(event){
                  if (event.originalEvent.origin !== self.args.regist_netkeiba_url ) return;
                  if (event.originalEvent.data === 'register_done' ) {
                      location.reload();
                  }
                });
                var return_url = location.href;
                document.cookie = 'url=' + return_url + '; path=/; domain=' + self.args.cookie_domain + ';';
                $('.swal2-confirm').colorbox({
                    iframe:true,
                    width: "94%",
                    height:"450px",
                    maxWidth:"360px",
                    speed:'200',
                    open:true,
                    fixed: true,
                    href: self.args.regist_netkeiba_url + '/?pid=regist_form&action=nk_input&nmlma=1&nterms=1&from=keirin'
                });
            }
        });
    }

     /*
      * 投票金額取得
      */
    self.get_votes_money = function(race_id, fn) {
        var api_url = sprintf("%s/api/v1/races/%s", self.args.betapi_url, race_id);
        $.ajax({
            type     : 'GET',
            url: api_url,
            dataType: 'json',
            crossDomain: true, // 認証のためCookie設定
            xhrFields: {
                withCredentials: true // これを追加
            },
            success: function( result ){
                if(result && result.data.money){
                    fn(result.data.money);
                }else{
                    fn(0);
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                if(XMLHttpRequest.status == 404){
                    fn(0);
                }
                console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                console.error('textStatus: ',textStatus);
                console.error('errorThrown.message: ',errorThrown.message);
                fn(0);
            }
        });
    }

     /*
      * TIPSTAR購入完了をnetkeirinへ通知
      */
    self.request_tipstar_bet_complete = function() {
        if (self.bet_complete_requested || !self.bet_id || self.bet_status_flag) {
            return;
        }
        self.bet_complete_requested = true;
        console.log('request_tipstar_bet_complete bet_id:', self.bet_id);
        var _data = {};
        _data.output = 'json';
        _data.mode = 'complete';
        _data.bet_id = self.bet_id;
        $.ajax({
            type     : 'POST',
            url      : self.args.keirin_url + '/bet/api_post_tipstar_bet.html',
            data     : _data,
            dataType : _data.output,
            success  : function( ret ){
                console.log('request_tipstar_bet_complete result:', ret);
            },
            error  : function(XMLHttpRequest, textStatus, errorThrown){
                console.log('request_tipstar_bet_complete error', XMLHttpRequest, textStatus);
                self.bet_complete_requested = false;
            }
        });
    }

    self.is_tipstar_purchase_complete_message = function(data) {
        if (!data || !data.action) {
            return false;
        }
        var complete_actions = {
            'NetKeirinVoteComplete': true,
            'NetKeirinPurchaseComplete': true,
            'NotifyNetKeirinBetComplete': true,
            'CompleteNetKeirinTickets': true,
            'NetKeirinBetComplete': true,
            'PurchaseComplete': true
        };
        return !!complete_actions[data.action];
    }

     /*
      * 購入ステータス確認
      */
    self.check_bet_status = function() {
        //console.log('self.check_bet_status');
        //console.log(self.bet_id);

        if(self.bet_status_flag == true) return;

        self.count++;
        if(self.count === 1){
            console.log('check_bet_status start bet_id:', self.bet_id);
        }
        var limit = 300;
        var timer_id = setTimeout(self.check_bet_status, 1000);
        var _data = {};
        _data.output = 'json';
        _data.mode = 'check';
        _data.bet_id = self.bet_id;
        $.ajax({
            type     : 'POST',
            url      : self.args.keirin_url + '/bet/api_post_tipstar_bet.html',
            data     : _data,
            dataType : _data.output,
            success  : function( ret ){
//                console.log(ret);
                if(ret['status'] == 'OK'){
                    self.bet_status_flag = true;
                    console.log('stop');
                    clearTimeout( timer_id );
                    //ストレージ削除
                    var ndisam = new NDIsam();
                    ndisam.clear(self.isam_domain);
                    //カートのデータ削除
                    var group_bet = 'bet_'+self.cur_race_id;
                    var cart_api = new NDCartApi(self.args.cart_url, 'json');
                    cart_api.clear_item(group_bet, function(resp){});
                    //tipstarのタブを閉じる
                    //self.tab.close();
                    //My収支に遷移
                    var location_url = sprintf("%sshushi/?bet_id=%s", self.args.keirin_url, self.bet_id);
                    console.log(location_url);
                    console.log(self.count);
                    window.location.href = location_url;
                }
            },
            error  : function(XMLHttpRequest, textStatus, errorThrown){
                console.log('XMLHttpRequest: %O',XMLHttpRequest);
                console.log('textStatus: %s',textStatus);
            }
        });
        if(self.count > limit){
            //時間内にstatusが変わらなかったら・・・
            clearTimeout( timer_id );
        }
    }

     /*
      * 買い目を表示用のオブジェクトに変換
      */
    self.make_bet_view_obj = function(){
        console.log('self.make_bet_view_obj');
        var disply_bet_view = {};
        for(var i = 0; i < self.bet_view.length; i++){
            var shikibetu = self.bet_view[i]['shikibetu'];
            if(!disply_bet_view[shikibetu]){
                disply_bet_view[shikibetu] = [];
            }
            self.bet_view[i]['idx'] = i;
            disply_bet_view[shikibetu].push(self.bet_view[i]);
        }
        console.log('disply_bet_view: ', disply_bet_view);
        return disply_bet_view;
    }

    self.show_tipstar_modal = function(){
        var current_scrollY = $(window).scrollTop();
        $(".HalfModal").addClass("OpenDraw");
        $(".Wrap").addClass("HalfModalViewOut");
        $(".Wrap.HalfModalViewOut").css({
            top: -1 * current_scrollY,
            height:'auto'
        });
        $("footer.SpFooter,footer.PcFooter").css({visibility: 'hidden',});
        $(".Wrap").append("<div class='ModalOverlay HalfModalOver'></div>");
        $(document).on("touchend click", ".HalfModal_CloseBtn,.Disagree button,.ModalOverlay", function() {
            $(".HalfModal").addClass("SlideOut");
            setTimeout(function () {
                $(".HalfModal").removeClass("OpenDraw");
                $(".HalfModal").removeClass("SlideOut");
            }, 200);
            $(".Wrap.HalfModalViewOut").attr({ style: ''}).removeClass("HalfModalViewOut");
            $(".HalfModalOver").remove();
            $('body').css({'position':'static'});
            $("footer.SpFooter,footer.PcFooter").css({visibility: 'visible'});
            $( 'html, body' ).prop( { scrollTop: current_scrollY } );
            self.is_tipstar_modal = false;
            self.is_cahrge = false;
            self.show_regist = false;
            self.update();
            return false;
            event.preventDefault();
        });
    }

    self.make_select_bet_odds = function(info, shikibetu){
        console.log('self.make_select_bet_odds', info);
        var tmp_odds = [];
        var odds_list = [];
        if(info['comb']){
            for(var i = 0; i < info['comb'].length; i++){
                var tmp_kaime = info['comb'][i].replace(/-/g, '');
                var odds = {};
                if(self.odds[shikibetu][tmp_kaime]){
                    odds[tmp_kaime] = self.odds[shikibetu][tmp_kaime][0];
                    tmp_odds.push(self.odds[shikibetu][tmp_kaime][0]);
                }else{
                    odds[tmp_kaime] = '0.0';
                    tmp_odds.push('0.0');
                }
                odds_list.push(odds);
            }
        }
        var max = 0;
        var min = 0;
        if(tmp_odds.length > 0){
            max = tmp_odds.reduce(function(a, b) {
                return Math.max(a, b);
            });
            min = tmp_odds.reduce(function(a, b) {
                return Math.min(a, b);
            });
        }
        var result = {
            'odds_list' : odds_list,
            'min_odds' : min,
            'max_odds' : max
        }
        return result;
    }

    //買い目一覧のオッズ開閉
    self.act_odds_open = function(shikibetu){
        console.log('self.act_odds_open : (%s)', shikibetu)
        if(self.is_odds_open[shikibetu]){
            self.is_odds_open[shikibetu] = false;
        }else{
            self.is_odds_open[shikibetu] = true;
        }
        console.log(self.is_odds_open);
    }

    self.act_select_odds_sort = function(odds_list, mode, shikibetu){
        console.log('self.act_select_odds_sort', odds_list, mode, shikibetu);
        if(self.select_odds_sort_mode == 'asc'){
              self.select_odds_sort_mode = 'desc';
        }else{
              self.select_odds_sort_mode = 'asc';
        }

        self.select_bet_odds[shikibetu] = odds_list.sort(function(a,b){
            if(mode == 'kaime'){
                var data_a = Object.keys(a)[0];
                var data_b = Object.keys(b)[0];
            }else{
                var data_a = Object.values(a)[0];
                var data_b = Object.values(b)[0];
            }
            if(self.select_odds_sort_mode == 'asc'){
                if( parseInt(data_a) < parseInt(data_b) ) return 1;
                if( parseInt(data_a) > parseInt(data_b) ) return -1;
            }else{
                if( parseInt(data_a) < parseInt(data_b) ) return -1;
                if( parseInt(data_a) > parseInt(data_b) ) return 1;
            }
            return 0;
        });
    }

    //買い目選択時
    self.act_select_kaime = function(shikibetu){
        console.log('self.act_select_kaime : ', shikibetu);
        if(Object.keys(self.select_odds).length >= 1){
            for(var kaime in self.select_odds){
                if(self.select_odds[kaime] == shikibetu){
                    delete self.select_odds[kaime];
                }
            }
        }
        //self.select_odds = {};
        if(self.select_kaime[shikibetu]){
            delete self.select_kaime[shikibetu];
        }else{
            self.select_kaime[shikibetu] = true;
        }
    }

    //オッズから選択時
    self.act_select_odds = function(kaime, shikibetu){
        console.log('self.act_select_odds', kaime, shikibetu);
        delete self.select_kaime[shikibetu];
        var tmp_kaime = sprintf('%s_%s', shikibetu, kaime);
        if(!self.select_odds[tmp_kaime]){
            self.select_odds[tmp_kaime] = shikibetu;
        }else if(self.select_odds[tmp_kaime] == shikibetu){
            delete self.select_odds[tmp_kaime];
        }
        console.log(self.select_odds);
    }

    self.act_chenge_edit_mode = function(){
        console.log('self.act_chenge_edit_mode');
        if(self.is_edit){
            self.is_edit = false;
            self.bet_select_all = false;
            self.bet_select = {};
        }else{
            self.is_edit = true;
        }
    }

    //選択した買い目を追加
    self.set_bet_odds = function(select_odds){
        console.log('self.set_bet_odds', select_odds);
        //オッズから選択時の方式は通常
        self.cur_houshiki = 0;
        //ボタン初期化
        self.btn_uno = {};
//        self.select_shikibetu = {};
        for(var tmp_kaime in select_odds) {
            self.select_shikibetu = {};
            var shikibetu = select_odds[tmp_kaime];
            var kaime = tmp_kaime.split('_')[1];
            self.select_shikibetu[shikibetu] = true;
            var new_btn_uno = {};
            var select_syaban = kaime.split('0');
            for(var i = 0; i < select_syaban.length; i++){
                var syaban = select_syaban[i].replace(/^0/, '');
                if(syaban){
                    if(i == 1){
                        if(!new_btn_uno[0]){
                            new_btn_uno[0] = {};
                        }
                        new_btn_uno[0][syaban] = true;
                    }else if(i == 2){
                        if(!new_btn_uno[1]){
                            new_btn_uno[1] = {};
                        }
                        new_btn_uno[1][syaban] = true;
                    }else if(i == 3){
                        if(!new_btn_uno[2]){
                            new_btn_uno[2] = {};
                        }
                        new_btn_uno[2][syaban] = true;
                    }
                }
            }
            self.btn_uno = new_btn_uno;
            self.set_bet(true);
        }
    }

    //オッズ自動更新
    self.odds_auto_update = function(){
        console.log('self.odds_auto_update');

        var api = new AplApiRace(self.args.api_url, true, 'json'/*, true*/);
        self.odds_update_timer = setInterval(function(){
            var bet_list = [];
            if(self.bet_view.length > 0){
                bet_list =  self.bet_view;
            }

            if(bet_list.length <= 0){
                return false;
            }
            if (self.debug) console.log('=============Send!! AplRaceOdds=============');

            // オッズ取得
            api.get('AplRaceOdds', {'race_id': self.cur_race_id}, function(odds_data) {
                if (self.debug) console.log('=============AplRaceOdds=============');
                if (self.debug) console.log(odds_data);
                for (var i = 1; i <= 9; i++) {
                    self.odds[i] = {};
                    if (undefined === odds_data['list_' + i]) {
                        continue;
                    }
                    for(var j = 0; j < odds_data['list_' + i].length; j++) {
                        var oval = odds_data['list_' + i][j];
                        self.odds[i][oval[0]] = [oval[1], oval[2], oval[3]];
                    }
                }
                if (self.debug) console.log('self.odds: %O', self.odds);
                self.bet_odds_list = [];

                for (var idx = 0; idx < bet_list.length; idx++) {
                    var bet_info = self.bet_gen(bet_list[idx]['bet_id'], bet_list[idx]['bet_money']);
                    // オッズ配当計算
                    if ('0' == bet_info['houshiki']) {
                        // 通常(バラ買い)
                        var key = '';
                        if ('1' == bet_info['shikibetu'] || '2' == bet_info['shikibetu']) {
                            key = sprintf("%02d", bet_info['kaime1']);
                        } else if ('3' == bet_info['shikibetu'] || '4' == bet_info['shikibetu'] || '5' == bet_info['shikibetu'] || '6' == bet_info['shikibetu'] || '7' == bet_info['shikibetu']) {
                            key = sprintf("%02d%02d", bet_info['kaime1'], bet_info['kaime2']);
                        } else if ('8' == bet_info['shikibetu'] || '9' == bet_info['shikibetu']) {
                            key = sprintf("%02d%02d%02d", bet_info['kaime1'], bet_info['kaime2'], bet_info['kaime3']);
                        }
                        var payback = 0;
                        if (undefined === self.odds[bet_info['shikibetu']]){
                            if(self.debug) console.error('empty odds shikibetu: %s',bet_info['shikibetu']);
                        }else if (undefined === self.odds[bet_info['shikibetu']][key]){
                            if(self.debug) console.error('unkown key : %s', key);
                            payback = 0;
                        } else {
                            var payback = self.odds[bet_info['shikibetu']][key][0] * bet_info['bet_money'];
                            payback = Math.round(payback);
                            if(self.bet_odds_list[bet_info['bet_id']] === undefined){
                                self.bet_odds_list[bet_info['bet_id']] = [];
                            }
                            self.bet_odds_list[bet_info['bet_id']].push(self.odds[bet_info['shikibetu']][key][0]);
                        }
                        bet_info['payback'] = payback;
                    } else {
                        // 以外(組合せ買い)
                        bet_info['payback'] = [];
                        bet_info['comb_odds'] = [];
                        for (var i = 0; i < bet_info['comb'].length; i++) {
                            var val = bet_info['comb'][i].split(/-/);
                            var comb_odds = '';
                            var key = '';
                            for (var j = 0; j < val.length; j++) {
                                key += sprintf("%02d", val[j]);
                            }
                            if (undefined === self.odds[bet_info['shikibetu']]){
                                if(self.debug) console.error('empty odds shikibetu: %s',bet_info['shikibetu']);
                            }else if(undefined === self.odds[bet_info['shikibetu']][key]){
                                if(self.debug) console.error('unkown key : %s', key);
                                payback = 0;
                                comb_odds = '0.0';
                            } else {
                                payback = self.odds[bet_info['shikibetu']][key][0] * bet_info['bet_money'];
                                payback = Math.round(payback);
                                comb_odds = self.odds[bet_info['shikibetu']][key][0];
                                if(self.bet_odds_list[bet_info['bet_id']] === undefined){
                                    self.bet_odds_list[bet_info['bet_id']] = [];
                                }
                                self.bet_odds_list[bet_info['bet_id']].push(self.odds[bet_info['shikibetu']][key][0]);
                            }
                            //if (self.debug) console.log('payback: %s:', payback);
                            bet_info['payback'].push(payback);
                            bet_info['comb_odds'].push(comb_odds);
                        }
                    }
                    bet_list[idx]['payback'] = bet_info['payback'];
                    bet_list[idx]['comb_odds'] = bet_info['comb_odds'];
                    if(self.bet_view.length > 0){
                        self.bet_view[idx] = bet_list[idx];
                    }
                    self.disply_bet_view = self.make_bet_view_obj();
                }
                if (self.debug) console.log('self.select_bet_odds: %O', self.select_bet_odds);
                if (self.debug) console.log('self.bet_odds_list: %O', self.bet_odds_list);
                self.update();
            });
        }, 15000);// 15秒
    }

    /*
     * tipstarに投票をする(アプリ版)
     */
    self.tipstar_bet_appli = function(type) {

        if (self.debug) console.log('self.tipstar_bet');

        if(!self.cur_race['sale_status'] || self.cur_race['sale_status'] <= 0){
            self.err_info_swal('このレースは発売時間外です。', false);
            return;
        }

        var now = new Date();
        var year = self.cur_race_id.substr(0, 4);
        var month = self.cur_race_id.substr(4, 2);
        var day = self.cur_race_id.substr(6, 2);
        var time = self.cur_race['close'].split(':');
        var endtime = new Date(year,month - 1,day,time[0],time[1]);
        var race_date = new Date(year,month - 1,day);
        if(now.getTime() <= race_date.getTime()){
            self.err_info_swal('このレースは投票時間外です', false);
            return;
        }

        if(now.getTime() >= endtime.getTime()){
            self.err_info_swal('このレースの投票は締め切りました。', false);
            return;
        }

        //ログイン必須
        if(!self.args.sns_user_id){
            self.show_registor_popup();
            return;
        }

        var ndisam = new NDIsam();
        var list = ndisam.list(self.isam_domain);
        if(!list || Object.keys(list).length <= 0){
            self.err_info_swal('買い目がありません', false);
            return false;
        }

        //PC確認(tipstar.jsから抜粋)
        //if(!matchSmallLayout().matches) {
        //     modalTipstarShow("tipstar_pc.html");
        //     return;
        //}

        //tip遷移案内確認
        if(IsMcShow && type == 'bet'){
            //モーダル表示
            self.is_tipstar_modal = true;
            self.update();
            self.show_tipstar_modal();
            return;
        }
        if(type == 'modal'){
            //cookieセット
            checkModalNone();
        }

        //セッションID取得
        var cookie = document.cookie;
        var cookie_list = cookie.split(';');
        var session_id = '';
        for(var c of cookie_list){
            var cArray = c.split('=');
            if( cArray[0].trim() == self.args.session_name){
                session_id = cArray[1];
                break;
            }
        }

        var ndisam = new NDIsam();
        var list = ndisam.list(self.isam_domain);
        var ary_bet = [];
        if(false !== list){
            for(var bet_key in list){
                ary_bet.push({'bet_key': bet_key, 'bet_id': list[bet_key]['bet_id'], 'money': list[bet_key]['bet_money']});
            }
        }
        var cart_api = new NDCartApi(self.args.cart_url, 'json');
        var group_bet = 'bet_'+self.cur_race_id;
        cart_api.clear_item(group_bet, function(resp){
            console.log('clear_item : ', resp);
            var ary_item_id = [];
            var ary_item_value = [];
            var ary_item_price = [];
            var ary_client_data = [];
            var client_data = {'user_id' : self.args.user_id}
            for(var i in ary_bet){
                ary_item_id.push(ary_bet[i]['bet_key']);
                ary_item_value.push(ary_bet[i]['bet_id']);
                ary_item_price.push(ary_bet[i]['money']);
                ary_client_data.push(client_data);
            }
            console.log(ary_item_id);
            console.log(ary_item_value);
            console.log(ary_item_price);
            console.log(ary_client_data);
            //レースIDとユーザーIDをカートに入れる
            //カートに買い目を入れる
            //クッキーからカートのセッションID(nkraceの値)を取り出す
            //セッションIDを引数としてappli_bet.htmlにロケーションする
            cart_api.add_item(group_bet, ary_item_id, ary_item_value, ary_item_price, ary_client_data, function(result){
                if(result){
                    console.log(result);
                    console.log('ok');
                    //ストレージ削除
                    //var ndisam = new NDIsam();
                    //ndisam.clear(self.isam_domain);
                    var appli_bet_url = sprintf("%sbet/appli_gateway.html?token=%s&race_id=%s", self.args.keirin_url, session_id, self.cur_race_id);
                    console.log(appli_bet_url);
                    location.href = appli_bet_url;
/*
                    var regist_url = self.args.regist_netkeiba_url + '/?pid=login_takeover&view=tipstar&next_url=%s';
                    var next_url = sprintf("%sbet/appli_bet.html?race_id=%s", self.args.keirin_url, self.cur_race_id);
//                    console.log(sprintf(regist_url, next_url));
                    console.log(sprintf(regist_url, encodeURIComponent(next_url)));
					if(typeof NetkeirinAppli == 'object' && NetkeirinAppli.platform == 'ios'){
						location.href = 'ndapp://check_geolocation?url=' + encodeURIComponent(sprintf(regist_url, next_url));
					} else {
						location.href = sprintf(regist_url, next_url);
					}
*/
                }else{
                    console.log('ng');
                }
            });
        });
    }

    self.check_passcode = async function(){
        if (self.debug) console.log('self.check_passcode');
        /* 二重に投票を受け付けてしまわないような対応 */
        if (self.is_active_button == false){
            if (self.debug) console.log('self.check_passcode cancelled!!');
            return;
        }
        if(self.cur_race_id.substr(8, 2) == '91'){
            console.log('pist6');
            // pist6のレースはnetkeirin投票しない
            self.is_pist6_error = true;
            self.update();
            self.list_mark_check();
            return;
        }
        if(!self.cur_race['sale_status'] || self.cur_race['sale_status'] <= 0){
            //self.err_info_swal('このレースは発売時間外です。', false);
            //return;
        }

        var now = new Date();
        var year = self.cur_race_id.substr(0, 4);
        var month = self.cur_race_id.substr(4, 2);
        var day = self.cur_race_id.substr(6, 2);
        var time = self.cur_race['close'].split(':');
        var endtime = new Date(year,month - 1,day,time[0],time[1]);
        var race_date = new Date(year,month - 1,day);
        if(now.getTime() <= race_date.getTime()){
            //self.err_info_swal('このレースは投票時間外です', false);
            //return;
        }

        //ログイン必須
        if(!self.args.sns_user_id){
            self.show_registor_popup();
            return;
        }


        if(now.getTime() >= endtime.getTime()){
            //self.err_info_swal('このレースの投票は締め切りました。', false);
            //return;
        }

        try{
            // ロック状態状態取得
            await self.get_passcoe_check_lock();
            self.is_passcode_form = true;
            self.update();
            // 暗証番号入力
            console.log('暗証番号入力');
        } catch(e){
            console.error('Error in get_passcoe_check_lock:', e);
            var response = e.responseJSON;
            if(response && response.data && response.data.result == 2){
                // ロック画面表示
                self.is_passcode_lock = true;
                self.unlock_at = response.data.unlock_at_view;
                self.update();
                return;
            }
            self.err_info_swal('暗証番号確認に失敗しました。しばらくしてから再度お試しください。', false);
            return;
        }
    }

    /*
     * netkeirin内の投票システムで投票をする
     */
    self.netkeirin_bet = async function(type) {
        console.log('self.netkeirin_bet');
        //---------------------------------------------
        // netkeirin投票パラメータ生成
        //---------------------------------------------
        if(self.is_voting){
            // 連打防止
            console.log('self.is_voting is true, return');
            return;
        }
        var netkeirin_bet = self.make_netkeirin_bet();
        console.log('netkeirin_bet : %O', netkeirin_bet);
        if(!netkeirin_bet){
            return;
        }

        // 暗証番号が違った場合、inputの欄を空にする
        self.clearInput = function (selector = '.ChargeType_A-3-2-1 #jsInputPasswordCurrent') {
            const inputCode = self.root.querySelector(selector);
            if(inputCode) inputCode.value = '';
        }

        try {
            // 投票中はローディングにする
            self.is_voting = true;
            self.update();

            // 暗証番号認証
            await self.passcode_auth();
            self.is_passcode_form = false;
            self.is_passcode_error = true;
            // self.clearInput();
        } catch (e) {
            console.error('Error in passcode_auth:', e);
            self.is_voting = false;
            self.update();
            var response = e.responseJSON;
            if(response && response.data.result == '2'){
                // 暗証番号ロック
                self.is_passcode_form = false;
                self.is_passcode_error = true;
                self.is_passcode_lock = true
                self.unlock_at = response.data.unlock_at_view;
                // self.clearInput();
                return;
            }else{
                // 暗証番号認証失敗
                self.is_passcode_error = true;
                self.clearInput();
                return;
            }
        } finally {
            // 暗証番号入力画面を閉じる
            //self.is_passcode_form = false;
            //self.passcode = '';
            self.is_voting = false;
            self.update();
        }

        try {
            // 投票中はローディングにする
            self.is_voting = true;
            self.update();

            // 投票上限額取得
            var vote_setting = await self.get_vote_setting();
            var vote_remain_price = vote_setting.data.vote_remain_price;
            // 未設定の場合はnullが返る
            if(vote_remain_price != undefined && vote_remain_price != null){
                if(self.total_bet_money > vote_remain_price){
                    // 投票上限額を超えている場合
                    const error = new Error('投票上限額を超えています');
                    error.vote_setting = vote_setting.data;
                    throw error;
                }
            }

        } catch (e) {
            // 投票上限額取得失敗
            console.log(e.vote_setting);
            self.vote_setting = e.vote_setting || {};
            self.is_money_limit_error = true;
            self.update();
            return;
        } finally {
            self.is_voting = false;
            self.update();
        }

        try {
            // 投票中はローディングにする
            self.is_voting = true;
            self.update();

            // 投票API実行
            var resutl = await self.post_netkeirin_bet(netkeirin_bet);
            console.log('投票成功:', resutl);
            //ストレージ削除
            var ndisam = new NDIsam();
            ndisam.clear(self.isam_domain);
            self.is_voting = false;
            self.update();
            // 購入完了ページに遷移
            window.location.href = self.args.keirin_url + 'shushi/inquiry.html?race_id='+self.cur_race_id + "&mode=bet_complete";
        } catch (error) {
            console.error('Error during netkeirin bet:', error);
            console.log('投票失敗:', error.responseJSON);
            let vote_error_msg = '';
            if (error != undefined && error.status === 422) {
                vote_error_msg = error.responseJSON.message.replace(/\n/g, "<br>");
            }else{
                vote_error_msg = sprintf("エラーが発生しました(%s)", XMLHttpRequest.status);
            }
            self.is_vote_error = true;
            self.is_voting = false;
            // ajax_race_live_flash.htmlの結果を反映させるためのここでアップデートする
            console.log('投票失敗:', vote_error_msg);
            self.update();
            $('#vote_error_msg').html(vote_error_msg);
            await self.handle_race_live_flash();
        }
    }


    //---------------------------------------------
    // 暗証番号ロック状態確認
    //---------------------------------------------
    self.get_passcoe_check_lock = function(){
        return new Promise(function(resolve, reject) {
            $.ajax({
                type     : 'GET',
                url      : self.args.keirin_url + '/regist/ekyc/api_get_passcoe_check.html',
                dataType : 'json',
                crossDomain: true, // 認証のためCookie設定
                xhrFields: {
                    withCredentials: true // これを追加
                },
                success  : function( ret, textStatus, xhr ){
                    console.log(ret);
                    if (xhr.status === 200 && ret['status'] == 'success' && ret['data']['result'] == '0') {
                        // 暗証番号入力
                        resolve();
                        return;
                    }
                    reject(xhr);
                },
                error  : function(XMLHttpRequest, textStatus, errorThrown){
                    console.log('XMLHttpRequest: %O',XMLHttpRequest);
                    console.log('textStatus: %O',textStatus);
                    console.log('errorThrown: %O',errorThrown);
                    reject(XMLHttpRequest);
                }
            });
        });
    }

    self.passcode_auth = function(){
        console.log('passcode_auth');
        console.log(self.passcode);

        return new Promise(function(resolve, reject) {
            if(self.passcode == ''){
                reject('passcode is empty');
            }
            var _data = {};
            _data.input = 'UTF-8';
            //_data.output = 'json';
            _data.passcode = self.passcode;
            $.ajax({
                type     : 'POST',
                url      : self.args.keirin_url + '/charge/api/api_get_auth_passcode.html',
                data     : _data,
                dataType : 'json',
                crossDomain: true, // 認証のためCookie設定
                xhrFields: {
                    withCredentials: true // これを追加
                },
                success  : function( ret, textStatus, xhr ){
                    console.log(ret);
                    console.log(xhr);
                    console.log(textStatus);
                    if (xhr.status === 200) {
                        // 暗証番号入力
                        if (ret['status'] == 'OK' && ret['data']['result'] == '1') {
                            resolve();
                        } else {
                            reject(xhr);
                        }
                    } else {
                        reject(xhr);
                    }
                },
                error  : function(XMLHttpRequest, textStatus, errorThrown){
                    reject(XMLHttpRequest);
                }
            });
        });
    }

   self.handle_race_live_flash = async function(){
      try {
        await self.show_race_live_flash();
      } catch (error) {
        console.error(error);
      } finally {
        self.update();
        self.list_mark_check();
      }
    }

    //---------------------------------------------
    // 投票API実行
    //---------------------------------------------
    self.post_netkeirin_bet = function(netkeirin_bet){
        return new Promise(function(resolve, reject) {
            $.ajax({
                type     : 'POST',
                url      : self.args.betapi_url + '/api/v1/votes',
                data     : netkeirin_bet,
                dataType : 'json',
                crossDomain: true, // 認証のためCookie設定
                xhrFields: {
                    withCredentials: true // これを追加
                },
                success  : function( ret, textStatus, xhr ){
                    if (xhr.status === 201) {
                        resolve();
                    }else{
                        reject(xhr);
                    }
                },
                error  : function(XMLHttpRequest, textStatus, errorThrown){
                    reject(XMLHttpRequest);
                }
            });
        });
    }

    //---------------------------------------------
    // 投票上限取得
    //---------------------------------------------
    self.get_vote_setting = function(){
        return new Promise(function(resolve, reject) {
            $.ajax({
                type     : 'GET',
                url      : self.args.betapi_url + '/api/v1/settings',
                dataType : 'json',
                crossDomain: true, // 認証のためCookie設定
                xhrFields: {
                    withCredentials: true // これを追加
                },
                success  : function( ret, textStatus, xhr ){
                    console.log('get_vote_setting ret: ', ret);
                    if (xhr.status === 200) {
                        resolve(ret);
                    }else{
                        reject(xhr);
                    }
                },
                error  : function(XMLHttpRequest, textStatus, errorThrown){
                    reject(XMLHttpRequest);
                }
            });
        });
    }

    //---------------------------------------------
    // LIVE速報表示(投票失敗時のモーダル)
    //---------------------------------------------
    self.show_race_live_flash = function(){
        return new Promise(function(resolve, reject) {
            var _data = {};
            _data.input = 'UTF-8';
            _data.output = 'json';
            _data.rf = 'toplive';
            $.ajax({
                type: "POST",
                url: self.args.keirin_url +  '/race/ajax_race_live_flash.html',
                data: _data,
                dataType: _data.output,
                success: function(data){
                    if (data !=='') {
                        $('#TodayRace_Live').parent().css('display', 'block');
                        $('#TodayRace_Live').html(data);
                    }
                    resolve();
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    console.error('textStatus:',textStatus);
                    reject();
                }
            });
        });
    }

    self.act_link_charge = function(){
        console.log('self.act_link_charge');
        self.is_cahrge = true;
        //モーダル表示
        self.is_tipstar_modal = true;
        self.update();
        self.show_tipstar_modal();
        return;
//        OnLinkClick(self.args.tipstar_url + '/charge');
    }

    self.act_distribution = function(bix){
        console.log('self.act_distribution');
        self.distribution_list = [];
        if(bix == 'all'){
            self.distribution_list = self.bet_view;
            self.distribution_title = '一括資金分配';
        }else{
            self.distribution_list.push(self.bet_view[bix]);
            self.distribution_title = '資金分配';
        }
        self.update();
    }

    self.show_registor_popup = function(){
        console.log('show_registor_popup');
        $(window).on('message', function(event){
            if (event.originalEvent.origin !== self.args.regist_netkeiba_url ) return;
            if (event.originalEvent.data === 'register_done' ) {
                location.reload();
            }
        });
        self.iframe_url = self.args.keirin_url + '/regist/regist_netkeiba.html?from=bet';
        var return_url = location.href;
        var host = location.host.split('.');
        var cookie_domain = '.' + host[1] + '.' + host[2];
        document.cookie = 'keirin_url=' + return_url + '; path=/; domain=' + cookie_domain + ';';
        //モーダル表示
        self.is_tipstar_modal = true;
        self.show_regist = true;
        self.update();
        self.show_tipstar_modal();
    }

    self.set_storage = function(new_part, add_c){
        // 買い目取得(local)
        var ndisam = new NDIsam();
        var i = 0;
        for (var item_key in add_c) {
            // 10が1となるバグ、暫定
            //     new_part[3] = key.replace(/^0/g, '');
            //     new_part[3] = new_part[3].replace(/-/g, '_');
            var tmp_key = item_key.split(/_/);
            var ary_val = tmp_key[1].split(/-/);
            for(var x=0; x<ary_val.length; x++){
                ary_val[x] = parseInt(ary_val[x]);
            }
            new_part[1] = sprintf("b%s", tmp_key[0]);
            new_part[3] = ary_val.join('_');
            //	     console.error('new_part[3]: %s',new_part[3]);
            var bet_id = new_part.join('_');
            if (self.debug) console.log('bet_id: %s', bet_id);
               // 投票管理番号を生成 (キーは現在時刻、ミリ秒まで)
            var str_rand = Date.now() + i;
            if(self.debug) console.log('str_rand: %s',str_rand);
            var bet_no = sprintf("%s_%s",self.cur_race_id,CybozuLabs.MD5.calc(str_rand));
            console.log('bet_no: ',bet_no);
            // 買い目を保存(local)
            var bet_money = add_c[item_key];
            if (self.debug) console.log('bet_id: %s bet_money: %s bet_no: %s', bet_id, bet_money, bet_no);
            ndisam.replace(self.isam_domain, bet_no, {
                bet_id: bet_id,
                bet_money: bet_money
            });
            i++;
        }
    }

    self.get_pasonal_data = function(fn){
        if(self.args.sns_user_id != ''){
            self.get_points(function(){
                self.get_ekyc_statue(function(){
                    fn();
                });
            });
        }else{
            fn();
        }
    }

    // 本人確認状態確認
    self.get_ekyc_statue = function(fn){
        var ekyc_api_url = self.args.keirin_url + '/regist/ekyc/api_get_validate.html';
        $.ajax({
            type     : 'GET',
            url: ekyc_api_url,
            dataType: 'json',
            success: function( result ){
                console.log('result: ',result);
                if(result['status'] == 'success' && (result['result'] == '1' || result['result'] == '3')){
                    self.is_ekyc = true;
                    self.is_ban_user = result['result'] == '3' ? true : false;
                    self.is_show_usage_limit = self.is_ban_user;
                    fn();
                } else {
                    fn();
                }
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                console.error('XMLHttpRequest.status: ',XMLHttpRequest.status)
                console.error('textStatus: ',textStatus);
                console.error('errorThrown.message: ',errorThrown.message);
                fn();
            }
        });
    }

    //残高取得
    self.get_points = function(fn){
        var _data = {};
        _data.output = 'jsonp';
        $.ajax({
            type: 'POST',
            url:  self.args.money_api_url + '/charge/api/api_get_points.html',
            data: _data,
            dataType: _data.output,
        }).done(function(data, textStatus, jqXHR){
            console.log(data);
            if (data.status == 'OK') {
                var point = data.data.points_summary.total_active_points;
                self.point = Math.trunc(point);
                fn(self.point);
            } else {
                fn();
            }
        }).fail(function(jqXHR, textStatus, errorThrown){
            fn();
            console.log('jqXHR: ',jqXHR);
        });
    }

    self.charge = function() {
      //e.preventDefault();
      $.colorbox({
          iframe:true,
          width: "90%",
          maxWidth:'480px',
          height:"500px",
          maxHeight:"90%",
          speed:'200',
          open:true,
          fixed: true,
          speed: 200,
          href: self.args.money_api_url + '/charge/',
          className: 'addChargeColorbox',
          onComplete: function () {
            window.addEventListener('message', function(event) {
              if (event.data === 'closeColorbox') {
                $.colorbox.close();
              }
            });
          },
          onClosed: function() {
           self.get_points(function(point){
//            self.update();
            self.args.obs.trigger('update_points_event', point);
           });
          }
      });
    }

    //制作
    self.list_mark_check = function(){
    // 特定の要素が存在するかどうかを判定
    if ($('.fixedFooter').length) {
        $(".InputFixedArea01").css({
            "bottom": "51px"
        });
    }

	var BetHead = $('.BetRaceHead_Wrap');
	var offset = BetHead.offset();
	var floatBetHead = function() {
		if($(window).scrollTop() > offset.top) {
			BetHead.addClass('Fixed');
		} else {
			BetHead.removeClass('Fixed');
		}
	}
	$(window).scroll(floatBetHead);
	$('body').bind('touchmove', floatBetHead);

		$('.RaceOdds_HorseList_Table tbody tr').each(function(){
			if($(this).find('.MarkIcon').length){
				$(this).addClass('selected');
			}
		});
		$(window).scroll(function () {
			var footHeight = $('.Find_FootArea').outerHeight() + 100;
			var scrollHeight = $(document).height();
			var scrollPosition = window.innerHeight + $(window).scrollTop();
			if (scrollHeight - scrollPosition <= footHeight) {
				$(".InputFixedArea01").css({
					"position": "relative"
				});
			} else {
				$(".InputFixedArea01").css({
					"position": "fixed",
					"bottom": "51px"
				});
			}
		});


        //エラーメッセージの開閉
        $(".errorMessageInBtn").off("click");
        $(".errorMessageInBtn").on("click", function(){
            console.log('errorMessageInBtnerrorMessageInBtnerrorMessageInBtn');
            $(this).closest('.errorMessageBox').toggleClass("isOpen");
            $(this).closest('.errorMessageBox').find('.errorMessageContents').slideToggle();
            self.is_vote_error = false;
        });
//        $(".errorMessageInBtn").click(function () {
//            console.log('errorMessageInBtnerrorMessageInBtnerrorMessageInBtn');
//            $(this).closest('.errorMessageBox').toggleClass("isOpen");
//            $(this).closest('.errorMessageBox').find('.errorMessageContents').slideToggle();
//        });

        //制作
        $("#RaceChoiceBtn").off("click");
        $("#RaceChoiceBtn").on("click", function(){
            console.log('click');
            make_slide_modal();
        });

        // レース選択のモーダル表示
        function make_slide_modal(){
            var current_scrollY = $(window).scrollTop();
            $(".HalfModal.RaceChoiceArea").addClass("OpenDraw");
            $(".Wrap").addClass("HalfModalViewOut");
            $(".Wrap.HalfModalViewOut").css({
                top: -1 * current_scrollY,
                height:'auto'
            });
            $("footer.SpFooter,footer.PcFooter").css({visibility: 'hidden',});
            $(".Wrap").append("<div class='ModalOverlay HalfModalOver'></div>");
            $(document).on("touchend click", ".HalfModal_CloseBtn,.Disagree button,.ModalOverlay", function() {
                modal_slide_out();
            });
        }

        // レース選択のモーダル表示　閉じる
        function modal_slide_out(event){
            var current_scrollY = $(window).scrollTop();
            $(".HalfModal.RaceChoiceArea").addClass("SlideOut");
            setTimeout(function () {
                $(".HalfModal.RaceChoiceArea").removeClass("OpenDraw");
                $(".HalfModal.RaceChoiceArea").removeClass("SlideOut");
            }, 200);
            $(".Wrap.HalfModalViewOut").attr({ style: ''}).removeClass("HalfModalViewOut");
            $(".HalfModalOver").remove();
            $('body').css({'position':'static'});
            $("footer.SpFooter,footer.PcFooter").css({visibility: 'visible'});
            $( 'html, body' ).prop( { scrollTop: current_scrollY } );
//            event.preventDefault();
        };


    }

    </script>

</bet_list>
