<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<%@ page import="org.springframework.web.util.HtmlUtils" %>
<!DOCTYPE html>
<%
    String ctx = request.getContextPath();
    String rawDisplayName = session.getAttribute("displayName") == null ? "" : String.valueOf(session.getAttribute("displayName"));
    String creatorValue = HtmlUtils.htmlEscape(rawDisplayName);
    boolean editMode = Boolean.TRUE.equals(request.getAttribute("editMode"));
    String editGameId = request.getAttribute("editGameId") == null ? "" : String.valueOf(request.getAttribute("editGameId"));
    String formAction = ctx + (editMode ? "/game/" + editGameId + "/edit" : "/game/new");
    String pageTitle = editMode ? "게임 수정" : "신규 게임 게시";
    String submitText = editMode ? "수정" : "등록";
    String editGameName = HtmlUtils.htmlEscape(request.getAttribute("editGameName") == null ? "" : String.valueOf(request.getAttribute("editGameName")));
    String editCreatorNote = HtmlUtils.htmlEscape(request.getAttribute("editCreatorNote") == null ? "" : String.valueOf(request.getAttribute("editCreatorNote")));
    String editGitUrl = HtmlUtils.htmlEscape(request.getAttribute("editGitUrl") == null ? "" : String.valueOf(request.getAttribute("editGitUrl")));
    String editWebglPath = HtmlUtils.htmlEscape(request.getAttribute("editWebglPath") == null ? "" : String.valueOf(request.getAttribute("editWebglPath")));
    String editThumbnailUrl = HtmlUtils.htmlEscape(request.getAttribute("editThumbnailUrl") == null ? "" : String.valueOf(request.getAttribute("editThumbnailUrl")));
    String editGameUuid = HtmlUtils.htmlEscape(request.getAttribute("editGameUuid") == null ? "" : String.valueOf(request.getAttribute("editGameUuid")));
    boolean editVisible = !editMode || Boolean.TRUE.equals(request.getAttribute("editVisible"));
