Files
hair/static/integration.html
T
xsl 28255ef7c2 feat: 接口5 新增 face_measure(复用接口1测量数值)+ 接口1 七眼 eye1~eye7
接口5(/api/v1/hairline/generate)在发际线结果基础上新增 data.face_measure,
复用接口1的四庭七眼测量数值(四庭/七眼 eye1~eye7/landmarks/姿态),
不含标注图;独立流程容错,测量失败时为 null 不影响发际线主结果。

重构:提取 _run_face_measure_data() 共用函数,接口1/6 改调它再补标注图,
行为不变(43 测试全过,错误码 1001/1003/1008 回归正常)。

接口1/5 七眼新增 eye1~eye7 从左到右 7 段宽度(cm),eye1/eye7 耳朵不可见
时为 null(保留键)。

测试页 test_interface5.html:移除点击切换卡片网格改为所有发型平铺,
新增四庭七眼测量卡片。前端接入页 integration.html / 接口文档同步更新。
2026-07-13 22:40:55 +08:00

360 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>旷视五接口 — 前端接入说明</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f8f9fb; color: #1e293b; line-height: 1.6; }
.wrap { max-width: 960px; margin: 0 auto; padding: 32px 24px; }
h1 { font-size: 26px; margin-bottom: 8px; }
.subtitle { color: #64748b; font-size: 14px; margin-bottom: 32px; }
.card { background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.05); margin-bottom: 24px; overflow: hidden; }
.card h2 { font-size: 16px; padding: 16px 20px; border-bottom: 1px solid #f1f5f9; background: #fafbfc; }
.card-body { padding: 18px 20px; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #f1f5f9; }
th { background: #f8fafc; font-weight: 700; color: #475569; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
tr:last-child td { border-bottom: none; }
code { font-family: "SF Mono", "Fira Code", monospace; font-size: 12.5px; background: #f1f5f9; padding: 2px 6px; border-radius: 4px; color: #0f172a; }
pre { background: #1e293b; color: #e2e8f0; padding: 16px 20px; border-radius: 8px; font-family: "SF Mono", "Fira Code", monospace; font-size: 12.5px; line-height: 1.5; overflow-x: auto; }
.badge { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 11px; font-weight: 700; }
.badge.post { background: #dbeafe; color: #1e40af; }
.badge.get { background: #d1fae5; color: #065f46; }
.badge.warn { background: #fef3c7; color: #92400e; }
.endpoint { margin-bottom: 20px; }
.endpoint .url { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.endpoint .desc { color: #64748b; font-size: 13px; margin-bottom: 10px; }
.endpoint .params { font-size: 12px; color: #94a3b8; margin-bottom: 8px; }
.link { color: #2563eb; text-decoration: none; font-size: 13px; }
.link:hover { text-decoration: underline; }
.toc { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 24px; }
.toc a { font-size: 13px; color: #2563eb; text-decoration: none; padding: 4px 12px; background: #eff6ff; border-radius: 6px; }
.toc a:hover { background: #dbeafe; }
hr { border: none; border-top: 1px solid #e2e8f0; margin: 20px 0; }
</style>
</head>
<body>
<div class="wrap">
<h1>📡 旷视五接口 — 前端接入说明</h1>
<p class="subtitle">Base URL: <code>https://hair.xiangsilian.com</code> &nbsp;|&nbsp; 在线文档: <a href="/docs" class="link">/docs</a> &nbsp;|&nbsp; 在线测试页见底部</p>
<div class="toc">
<a href="#overview">通用约定</a>
<a href="#if1">接口1</a>
<a href="#if2">接口2</a>
<a href="#if3">接口3</a>
<a href="#if4">接口4</a>
<a href="#if5">接口5</a>
<a href="#if6">接口6</a>
<a href="#if7">接口7</a>
<a href="#errors">错误码</a>
<a href="#test">在线测试</a>
</div>
<!-- ======== 通用约定 ======== -->
<div class="card" id="overview">
<h2>🔧 通用约定</h2>
<div class="card-body">
<table>
<tr><td>协议</td><td>HTTPS</td></tr>
<tr><td>请求方式</td><td>全部 <span class="badge post">POST</span></td></tr>
<tr><td>编码</td><td>UTF-8</td></tr>
<tr><td>Content-Type</td><td><code>multipart/form-data</code></td></tr>
<tr><td>图片参数</td><td>三选一:<code>image_file</code>(文件上传)/ <code>image_url</code>URL/ <code>image_base64</code>base64 + 前缀)</td></tr>
<tr><td>图片格式</td><td>JPG / PNG,单人正面照</td></tr>
</table>
<p style="margin-top:14px;font-size:13px"><strong>统一响应结构</strong></p>
<pre>{
"code": 0, // 0=成功,非0=错误
"message": "success",
"request_id": "...", // 请求追踪 ID
"data": { ... } // 业务数据,各接口不同
}</pre>
</div>
</div>
<!-- ======== 接口1 ======== -->
<div class="card" id="if1">
<h2>1. 四庭七眼测量 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/measure</code></h2>
<div class="card-body">
<p class="desc">上传正面照 → 返回标注好的 PNG(仅标注图层,透明底)+ 四庭七眼厘米数值 + 关键点像素坐标。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file</td><td>file</td><td>三选一</td><td>上传图片文件</td></tr>
<tr><td>image_url</td><td>string</td><td>三选一</td><td>图片 URL</td></tr>
<tr><td>image_base64</td><td>string</td><td>三选一</td><td>base64 字符串,需带 data:image/...;base64, 前缀</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>annotated_image_url</code></td><td>string</td><td>标注 PNG URL(仅标注图层,透明底,叠加到原图上显示)</td></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>全脸高度(cm= 四庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>四庭:top/upper/middle/lower,各含 <code>_cm</code><code>ratios</code></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:<code>eye_width_cm</code>/<code>face_width_cm</code>/<code>inter_eye_distance_cm</code> + <code>ratios</code> + <code>eye1</code>~<code>eye7</code>(从左到右 7 段宽度 cm<code>eye1</code>/<code>eye7</code> 耳朵不可见时为 null</td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>5 个关键点像素坐标:hair_top/hairline/brow_center/nose_bottom/chin_tip</td></tr>
<tr><td><code>hairline_source</code></td><td>string</td><td>发际线来源:<code>"segmentation"</code>(真实分割,可信度高)/ <code>"estimated"</code>(比例估算,可信度低)</td></tr>
<tr><td><code>head_pose</code></td><td>object</td><td>头部姿态角度:<code>{ yaw, pitch, roll }</code>(度),接近 0 表示正面照</td></tr>
</table>
<p style="margin-top:12px;font-size:12px;color:#64748b">💡 前端把标注图叠加到原图上即可呈现测量效果(标注图白色线条 #FFFFFF,透明底)。</p>
<p style="margin-top:8px"><strong>请求示例</strong>fetch):</p>
<pre>const fd = new FormData();
fd.append('image_file', file); // 或 image_url / image_base64
const res = await fetch('https://hair.xiangsilian.com/api/v1/face/measure', {
method: 'POST',
body: fd
});
const { code, data } = await res.json();
// data.annotated_image_url → 标注 PNG
// data.face_total_height_cm → 全脸高度
// data.four_courts.ratios → { top_court: 0.25, ... }
// 前端叠加显示:原图 + annotated_image_urlabsolute 叠加)</pre>
</div>
</div>
<!-- ======== 接口2 ======== -->
<div class="card" id="if2">
<h2>2. C端生发 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hair/grow</code></h2>
<div class="card-body">
<p class="desc">上传正面照 + 性别 + 发型序号 → 返回指定发际线类型的预览图与生发图。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
<tr><td>gender</td><td>string</td><td>✅ 必填</td><td><code>"male"</code> / <code>"female"</code></td></tr>
<tr><td>hair_style</td><td>int</td><td>✅ 必填</td><td>发型序号。female: 1~5male: 1~4(见下方映射)</td></tr>
</table>
<p style="margin-top:12px"><strong>data.results[] 元素</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>image_url</code></td><td>string</td><td>发际线叠加预览图(曲线叠在原图上)</td></tr>
<tr><td><code>grown_image_url</code></td><td>string</td><td>生发后效果图(ComfyUI/Flux「植发3个月」)⚠ 可空</td></tr>
<tr><td><code>hairline_type</code></td><td>string</td><td>发际线类型 key</td></tr>
<tr><td><code>order</code></td><td>int</td><td>排序(1=最佳,当前按贴图顺序)</td></tr>
</table>
<p style="margin-top:8px;font-size:12px;color:#64748b">
Female 5 种:ellipse/flower/heart/straight/wave &nbsp;|&nbsp;
Male 4 种:ellipse/m/straight/inverse_arc<br>
⚠ 生发图由本机 ComfyUI 生成,耗时可达数分钟,fetch 超时需放大(≥5min)。
</p>
</div>
</div>
<!-- ======== 接口3 ======== -->
<div class="card" id="if3">
<h2>3. B端生发(医生端)&nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hair/grow-b</code></h2>
<div class="card-body">
<p class="desc">医生用马克笔在用户照片额头画线 → 拍照上传 → 系统生成生发效果图。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>marked_image_file / marked_image_url / marked_image_base64</td><td></td><td>✅ 三选一</td><td>已用马克笔标注发际线的图片</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>hair_growth_image_url</code></td><td>string</td><td>生发后效果图 URL ⚠ 可空</td></tr>
<tr><td><code>hairline_type</code></td><td>string</td><td>固定 <code>"custom"</code>(手绘定制)</td></tr>
</table>
<p style="font-size:12px;color:#64748b">⚠ 划线图未检测到划线(或无人脸)→ code=1001</p>
</div>
</div>
<!-- ======== 接口4 ======== -->
<div class="card" id="if4">
<h2>4. 用户特征分析 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/features</code></h2>
<div class="card-body">
<p class="desc">上传照片 → 火山方舟豆包视觉模型分析 → 返回几十项面部特征(脸型/眉形/肤色/四季色彩…)。</p>
<p><strong>入参</strong>image_file / image_url / image_base64 三选一。无其他参数。</p>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>features</code></td><td>string</td><td><strong>JSON 字符串</strong>(不是对象!客户端需 <code>JSON.parse()</code></td></tr>
</table>
<p style="margin-top:8px"><strong>features 英文优先字段</strong>(其余中文字段同时返回,共~42个):</p>
<table>
<tr><th>字段</th><th>说明</th><th>字段</th><th>说明</th></tr>
<tr><td>face_shape</td><td>脸型</td><td>eyebrow_shape</td><td>眉形</td></tr>
<tr><td>facial_age</td><td>面部年龄区间</td><td>gender</td><td>性别</td></tr>
<tr><td>dynamic_static_type</td><td>动静类型</td><td>gene_style</td><td>基因风格</td></tr>
</table>
<pre>const res = await fetch('https://hair.xiangsilian.com/api/v1/face/features', {
method: 'POST',
body: fd
});
const { code, data } = await res.json();
const features = JSON.parse(data.features); // ← 注意:data.features 是字符串!
console.log(features.face_shape); // "鹅蛋脸"
console.log(features['四季色彩季型']); // "冷夏型"(中文字段也保留)</pre>
</div>
</div>
<!-- ======== 接口5 ======== -->
<div class="card" id="if5">
<h2>5. 发际线 PNG 生成 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hairline/generate</code></h2>
<div class="card-body">
<p class="desc">上传正面照 + 性别 + 多选发型 → 每个选中发型 middle/high/low 三档发际线叠图 + 生发图 + 最佳发际线中心点坐标。</p>
<p><strong>入参</strong>(同接口2:先选性别,再多选发型)</p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
<tr><td>gender</td><td>string</td><td>✅ 必填</td><td><code>"male"</code> / <code>"female"</code></td></tr>
<tr><td>hair_style</td><td>string</td><td>✅ 必填</td><td>发型序号,逗号分隔多选(如 <code>1,2,3</code>)。缺失/越界返回 1007</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>hairline_images[]</code></td><td>object[]</td><td>选中发型列表,每项含 <code>hairline_type</code><code>image_middle_url</code>/<code>image_high_url</code>/<code>image_low_url</code> 三档叠图、<code>grown_image_url</code> 生发图(失败为 null)、<code>order</code></td></tr>
<tr><td><code>best_hairline_center_point</code></td><td>object</td><td>首个选中发型 middle 档发际线中心点像素坐标 <code>{ x: number, y: number }</code></td></tr>
<tr><td><code>face_measure</code></td><td>object \| null</td><td>复用<a href="#if1">接口1</a><strong>四庭七眼测量数值</strong>(不含标注图)。独立流程,测量失败时为 <code>null</code>,不影响发际线主结果。结构见下表</td></tr>
</table>
<p style="margin-top:12px"><code>face_measure</code> 字段(与接口1 的 <code>data</code> 同构,<strong>不含</strong> <code>annotated_image_*</code>):</p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>全脸高度(cm= 四庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>四庭:top/upper/middle/lower,各含 <code>_cm</code><code>ratios</code></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:<code>eye_width_cm</code>/<code>face_width_cm</code>/<code>inter_eye_distance_cm</code> + <code>ratios</code> + <code>eye1</code>~<code>eye7</code>(从左到右 7 段宽度 cm<code>eye1</code>/<code>eye7</code> 耳朵不可见时为 null</td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>5 个关键点像素坐标:hair_top/hairline/brow_center/nose_bottom/chin_tip</td></tr>
<tr><td><code>hairline_source</code></td><td>string</td><td>发际线来源:<code>"segmentation"</code>(真实分割)/ <code>"estimated"</code>(比例估算)</td></tr>
<tr><td><code>head_pose</code></td><td>object</td><td>头部姿态角度:<code>{ yaw, pitch, roll }</code>(度)</td></tr>
</table>
<p style="margin-top:12px;font-size:12px;color:#64748b">💡 前端无需额外请求接口1 即可拿到四庭七眼测量数值;<code>face_measure</code><code>null</code> 时(角度过大/无人脸等)仅隐藏测量区块,发际线结果照常展示。</p>
</div>
</div>
<!-- ======== 接口6 ======== -->
<div class="card" id="if6">
<h2>6. 四庭七眼测量 v2 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/measure-v2</code> &nbsp;<span class="badge warn">v2</span></h2>
<div class="card-body">
<p class="desc">基于<a href="#if1">接口1</a>的变体。上传正面照 → 返回标注 PNG + 三庭七眼数据。与接口1 的差异:</p>
<ul style="font-size:13px;color:#475569;margin:8px 0 12px 18px;line-height:1.8">
<li><strong>去顶庭</strong>:不画头顶横线、不返回顶庭数据,<code>face_total_height_cm</code> = 上+中+下庭</li>
<li><strong>竖线范围</strong>:发际线→下巴尖(接口1 为头顶→下巴尖)</li>
<li><strong>无头部端线</strong>:仅七眼 6 点 5 段标尺(接口1 为 8 点 7 段)</li>
</ul>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>annotated_image_url</code></td><td>string</td><td>标注 PNG URL(仅标注图层,透明底)</td></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>面部总高度(cm= 三庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>三庭:upper/middle/lower,各含 _cm 和 ratios<strong>无 top_court</strong></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:eye_width/face_width/inter_eye_distance</td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>4 个关键点:hairline/brow_center/nose_bottom/chin_tip<strong>无 hair_top</strong></td></tr>
</table>
</div>
</div>
<!-- ======== 接口7 ======== -->
<div class="card" id="if7">
<h2>7. C端生发 v2 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hair/grow-v2</code> &nbsp;<span class="badge warn">v2</span></h2>
<div class="card-body">
<p class="desc">功能与<a href="#if2">接口2</a>完全一致,仅 ComfyUI 工作流不同——使用 <code>add_hair2.json</code> 替代 <code>add_hair.json</code>Flux-2 Klein 9b)。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
<tr><td>gender</td><td>string</td><td>✅ 必填</td><td><code>"male"</code> / <code>"female"</code></td></tr>
<tr><td>hair_style</td><td>int</td><td>✅ 必填</td><td>发型序号。female: 1~5male: 1~4</td></tr>
</table>
<p style="margin-top:12px"><strong>data.results[] 元素</strong>(同接口2</p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>image_url</code></td><td>string</td><td>发际线叠加预览图</td></tr>
<tr><td><code>grown_image_url</code></td><td>string</td><td>生发后效果图 ⚠ 可空</td></tr>
<tr><td><code>hairline_type</code></td><td>string</td><td>发际线类型 key</td></tr>
<tr><td><code>order</code></td><td>int</td><td>排序</td></tr>
</table>
<p style="margin-top:8px;font-size:12px;color:#64748b">
Female 5 种:ellipse/flower/heart/straight/wave &nbsp;|&nbsp;
Male 4 种:ellipse/m/straight/inverse_arc<br>
⚠ 工作流: add_hair2.jsonFlux-2 Klein 9b),输入节点 26,输出节点 75。
</p>
</div>
</div>
<!-- ======== 错误码 ======== -->
<div class="card" id="errors">
<h2>⚠ 错误码</h2>
<div class="card-body">
<table>
<tr><th>code</th><th>message</th><th>说明</th></tr>
<tr><td>1001</td><td>无法识别人像</td><td>未检测到人脸</td></tr>
<tr><td>1003</td><td>角度问题,非正面照</td><td>非正面 / 角度过大</td></tr>
<tr><td>1005</td><td>检测到多张人脸</td><td>仅支持单人</td></tr>
<tr><td>1007</td><td>图片参数错误 / 后端不可用</td><td>参数传错 / 服务繁忙请稍后重试</td></tr>
<tr><td>1008</td><td>图片格式不支持</td><td>非 JPG/PNG / base64 解码失败</td></tr>
</table>
<p style="font-size:12px;color:#94a3b8;margin-top:8px">1004 已废弃(接口2 不再自动判性别,改由客户端传 gender 参数)。</p>
</div>
</div>
<!-- ======== 在线测试页 ======== -->
<div class="card" id="test">
<h2>🧪 在线测试页面</h2>
<div class="card-body">
<table>
<tr><th>接口</th><th>测试页</th><th>功能</th></tr>
<tr><td>1. 四庭七眼</td><td><a href="/static/test_interface1.html" class="link">/static/test_interface1.html</a></td><td>上传照片 → 原图+标注叠加,底图/标注开关,指标卡片</td></tr>
<tr><td>2. C端生发</td><td><a href="/static/test_interface2.html" class="link">/static/test_interface2.html</a></td><td>上传+性别 → 方案一覧(原图/叠加/生发),双图对比</td></tr>
<tr><td>3. B端生发</td><td><a href="/static/test_interface3.html" class="link">/static/test_interface3.html</a></td><td>划线图上传 → 生发效果图</td></tr>
<tr><td>4. 用户特征</td><td><a href="/static/test_interface4.html" class="link">/static/test_interface4.html</a></td><td>上传照片 → 42项面部特征表格 + 原始JSON</td></tr>
<tr><td>5. 发际线PNG</td><td><a href="/static/test_interface5.html" class="link">/static/test_interface5.html</a></td><td>上传+性别 → 发际线方案+中心点坐标</td></tr>
<tr><td>6. 四庭七眼 v2</td><td><a href="/static/test_interface6.html" class="link">/static/test_interface6.html</a></td><td>同接口1,去顶庭 · 竖线发际线→下巴 · 无头部端线</td></tr>
<tr><td>7. C端生发 v2</td><td><a href="/static/test_interface7.html" class="link">/static/test_interface7.html</a></td><td>同接口2,使用 add_hair2.json 工作流(Flux-2 Klein 9b</td></tr>
</table>
<p style="font-size:12px;color:#94a3b8;margin-top:12px">
完整 API 文档:<a href="/docs" class="link">/docs</a>Swagger UI
</p>
</div>
</div>
<p style="text-align:center;font-size:12px;color:#cbd5e1;margin-top:32px">
Base: https://hair.xiangsilian.com &nbsp;|&nbsp; Swagger: /docs &nbsp;|&nbsp; 接入说明: /static/integration.html
</p>
</div>
</body>
</html>