市场夺宝奇兵
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

799 lines
25 KiB

9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width,initial-scale=1" />
  6. <title>管理后台 · Adam说港股导流</title>
  7. <style>
  8. .tab-container {
  9. max-width: 1200px;
  10. margin: 0 0 12px 0;
  11. padding: 0 16px;
  12. }
  13. .tabs {
  14. display: flex;
  15. gap: 50px;
  16. padding: 4px;
  17. border-radius: 8px;
  18. width: fit-content;
  19. }
  20. .tab {
  21. padding: 10px 20px;
  22. border-radius: 6px;
  23. border: none;
  24. background: transparent;
  25. color: #131212;
  26. font-weight: 700;
  27. cursor: pointer;
  28. transition: all 0.3s ease;
  29. font-size: 16px;
  30. white-space: nowrap;
  31. }
  32. .tab:hover {
  33. background: rgba(46, 125, 50, 0.1);
  34. color: #25D366;
  35. }
  36. .tab.active {
  37. background: #BAF7D0;
  38. color: #0E4322;
  39. box-shadow: 0 2px 4px rgba(46, 125, 50, 0.3);
  40. }
  41. * {
  42. box-sizing: border-box;
  43. }
  44. body {
  45. font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  46. padding: 24px;
  47. background: #f0f2f6;
  48. color: #1e293b;
  49. margin: 0;
  50. }
  51. .card {
  52. background: #ffffff;
  53. padding: 20px 16px 24px 16px;
  54. border-radius: 20px;
  55. box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05);
  56. max-width: 100%;
  57. overflow-x: auto;
  58. }
  59. .table-wrapper {
  60. overflow-x: auto;
  61. border-radius: 14px;
  62. margin-top: 8px;
  63. }
  64. table {
  65. width: 100%;
  66. border-collapse: collapse;
  67. min-width: 1000px;
  68. font-size: 13.5px;
  69. }
  70. th,
  71. td {
  72. padding: 12px 10px;
  73. border-bottom: 1px solid #e9edf2;
  74. text-align: center;
  75. vertical-align: middle;
  76. }
  77. th {
  78. background: #f8fafc;
  79. font-weight: 600;
  80. color: #1e293b;
  81. letter-spacing: 0.3px;
  82. white-space: nowrap;
  83. }
  84. td {
  85. white-space: nowrap;
  86. overflow: hidden;
  87. text-overflow: ellipsis;
  88. max-width: 180px;
  89. }
  90. td:nth-child(1) {
  91. max-width: 55px;
  92. }
  93. td:nth-child(2) {
  94. max-width: 100px;
  95. }
  96. td:nth-child(3) {
  97. max-width: 100px;
  98. overflow: visible;
  99. white-space: normal;
  100. }
  101. td:nth-child(4) {
  102. max-width: 90px;
  103. }
  104. td:nth-child(5) {
  105. max-width: 120px;
  106. }
  107. td:nth-child(6) {
  108. max-width: 120px;
  109. }
  110. td:nth-child(7) {
  111. max-width: 150px;
  112. }
  113. td:nth-child(8) {
  114. max-width: 120px;
  115. }
  116. td:nth-child(9) {
  117. max-width: 100px;
  118. }
  119. td:nth-child(10) {
  120. max-width: 160px;
  121. }
  122. td:nth-child(11) {
  123. max-width: 100px;
  124. white-space: normal;
  125. }
  126. td:nth-child(12) {
  127. max-width: 160px;
  128. }
  129. td:nth-child(13) {
  130. max-width: 100px;
  131. white-space: normal;
  132. }
  133. td[title] {
  134. cursor: help;
  135. }
  136. .controls {
  137. display: flex;
  138. gap: 16px;
  139. align-items: center;
  140. flex-wrap: wrap;
  141. margin-top: 20px;
  142. background: #ffffff;
  143. padding: 8px 4px;
  144. }
  145. .pagination {
  146. display: flex;
  147. gap: 6px;
  148. align-items: center;
  149. margin-left: auto;
  150. flex-wrap: wrap;
  151. }
  152. .btn {
  153. padding: 6px 12px;
  154. border-radius: 30px;
  155. border: 1px solid #d4d9e2;
  156. background: #fff;
  157. cursor: pointer;
  158. font-size: 12.5px;
  159. font-weight: 500;
  160. transition: all 0.2s ease;
  161. }
  162. .btn:hover:not(:disabled) {
  163. background-color: #f1f5f9;
  164. border-color: #94a3b8;
  165. }
  166. .btn:disabled {
  167. opacity: 0.5;
  168. cursor: not-allowed;
  169. }
  170. .btn.primary {
  171. background: #2563eb;
  172. color: white;
  173. border-color: #2563eb;
  174. }
  175. .btn.primary:hover:not(:disabled) {
  176. background: #1d4ed8;
  177. }
  178. .btn.whatsapp {
  179. background: #25D366;
  180. color: #fff;
  181. border-color: #1da15a;
  182. }
  183. .btn.whatsapp:hover {
  184. background: #20b859;
  185. }
  186. .status-btn {
  187. padding: 5px 12px;
  188. border-radius: 24px;
  189. border: none;
  190. font-weight: 500;
  191. cursor: pointer;
  192. font-size: 12px;
  193. transition: 0.1s;
  194. }
  195. .status-0 {
  196. background: #fee2e2;
  197. color: #b91c1c;
  198. border: 1px solid #fecaca;
  199. }
  200. .status-1 {
  201. background: #dcfce7;
  202. color: #15803d;
  203. border: 1px solid #bbf7d0;
  204. }
  205. .btn.active {
  206. background: #2563eb;
  207. color: white;
  208. border-color: #2563eb;
  209. }
  210. select,
  211. input[type="number"] {
  212. padding: 6px 12px;
  213. border-radius: 30px;
  214. border: 1px solid #cbd5e1;
  215. background: white;
  216. font-size: 13px;
  217. }
  218. .small {
  219. font-size: 13px;
  220. color: #475569;
  221. }
  222. @media (max-width: 720px) {
  223. .controls {
  224. flex-direction: column;
  225. align-items: stretch;
  226. }
  227. .pagination {
  228. margin-left: 0;
  229. justify-content: center;
  230. }
  231. }
  232. #noteModal {
  233. display: none;
  234. position: fixed;
  235. inset: 0;
  236. background: rgba(0, 0, 0, 0.5);
  237. backdrop-filter: blur(3px);
  238. align-items: center;
  239. justify-content: center;
  240. z-index: 10000;
  241. }
  242. #noteModal .dialog {
  243. background: #fff;
  244. padding: 24px;
  245. border-radius: 28px;
  246. width: 90%;
  247. max-width: 520px;
  248. box-shadow: 0 25px 40px rgba(0, 0, 0, 0.2);
  249. }
  250. #noteModal textarea {
  251. width: 100%;
  252. min-height: 130px;
  253. padding: 12px;
  254. border-radius: 18px;
  255. border: 1px solid #cbd5e1;
  256. font-size: 14px;
  257. font-family: inherit;
  258. resize: vertical;
  259. }
  260. .toast {
  261. position: fixed;
  262. top: 24px;
  263. left: 50%;
  264. transform: translateX(-50%) translateY(-30px);
  265. background: #1e293b;
  266. color: white;
  267. padding: 10px 20px;
  268. border-radius: 60px;
  269. font-size: 14px;
  270. font-weight: 500;
  271. opacity: 0;
  272. transition: all 0.2s ease;
  273. z-index: 11000;
  274. pointer-events: none;
  275. box-shadow: 0 6px 14px rgba(0, 0, 0, 0.1);
  276. }
  277. .toast.show {
  278. opacity: 1;
  279. transform: translateX(-50%) translateY(0);
  280. }
  281. #loginCheckModal {
  282. display: none;
  283. position: fixed;
  284. inset: 0;
  285. background: rgba(0, 0, 0, 0.75);
  286. align-items: center;
  287. justify-content: center;
  288. z-index: 99999;
  289. }
  290. #loginCheckModal .dialog {
  291. background: #fff;
  292. padding: 32px;
  293. border-radius: 32px;
  294. width: 90%;
  295. max-width: 380px;
  296. text-align: center;
  297. }
  298. #loginCheckModal h3 {
  299. margin: 0 0 12px;
  300. color: #e11d48;
  301. }
  302. .dialog-buttons {
  303. margin-top: 20px;
  304. display: flex;
  305. justify-content: flex-end;
  306. gap: 12px;
  307. }
  308. </style>
  309. </head>
  310. <body>
  311. <div id="loginCheckModal">
  312. <div class="dialog">
  313. <h3>🔐 访问被拒绝</h3>
  314. <p>您尚未登录或登录已过期,请重新登录系统。</p>
  315. <button class="btn primary" id="goToLoginBtn">前往登录页面</button>
  316. </div>
  317. </div>
  318. <div class="tab-container">
  319. <div class="tabs">
  320. <button class="tab active" data-tab="hk-stock">Adam说港股导流</button>
  321. </div>
  322. </div>
  323. <div class="card">
  324. <div class="table-wrapper">
  325. <table aria-describedby="成员反馈列表">
  326. <thead>
  327. <tr>
  328. <th style="width: 50px">序号</th>
  329. <th style="width: 100px">姓名</th>
  330. <th style="width: 100px">WhatsApp</th>
  331. <th style="width: 90px">国家/地区代码</th>
  332. <th style="width: 120px">电话号码</th>
  333. <th style="width: 120px">微信ID</th>
  334. <th style="width: 150px">邮箱</th>
  335. <th style="width: 130px">反馈内容</th>
  336. <th style="width: 100px">反馈类型</th>
  337. <th style="width: 160px">添加时间</th>
  338. <th style="width: 100px">是否联系</th>
  339. <th style="width: 160px">备注</th>
  340. <th style="width: 100px">操作</th>
  341. </tr>
  342. </thead>
  343. <tbody id="tableBody"></tbody>
  344. </table>
  345. </div>
  346. <div class="controls">
  347. <div class="small">
  348. 每页显示
  349. <select id="pageSizeSelect">
  350. <option value="20" selected>20</option>
  351. <option value="50">50</option>
  352. <option value="100">100</option>
  353. <option value="200">200</option>
  354. </select>
  355. </div>
  356. <div class="small"><span id="totalCount">0</span></div>
  357. <div class="pagination" id="pagination"></div>
  358. </div>
  359. </div>
  360. <div id="noteModal">
  361. <div class="dialog">
  362. <h3 style="margin-top: 0;">✏️ 编辑备注</h3>
  363. <textarea id="noteTextarea" rows="4" placeholder="输入备注信息..."></textarea>
  364. <div class="dialog-buttons">
  365. <button class="btn" id="noteCancelBtn">取消</button>
  366. <button class="btn primary" id="noteSaveBtn">保存</button>
  367. </div>
  368. </div>
  369. </div>
  370. <div id="toast" class="toast"></div>
  371. <script type="module">
  372. import { getMemberListApi, updateMemberStateApi, editMemberNoteApi } from './src/api/hkmember.js'
  373. // ========== 登录验证 ==========
  374. function checkLoginStatus() {
  375. const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
  376. const loginTime = parseInt(localStorage.getItem('loginTime'), 10);
  377. if (!isLoggedIn || isNaN(loginTime)) return false;
  378. const hoursDiff = (new Date().getTime() - loginTime) / (1000 * 60 * 60);
  379. return hoursDiff < 24;
  380. }
  381. function showLoginCheckModal() {
  382. const modal = document.getElementById('loginCheckModal');
  383. if (modal) modal.style.display = 'flex';
  384. }
  385. function hideLoginCheckModal() {
  386. const modal = document.getElementById('loginCheckModal');
  387. if (modal) modal.style.display = 'none';
  388. }
  389. function redirectToLogin() {
  390. window.location.href = 'hkLogiManagement.html';
  391. }
  392. function requireAuth() {
  393. if (!checkLoginStatus()) {
  394. showLoginCheckModal();
  395. return false;
  396. }
  397. return true;
  398. }
  399. document.getElementById('goToLoginBtn')?.addEventListener('click', redirectToLogin);
  400. // ========== 映射反馈类型文字 ==========
  401. function formatFeedbackType(typeValue) {
  402. const val = parseInt(typeValue, 10);
  403. switch (val) {
  404. case 1: return '功能建议';
  405. case 2: return '问题反馈';
  406. case 3: return '体验优化';
  407. case 4: return '其他建议';
  408. default: return typeValue || '—';
  409. }
  410. }
  411. // ========== 状态管理 ==========
  412. let state = {
  413. pageSize: 20,
  414. currentPage: 1,
  415. total: 0,
  416. items: []
  417. };
  418. const tableBody = document.getElementById("tableBody");
  419. const paginationEl = document.getElementById("pagination");
  420. const totalCountEl = document.getElementById("totalCount");
  421. const pageSizeSelect = document.getElementById("pageSizeSelect");
  422. const noteModal = document.getElementById("noteModal");
  423. const noteTextarea = document.getElementById("noteTextarea");
  424. const noteCancelBtn = document.getElementById("noteCancelBtn");
  425. const noteSaveBtn = document.getElementById("noteSaveBtn");
  426. const toastEl = document.getElementById("toast");
  427. let editingRowId = null;
  428. function showToast(msg, isError = false) {
  429. toastEl.textContent = msg;
  430. toastEl.style.background = isError ? '#e11d48' : '#1e293b';
  431. toastEl.classList.add("show");
  432. setTimeout(() => {
  433. toastEl.classList.remove("show");
  434. toastEl.style.background = '#1e293b';
  435. }, 1800);
  436. }
  437. // ========== 获取数据 ==========
  438. async function fetchPage(page, pageSize) {
  439. if (!requireAuth()) return { items: [], total: 0 };
  440. try {
  441. const res = await getMemberListApi({
  442. page: page,
  443. page_size: pageSize,
  444. });
  445. if (res && typeof res.code !== "undefined" && res.code !== 200) {
  446. throw new Error(res.msg || "接口异常");
  447. }
  448. const payload = res?.data || {};
  449. state.items = payload.list || [];
  450. state.total = payload.total || 0;
  451. return { items: state.items, total: state.total };
  452. } catch (err) {
  453. console.error(err);
  454. showToast("获取数据失败: " + (err.message || '网络错误'), true);
  455. state.items = [];
  456. state.total = 0;
  457. return { items: [], total: 0 };
  458. }
  459. }
  460. // ========== WhatsApp 跳转(与美股页面完全一致的逻辑) ==========
  461. function handleWhatsApp(id) {
  462. const item = state.items.find((it) => String(it.id) === String(id));
  463. if (!item) return;
  464. // 移除国家代码中的+号
  465. const cleanCode = (item.code || '').replace(/\+/g, '');
  466. const whatsappPhone = cleanCode + (item.telephone || '');
  467. if (!whatsappPhone) {
  468. showToast("电话号码无效,无法跳转", true);
  469. return;
  470. }
  471. const whatsappUrl = `https://api.whatsapp.com/send?phone=${encodeURIComponent(whatsappPhone)}&text=${encodeURIComponent('hello欢迎来到Adam说港股')}`;
  472. window.open(whatsappUrl, '_blank');
  473. }
  474. // ========== 渲染表格 ==========
  475. function renderTable() {
  476. const startIndex = (state.currentPage - 1) * state.pageSize;
  477. const items = state.items || [];
  478. tableBody.innerHTML = items.map((item, idx) => {
  479. const serial = startIndex + idx + 1;
  480. const statusClass = item.isRelated ? "status-1" : "status-0";
  481. const statusText = item.isRelated ? "已联系" : "未联系";
  482. const feedbackTypeText = formatFeedbackType(item.feedback_type);
  483. // 安全转义
  484. const name = escapeHtml(item.name || "");
  485. const code = escapeHtml(item.code || "");
  486. const telephone = escapeHtml(item.telephone || "");
  487. const wechat = escapeHtml(item.wechat || "");
  488. const email = escapeHtml(item.email || "");
  489. const feedbackContent = escapeHtml(item.feedback_content || "");
  490. const createdAt = escapeHtml(item.createdAt || "");
  491. const note = escapeHtml(item.note || "");
  492. return `
  493. <tr>
  494. <td title="${serial}">${serial}</td>
  495. <td title="${name}">${name}</td>
  496. <td style="overflow: visible; white-space: normal;">
  497. <button class="btn whatsapp" data-action="whatsapp" data-id="${item.id}">💬 WhatsApp</button>
  498. </td>
  499. <td title="${code}">${code}</td>
  500. <td title="${telephone}">${telephone}</td>
  501. <td title="${wechat}">${wechat}</td>
  502. <td title="${email}">${email}</td>
  503. <td title="${feedbackContent}">${feedbackContent}</td>
  504. <td title="${feedbackTypeText}">${feedbackTypeText}</td>
  505. <td title="${createdAt}">${createdAt}</td>
  506. <td style="white-space: normal;">
  507. <button class="status-btn ${statusClass}" data-action="toggle" data-id="${item.id}">${statusText}</button>
  508. </td>
  509. <td title="${note}">${note}</td>
  510. <td>
  511. <button class="btn" data-action="editNote" data-id="${item.id}" style="font-size:12px;">✎ 备注</button>
  512. </td>
  513. </tr>
  514. `;
  515. }).join("");
  516. totalCountEl.textContent = state.total;
  517. }
  518. // ========== 切换联系状态 ==========
  519. async function handleToggle(id, btnEl) {
  520. const item = state.items.find((it) => String(it.id) === String(id));
  521. if (!item) return;
  522. const prev = item.isRelated;
  523. const newVal = prev ? 0 : 1;
  524. // 乐观更新UI
  525. item.isRelated = newVal;
  526. btnEl.textContent = newVal ? "已联系" : "未联系";
  527. btnEl.classList.toggle("status-1", !!newVal);
  528. btnEl.classList.toggle("status-0", !newVal);
  529. try {
  530. const res = await updateMemberStateApi({ id: item.id, state: newVal });
  531. if (res && typeof res.code !== "undefined" && res.code !== 200) {
  532. throw new Error(res.msg || "更新失败");
  533. }
  534. showToast("状态已更新");
  535. } catch (err) {
  536. // 回滚
  537. item.isRelated = prev;
  538. btnEl.textContent = prev ? "已联系" : "未联系";
  539. btnEl.classList.toggle("status-1", !!prev);
  540. btnEl.classList.toggle("status-0", !prev);
  541. showToast("更新失败: " + (err.message || '网络错误'), true);
  542. }
  543. }
  544. // ========== 备注编辑 ==========
  545. function openNoteModal(id) {
  546. if (!requireAuth()) return;
  547. const item = state.items.find((it) => String(it.id) === String(id));
  548. if (!item) return;
  549. editingRowId = id;
  550. noteTextarea.value = item.note || "";
  551. noteModal.style.display = "flex";
  552. noteTextarea.focus();
  553. }
  554. function closeNoteModal() {
  555. editingRowId = null;
  556. noteTextarea.value = "";
  557. noteModal.style.display = "none";
  558. }
  559. noteCancelBtn.addEventListener("click", closeNoteModal);
  560. noteSaveBtn.addEventListener("click", async () => {
  561. if (!requireAuth()) return;
  562. if (!editingRowId) return closeNoteModal();
  563. const newNote = noteTextarea.value.trim();
  564. const item = state.items.find((it) => String(it.id) === String(editingRowId));
  565. if (!item) return closeNoteModal();
  566. const oldNote = item.note;
  567. item.note = newNote;
  568. renderTable();
  569. try {
  570. const res = await editMemberNoteApi({ id: item.id, note: newNote });
  571. if (res && typeof res.code !== "undefined" && res.code !== 200) {
  572. throw new Error(res.msg || "保存失败");
  573. }
  574. showToast("备注保存成功");
  575. } catch (err) {
  576. item.note = oldNote;
  577. renderTable();
  578. showToast("保存备注失败: " + (err.message || '接口错误'), true);
  579. } finally {
  580. closeNoteModal();
  581. }
  582. });
  583. // ========== 事件监听 ==========
  584. tableBody.addEventListener("click", async (e) => {
  585. if (!requireAuth()) return;
  586. const whatsappBtn = e.target.closest('[data-action="whatsapp"]');
  587. if (whatsappBtn) {
  588. const id = whatsappBtn.getAttribute("data-id");
  589. handleWhatsApp(id);
  590. return;
  591. }
  592. const toggler = e.target.closest('[data-action="toggle"]');
  593. if (toggler) {
  594. const id = toggler.getAttribute("data-id");
  595. await handleToggle(id, toggler);
  596. return;
  597. }
  598. const editBtn = e.target.closest('[data-action="editNote"]');
  599. if (editBtn) {
  600. const id = editBtn.getAttribute("data-id");
  601. openNoteModal(id);
  602. return;
  603. }
  604. });
  605. // ========== 分页 ==========
  606. function renderPagination() {
  607. const totalPages = Math.max(1, Math.ceil(state.total / state.pageSize));
  608. let current = Math.min(Math.max(1, state.currentPage), totalPages);
  609. state.currentPage = current;
  610. const pages = buildPageList(current, totalPages, 2);
  611. let html = '';
  612. html += `<button class="btn" data-action="prev" ${current === 1 ? 'disabled' : ''}>◀ 上一页</button>`;
  613. pages.forEach(p => {
  614. if (p === '...') {
  615. html += `<span class="small" style="padding:0 6px;">...</span>`;
  616. } else {
  617. html += `<button class="btn ${p === current ? 'active' : ''}" data-page="${p}">${p}</button>`;
  618. }
  619. });
  620. html += `<button class="btn" data-action="next" ${current === totalPages ? 'disabled' : ''}>下一页 ▶</button>`;
  621. paginationEl.innerHTML = html;
  622. }
  623. function buildPageList(current, total, delta) {
  624. const pages = [];
  625. const left = Math.max(1, current - delta);
  626. const right = Math.min(total, current + delta);
  627. if (left > 1) {
  628. pages.push(1);
  629. if (left > 2) pages.push('...');
  630. }
  631. for (let i = left; i <= right; i++) pages.push(i);
  632. if (right < total) {
  633. if (right < total - 1) pages.push('...');
  634. pages.push(total);
  635. }
  636. return pages;
  637. }
  638. paginationEl.addEventListener("click", (e) => {
  639. if (!requireAuth()) return;
  640. const btn = e.target.closest("button");
  641. if (!btn) return;
  642. const action = btn.getAttribute("data-action");
  643. if (action === "prev") {
  644. if (state.currentPage > 1) state.currentPage--;
  645. } else if (action === "next") {
  646. const totalPages = Math.max(1, Math.ceil(state.total / state.pageSize));
  647. if (state.currentPage < totalPages) state.currentPage++;
  648. } else {
  649. const p = Number(btn.getAttribute("data-page"));
  650. if (!isNaN(p) && p > 0) state.currentPage = p;
  651. }
  652. update();
  653. });
  654. pageSizeSelect.addEventListener("change", () => {
  655. if (!requireAuth()) return;
  656. const newSize = parseInt(pageSizeSelect.value, 10);
  657. state.pageSize = newSize;
  658. state.currentPage = 1;
  659. update();
  660. });
  661. async function update() {
  662. if (!requireAuth()) return;
  663. await fetchPage(state.currentPage, state.pageSize);
  664. renderTable();
  665. renderPagination();
  666. }
  667. function escapeHtml(s) {
  668. if (s === undefined || s === null) return '';
  669. return String(s).replace(/[&<>]/g, function (m) {
  670. if (m === '&') return '&amp;';
  671. if (m === '<') return '&lt;';
  672. if (m === '>') return '&gt;';
  673. return m;
  674. });
  675. }
  676. // ========== 初始化 ==========
  677. if (checkLoginStatus()) {
  678. update();
  679. } else {
  680. showLoginCheckModal();
  681. }
  682. window.addEventListener('focus', () => {
  683. if (checkLoginStatus() && document.getElementById('loginCheckModal')?.style.display === 'flex') {
  684. hideLoginCheckModal();
  685. update();
  686. } else if (!checkLoginStatus() && document.getElementById('loginCheckModal')?.style.display !== 'flex') {
  687. showLoginCheckModal();
  688. }
  689. });
  690. </script>
  691. </body>
  692. </html>