%>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <jsp:include page="/WEB-INF/views/theme-init.jsp"/>
    <title><%= pageTitle %> | bibimbap</title>
    <style>
      html {
        color-scheme: light;
        --surface: #faf8f5;
        --card-bg: #fff;
        --text: #1a1a1a;
        --text-muted: #5c5c5c;
        --accent: #e8a54b;
        --border: rgba(0, 0, 0, 0.08);
        --card-media-1: #f0ebe3;
        --card-media-2: #e5ddd2;
        --card-media-3: #dccfb8;
        --card-shadow: rgba(0, 0, 0, 0.06);
        --button-text: #1a1a1a;
        --field-bg: #fff;
      }
      html[data-theme="dark"] {
        color-scheme: dark;
        --surface: #121212;
        --card-bg: #1e1e1e;
        --text: #ece8e1;
        --text-muted: #a39e96;
        --border: rgba(255, 255, 255, 0.1);
        --card-media-1: #2a2620;
        --card-media-2: #1f1c18;
        --card-media-3: #3d3528;
        --card-shadow: rgba(0, 0, 0, 0.35);
        --button-text: #1a1a1a;
        --field-bg: #181818;
      }
      body {
        margin: 0;
        min-height: 100vh;
        font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans KR", sans-serif;
        background: var(--surface);
        color: var(--text);
        display: flex;
        flex-direction: column;
      }
      .game-register-main {
        width: 100%;
        max-width: 72rem;
        box-sizing: border-box;
        margin: 0 auto;
        padding: 2rem max(1rem, env(safe-area-inset-left)) 3rem max(1rem, env(safe-area-inset-right));
        flex: 1;
      }
      .game-register-heading {
        width: min(100%, 56rem);
        margin: 0 auto 1rem;
      }
      .game-register-heading__eyebrow {
        margin: 0 0 0.35rem;
        font-size: 0.75rem;
        font-weight: 800;
        color: var(--accent);
        letter-spacing: 0.02em;
      }
      .game-register-heading__title {
        margin: 0;
        font-size: 1.75rem;
        line-height: 1.2;
        letter-spacing: 0;
      }
      .game-register-layout {
        width: min(100%, 56rem);
        margin: 0 auto;
        display: grid;
        grid-template-columns: minmax(0, 1fr) 18rem;
        gap: 1rem;
        align-items: start;
      }
      .game-register-panel,
      .game-preview {
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--card-bg);
        box-shadow: 0 2px 8px var(--card-shadow);
      }
      .game-register-panel {
        padding: 1.5rem;
      }
      .game-form {
        display: grid;
        gap: 1rem;
      }
      .game-form__grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0.875rem;
      }
      .game-field {
        display: grid;
        gap: 0.375rem;
      }
      .game-field--full {
        grid-column: 1 / -1;
      }
      .game-field__label {
        font-size: 0.8125rem;
        font-weight: 700;
        color: var(--text);
      }
      .game-field__input,
      .game-field__textarea {
        width: 100%;
        box-sizing: border-box;
        border: 1px solid var(--border);
        border-radius: 12px;
        background: var(--field-bg);
        color: var(--text);
        font-size: 1rem;
      }
      .game-field__input {
        height: 3rem;
        padding: 0 0.875rem;
      }
      .game-file {
        min-height: 3rem;
        padding: 0.625rem 0.75rem;
        border: 1px solid var(--border);
        border-radius: 12px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        background: var(--field-bg);
        color: var(--text);
        cursor: pointer;
        box-sizing: border-box;
        -webkit-tap-highlight-color: transparent;
      }
      .game-file:hover {
        border-color: rgba(232, 165, 75, 0.45);
      }
      .game-file__action {
        flex-shrink: 0;
        min-height: 2rem;
        border-radius: 8px;
        padding: 0 0.625rem;
        display: inline-flex;
        align-items: center;
        background: rgba(232, 165, 75, 0.18);
        color: var(--text);
        font-size: 0.8125rem;
        font-weight: 800;
      }
      .game-file__name {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: var(--text-muted);
        font-size: 0.875rem;
      }
      .game-file__input {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        border: 0;
      }
      .game-field__textarea {
        min-height: 8rem;
        resize: vertical;
        padding: 0.875rem;
        line-height: 1.55;
      }
      .game-field__input::placeholder,
      .game-field__textarea::placeholder {
        color: var(--text-muted);
      }
      .game-field__input:focus,
      .game-field__textarea:focus {
        outline: none;
        border-color: var(--accent);
        box-shadow: 0 0 0 3px rgba(232, 165, 75, 0.25);
      }
      .game-check {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        font-size: 0.875rem;
        color: var(--text-muted);
      }
      .game-check input {
        width: 1rem;
        height: 1rem;
        accent-color: var(--accent);
      }
      .game-form__actions {
        display: flex;
        justify-content: flex-end;
        gap: 0.625rem;
      }
      .game-button {
        min-height: 2.875rem;
        border: 1px solid var(--border);
        border-radius: 10px;
        padding: 0 1rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 0.5rem;
        background: var(--card-bg);
        color: var(--text);
        font-size: 0.9375rem;
        font-weight: 800;
        text-decoration: none;
        cursor: pointer;
        box-sizing: border-box;
        -webkit-tap-highlight-color: transparent;
      }
      .game-button:hover {
        border-color: rgba(232, 165, 75, 0.45);
        box-shadow: 0 4px 12px var(--card-shadow);
      }
      .game-button:active {
        transform: scale(0.98);
      }
      .game-button--primary {
        border-color: transparent;
        background: var(--accent);
        color: var(--button-text);
      }
      .game-button:disabled {
        cursor: not-allowed;
        opacity: 0.58;
        box-shadow: none;
      }
      .game-button svg {
        width: 1.125rem;
        height: 1.125rem;
      }
      .game-preview {
        overflow: hidden;
        position: sticky;
        top: 5rem;
      }
      .game-preview__media {
        position: relative;
        width: 100%;
        aspect-ratio: 4 / 5;
        background: linear-gradient(160deg, var(--card-media-1) 0%, var(--card-media-2) 45%, var(--card-media-3) 100%);
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 14%;
        box-sizing: border-box;
      }
      .game-preview__media img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        position: absolute;
        inset: 0;
      }
      .game-preview__media img[hidden] {
        display: none;
      }
      .game-preview__fallback {
        width: min(52%, 7.5rem);
        height: auto;
        opacity: 0.88;
        filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.12));
      }
      html[data-theme="dark"] .game-preview__fallback {
        opacity: 0.92;
        filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.45));
      }
      .game-preview__body {
        padding: 0.875rem 1rem 1rem;
      }
      .game-preview__name {
        margin: 0;
        font-size: 1rem;
        line-height: 1.35;
        letter-spacing: 0;
        word-break: break-word;
      }
      .game-preview__creator,
      .game-preview__note {
        margin: 0.35rem 0 0;
        color: var(--text-muted);
        font-size: 0.8125rem;
        line-height: 1.45;
        word-break: break-word;
      }
      .game-preview__note {
        display: -webkit-box;
        -webkit-line-clamp: 4;
        -webkit-box-orient: vertical;
        overflow: hidden;
      }
      @media (max-width: 900px) {
        .game-register-layout {
          grid-template-columns: 1fr;
        }
        .game-preview {
          position: static;
          width: min(100%, 24rem);
        }
      }
      @media (max-width: 560px) {
        .game-register-main {
          padding-top: 1.5rem;
        }
        .game-register-panel {
          padding: 1.25rem;
        }
        .game-form__grid {
          grid-template-columns: 1fr;
        }
        .game-form__actions {
          flex-direction: column-reverse;
        }
        .game-button {
          width: 100%;
        }
      }
    </style>
</head>
<body>
    <jsp:include page="/WEB-INF/views/header.jsp"/>
    <main class="game-register-main">
        <section class="game-register-heading" aria-labelledby="game-register-title">
            <p class="game-register-heading__eyebrow">BIBIMBAP GAME</p>
            <h1 class="game-register-heading__title" id="game-register-title"><%= pageTitle %></h1>
        </section>

        <div class="game-register-layout">
            <section class="game-register-panel" aria-label="게임 등록 양식">
                <form class="game-form" action="<%= formAction %>" method="post" id="game-register-form" data-edit-mode="<%= editMode %>">
                    <div class="game-form__grid">
                        <div class="game-field game-field--full">
                            <label class="game-field__label" for="game-name">게임 이름</label>
                            <input class="game-field__input" type="text" id="game-name" name="name" maxlength="80" autocomplete="off" value="<%= editGameName %>" required />
                        </div>
                        <div class="game-field">
                            <label class="game-field__label" for="game-git-url">소스 코드 URL</label>
                            <input class="game-field__input" type="url" id="game-git-url" name="gitUrl" placeholder="https://example.com/repository" autocomplete="url" value="<%= editGitUrl %>" />
                        </div>
                        <div class="game-field">
                            <label class="game-field__label" for="game-webgl-zip">WebGL zip</label>
                            <label class="game-file" for="game-webgl-zip">
                                <span class="game-file__action">zip 선택</span>
                                <span class="game-file__name" id="game-webgl-file-name"><%= editMode && !editWebglPath.isBlank() ? "기존 WebGL 유지" : "선택된 파일 없음" %></span>
                            </label>
                            <input class="game-file__input" type="file" id="game-webgl-zip" name="webglZip" accept=".zip,application/zip,application/x-zip-compressed" <%= editMode ? "" : "required" %> />
                        </div>
                        <div class="game-field">
                            <label class="game-field__label" for="game-thumbnail-image">썸네일 이미지</label>
                            <label class="game-file" for="game-thumbnail-image">
                                <span class="game-file__action">이미지 선택</span>
                                <span class="game-file__name" id="game-thumbnail-file-name"><%= editMode && !editThumbnailUrl.isBlank() ? "기존 썸네일 유지" : "선택된 파일 없음" %></span>
                            </label>
                            <input class="game-file__input" type="file" id="game-thumbnail-image" name="thumbnailImage" accept="image/png,image/jpeg,image/webp,image/gif" />
                        </div>
                        <div class="game-field game-field--full">
                            <label class="game-field__label" for="game-creator-note">소개</label>
                            <textarea class="game-field__textarea" id="game-creator-note" name="creatorNote" maxlength="600"><%= editCreatorNote %></textarea>
                        </div>
                    </div>
                    <input type="hidden" id="game-uploaded-game-uuid" name="gameUuid" value="<%= editGameUuid %>" />
                    <input type="hidden" id="game-uploaded-webgl-path" name="webglPath" value="<%= editWebglPath %>" />
                    <input type="hidden" id="game-uploaded-thumbnail-url" name="thumbnailUrl" value="<%= editThumbnailUrl %>" />

                    <label class="game-check">
                        <input type="checkbox" name="visible" value="true" <%= editVisible ? "checked" : "" %> />
                        <span>목록에 공개</span>
                    </label>

                    <div class="game-form__actions">
                        <a class="game-button" href="<%= editMode ? ctx + "/game/" + editGameId : ctx + "/" %>">취소</a>
                        <button class="game-button game-button--primary" type="submit" id="game-register-submit">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                                <path d="M12 5v14"/>
                                <path d="M5 12h14"/>
                            </svg>
                            <span id="game-register-submit-label"><%= submitText %></span>
                        </button>
                    </div>
                </form>
            </section>

            <aside class="game-preview" aria-label="미리보기">
                <div class="game-preview__media">
                    <% if (editThumbnailUrl.isBlank()) { %>
                    <img id="preview-thumb" alt="" hidden />
                    <% } else { %>
                    <img id="preview-thumb" src="<%= ctx + editThumbnailUrl %>" alt="" />
                    <% } %>
                    <img class="game-preview__fallback" id="preview-fallback" src="<%= ctx %>/images/logo.png" alt="" width="120" height="120" <%= editThumbnailUrl.isBlank() ? "" : "hidden" %> />
                </div>
                <div class="game-preview__body">
                    <h2 class="game-preview__name" id="preview-name"><%= editGameName.isBlank() ? "게임 이름" : editGameName %></h2>
                    <p class="game-preview__creator" id="preview-creator"><%= creatorValue.isBlank() ? "제작자" : creatorValue %></p>
                    <p class="game-preview__note" id="preview-note"><%= editCreatorNote.isBlank() ? "소개" : editCreatorNote %></p>
                </div>
            </aside>
        </div>
    </main>
    <jsp:include page="/WEB-INF/views/footer.jsp"/>
    <script>
(function () {
  var ctx = '<%= ctx %>';
  var form = document.getElementById('game-register-form');
  var editMode = form && form.getAttribute('data-edit-mode') === 'true';
  var nameInput = document.getElementById('game-name');
  var gitUrlInput = document.getElementById('game-git-url');
  var noteInput = document.getElementById('game-creator-note');
  var webglInput = document.getElementById('game-webgl-zip');
  var thumbnailInput = document.getElementById('game-thumbnail-image');
  var webglFileName = document.getElementById('game-webgl-file-name');
  var thumbnailFileName = document.getElementById('game-thumbnail-file-name');
  var uploadedGameUuid = document.getElementById('game-uploaded-game-uuid');
  var uploadedWebglPath = document.getElementById('game-uploaded-webgl-path');
  var uploadedThumbnailUrl = document.getElementById('game-uploaded-thumbnail-url');
  var visibleInput = form ? form.querySelector('input[name="visible"]') : null;
  var submitBtn = document.getElementById('game-register-submit');
  var submitLabel = document.getElementById('game-register-submit-label');
  var previewName = document.getElementById('preview-name');
  var previewNote = document.getElementById('preview-note');
  var previewThumb = document.getElementById('preview-thumb');
  var previewFallback = document.getElementById('preview-fallback');
  var thumbnailPreviewUrl = null;
  var submitText = submitLabel ? submitLabel.textContent : '';

  function valueOr(input, fallback) {
    var value = input && input.value ? input.value.trim() : '';
    return value || fallback;
  }

  function updatePreview() {
    previewName.textContent = valueOr(nameInput, '게임 이름');
    previewNote.textContent = valueOr(noteInput, '소개');
  }

  function setThumbnailPreview(file) {
    if (thumbnailPreviewUrl) {
      URL.revokeObjectURL(thumbnailPreviewUrl);
      thumbnailPreviewUrl = null;
    }
    if (file) {
      thumbnailPreviewUrl = URL.createObjectURL(file);
      previewThumb.src = thumbnailPreviewUrl;
      previewThumb.hidden = false;
      if (previewFallback) {
        previewFallback.hidden = true;
      }
    } else {
      previewThumb.removeAttribute('src');
      previewThumb.hidden = true;
      if (previewFallback) {
        previewFallback.hidden = false;
      }
    }
  }

  function openModal(title, message, confirmText, onConfirm) {
    if (window.BibimbapModal && typeof window.BibimbapModal.alert === 'function') {
      window.BibimbapModal.alert({
        title: title,
        message: message,
        confirmText: confirmText || '확인',
        onConfirm: onConfirm
      });
      return;
    }
    alert(message);
    if (typeof onConfirm === 'function') {
      onConfirm();
    }
  }

  function setSubmitting(submitting) {
    if (!submitBtn) return;
    submitBtn.disabled = submitting;
    if (submitLabel) {
      submitLabel.textContent = submitting ? (editMode ? '수정 중...' : '등록 중...') : submitText;
    }
  }

  function uploadFile(url, file, fields) {
    var body = new FormData();
    body.append('file', file);
    if (fields) {
      Object.keys(fields).forEach(function (key) {
        body.append(key, fields[key]);
      });
    }
    return fetch(url, {
      method: 'POST',
      headers: window.BibimbapCsrf ? window.BibimbapCsrf.headers({
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      }) : {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      body: body
    }).catch(function () {
      throw new Error('Upload request failed before receiving a server response. Please check the server console and browser Network tab.');
    }).then(function (res) {
      return res.json().catch(function () {
        return { message: '파일을 업로드하지 못했습니다.' };
      }).then(function (data) {
        if (!res.ok) {
          var error = new Error(data && data.message ? data.message : '파일을 업로드하지 못했습니다.');
          error.status = res.status;
          throw error;
        }
        return data;
      });
    });
  }

  function saveGame() {
    var body = new URLSearchParams();
    body.set('name', valueOr(nameInput, ''));
    body.set('gitUrl', valueOr(gitUrlInput, ''));
    body.set('creatorNote', valueOr(noteInput, ''));
    body.set('gameUuid', valueOr(uploadedGameUuid, ''));
    body.set('webglPath', valueOr(uploadedWebglPath, ''));
    body.set('thumbnailUrl', valueOr(uploadedThumbnailUrl, ''));
    if (visibleInput && visibleInput.checked) {
      body.set('visible', visibleInput.value || 'true');
    }

    return fetch(form.action, {
      method: 'POST',
      headers: window.BibimbapCsrf ? window.BibimbapCsrf.headers({
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      }) : {
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      body: body
    }).then(function (res) {
      return res.json().catch(function () {
        return { message: '게임을 등록하지 못했습니다.' };
      }).then(function (data) {
        if (!res.ok) {
          var error = new Error(data && data.message ? data.message : '게임을 등록하지 못했습니다.');
          error.status = res.status;
          throw error;
        }
        return data;
      });
    });
  }

  if (nameInput) nameInput.addEventListener('input', updatePreview);
  if (noteInput) noteInput.addEventListener('input', updatePreview);
  if (webglInput) {
    webglInput.addEventListener('change', function () {
      var file = webglInput.files && webglInput.files[0];
      webglFileName.textContent = file ? file.name : '선택된 파일 없음';
      if (uploadedWebglPath) {
        uploadedWebglPath.value = '';
      }
      if (uploadedGameUuid) {
        uploadedGameUuid.value = '';
      }
    });
  }
  if (thumbnailInput) {
    thumbnailInput.addEventListener('change', function () {
      var file = thumbnailInput.files && thumbnailInput.files[0];
      thumbnailFileName.textContent = file ? file.name : '선택된 파일 없음';
      if (uploadedThumbnailUrl) {
        uploadedThumbnailUrl.value = '';
      }
      if (file && file.type && file.type.indexOf('image/') === 0) {
        setThumbnailPreview(file);
      } else {
        setThumbnailPreview(null);
        if (file) {
          thumbnailInput.value = '';
          thumbnailFileName.textContent = '선택된 파일 없음';
          openModal('썸네일 선택 실패', '이미지 파일만 선택해 주세요.');
        }
      }
    });
  }

  if (previewThumb) {
    previewThumb.addEventListener('error', function () {
      previewThumb.removeAttribute('src');
      previewThumb.hidden = true;
      if (previewFallback) {
        previewFallback.hidden = false;
      }
    });
  }

  if (form) {
    form.addEventListener('submit', function (ev) {
      ev.preventDefault();
      if (!form.checkValidity()) {
        form.reportValidity();
        return;
      }

      var webglFile = webglInput && webglInput.files ? webglInput.files[0] : null;
      var thumbnailFile = thumbnailInput && thumbnailInput.files ? thumbnailInput.files[0] : null;
      if (!editMode && !webglFile) {
        openModal('업로드 실패', 'WebGL zip 파일을 선택해 주세요.');
        return;
      }

      setSubmitting(true);
      (webglFile ? uploadFile(ctx + '/api/game-files/webgl-zip', webglFile) : Promise.resolve({
        gameUuid: uploadedGameUuid ? uploadedGameUuid.value : '',
        webglPath: uploadedWebglPath ? uploadedWebglPath.value : ''
      })).then(function (webglResult) {
        if (uploadedGameUuid && webglResult && webglResult.gameUuid) {
          uploadedGameUuid.value = webglResult.gameUuid;
        }
        if (uploadedWebglPath && webglResult && webglResult.webglPath) {
          uploadedWebglPath.value = webglResult.webglPath;
        }
        if (!thumbnailFile) {
          return {
            webglResult: webglResult,
            thumbnailResult: null
          };
        }
        return uploadFile(ctx + '/api/game-files/thumbnail', thumbnailFile, {
          gameUuid: webglResult.gameUuid
        }).then(function (thumbnailResult) {
          return {
            webglResult: webglResult,
            thumbnailResult: thumbnailResult
          };
        });
      }).then(function (results) {
        var thumbnailResult = results.thumbnailResult;
        if (uploadedThumbnailUrl && thumbnailResult && thumbnailResult.thumbnailUrl) {
          uploadedThumbnailUrl.value = thumbnailResult.thumbnailUrl;
        }
        return saveGame();
      }).then(function (registerResult) {
        openModal(editMode ? '게임 수정 완료' : '게임 등록 완료', editMode ? '게임이 수정되었습니다.' : '게임 등록이 완료되었습니다.', '확인', function () {
          if (registerResult && registerResult.gameId) {
            window.location.href = ctx + '/game/' + registerResult.gameId;
          } else if (registerResult && registerResult.location) {
            window.location.href = ctx + registerResult.location;
          } else {
            window.location.href = ctx + '/';
          }
        });
      }).catch(function (err) {
        openModal('등록 실패', err.message || '게임을 등록하지 못했습니다.', '확인', function () {
          if (err.status === 401) {
            window.location.href = ctx + '/login';
          }
        });
      }).finally(function () {
        setSubmitting(false);
      });
    });
  }

  updatePreview();
})();
    </script>
</body>
</html>
