CoolFace
Apppublic

Malits/Av1api

sourceHugging Faceupdated 1mo agoView on Hugging Face
0likes
av1encodes_tester.html3516 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="UTF-8">5<meta name="viewport" content="width=device-width, initial-scale=1.0">6<title>AV1Encodes · API Tester</title>7<style>8  @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;600;700&family=Syne:wght@400;700;800&display=swap');9 10  :root {11    --bg:      #0a0a0d;12    --surface: #111118;13    --border:  #1c1c2a;14    --accent:  #6c63ff;15    --accent2: #ff7b54;16    --green:   #3dffa0;17    --red:     #ff4f6e;18    --yellow:  #ffcb57;19    --cyan:    #38d9f5;20    --text:    #dde1f0;21    --muted:   #52526e;22    --mono: 'JetBrains Mono', monospace;23    --sans: 'Syne', sans-serif;24  }25 26  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }27  body {28    background: var(--bg);29    color: var(--text);30    font-family: var(--mono);31    font-size: 13px;32    min-height: 100vh;33    display: flex;34    flex-direction: column;35  }36 37  /* ── HEADER ─────────────────────────────────── */38  header {39    padding: 12px 28px;40    border-bottom: 1px solid var(--border);41    display: flex;42    align-items: center;43    gap: 14px;44    background: var(--surface);45    position: sticky;46    top: 0;47    z-index: 100;48  }49  .logo {50    font-family: var(--sans);51    font-size: 18px;52    font-weight: 800;53    color: #fff;54    display: flex;55    align-items: center;56    gap: 8px;57    letter-spacing: -0.5px;58  }59  .logo-icon {60    width: 28px; height: 28px;61    background: var(--accent);62    border-radius: 6px;63    display: flex; align-items: center; justify-content: center;64    font-size: 14px;65  }66  .logo span { color: var(--accent); }67  .base-url-pill {68    background: var(--bg);69    border: 1px solid var(--border);70    border-radius: 6px;71    padding: 4px 12px;72    font-size: 11px;73    color: var(--muted);74    display: flex;75    align-items: center;76    gap: 8px;77  }78  .base-url-pill input {79    background: transparent;80    border: none;81    color: var(--cyan);82    font-family: var(--mono);83    font-size: 11px;84    outline: none;85    width: 240px;86  }87  .status-dot {88    width: 7px; height: 7px;89    border-radius: 50%;90    background: var(--muted);91    transition: background .3s;92  }93  .status-dot.online { background: var(--green); animation: pulse 2s infinite; }94  .status-dot.offline { background: var(--red); }95  @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.3} }96  .kbd-hint {97    margin-left: auto;98    font-size: 10px;99    color: var(--muted);100    display: flex;101    align-items: center;102    gap: 5px;103  }104  .kbd {105    background: var(--border);106    border: 1px solid #2a2a40;107    border-radius: 3px;108    padding: 1px 5px;109    font-size: 9px;110  }111 112  /* ── LAYOUT ──────────────────────────────────── */113  .layout { display: flex; flex: 1; overflow: hidden; height: calc(100vh - 53px); }114 115  /* ── SIDEBAR ─────────────────────────────────── */116  aside {117    width: 270px;118    min-width: 270px;119    background: var(--surface);120    border-right: 1px solid var(--border);121    display: flex;122    flex-direction: column;123    overflow: hidden;124  }125  .sidebar-tabs {126    display: flex;127    border-bottom: 1px solid var(--border);128    flex-shrink: 0;129  }130  .stab {131    flex: 1;132    padding: 9px 4px;133    text-align: center;134    font-size: 10px;135    text-transform: uppercase;136    letter-spacing: 1px;137    color: var(--muted);138    cursor: pointer;139    transition: color .2s, background .2s;140  }141  .stab.active { color: var(--accent); background: #6c63ff10; border-bottom: 2px solid var(--accent); }142  .sidebar-panel { flex: 1; overflow-y: auto; padding: 6px 0; display: none; }143  .sidebar-panel.active { display: block; }144 145  /* ── ROUTE LIST ──────────────────────────────── */146  .group-label {147    font-size: 9px;148    text-transform: uppercase;149    letter-spacing: 2px;150    color: var(--muted);151    padding: 14px 16px 5px;152    font-weight: 700;153  }154  .route-item {155    display: flex;156    align-items: center;157    gap: 9px;158    padding: 7px 16px;159    cursor: pointer;160    border-left: 2px solid transparent;161    transition: background .12s;162    user-select: none;163  }164  .route-item:hover { background: #1e1e2e; }165  .route-item.active { background: #6c63ff0e; border-left-color: var(--accent); }166  .method-badge {167    font-size: 9px;168    font-weight: 700;169    padding: 2px 5px;170    border-radius: 3px;171    min-width: 42px;172    text-align: center;173    letter-spacing: .5px;174  }175  .m-GET    { background: #3dffa018; color: var(--green); }176  .m-POST   { background: #ff7b5418; color: var(--accent2); }177  .m-PATCH  { background: #ffcb5718; color: var(--yellow); }178  .m-DELETE { background: #ff4f6e18; color: var(--red); }179  .route-path {180    font-size: 11px;181    color: var(--text);182    white-space: nowrap;183    overflow: hidden;184    text-overflow: ellipsis;185    flex: 1;186  }187  .divider { height: 1px; background: var(--border); margin: 4px 0; }188 189  /* ── HISTORY ─────────────────────────────────── */190  .hist-empty { padding: 28px 16px; font-size: 11px; color: var(--muted); text-align: center; }191  .hist-item {192    padding: 8px 14px;193    cursor: pointer;194    border-left: 2px solid transparent;195    transition: background .12s;196  }197  .hist-item:hover { background: #1e1e2e; }198  .hist-top { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }199  .hist-path { font-size: 10px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }200  .hist-time { font-size: 10px; color: var(--muted); margin-left: auto; white-space: nowrap; }201  .hist-actions { display: flex; gap: 8px; padding: 8px 14px 4px; }202  .hist-btn {203    flex: 1;204    background: transparent;205    border: 1px solid var(--border);206    color: var(--muted);207    font-family: var(--mono);208    font-size: 10px;209    padding: 4px 8px;210    border-radius: 4px;211    cursor: pointer;212    transition: color .2s, border-color .2s;213  }214  .hist-btn:hover { border-color: var(--accent); color: var(--accent); }215  .hist-btn.danger:hover { border-color: var(--red); color: var(--red); }216 217  /* ── MAIN ────────────────────────────────────── */218  main { flex: 1; display: flex; flex-direction: column; overflow: hidden; }219 220  /* ── REQUEST PANEL ───────────────────────────── */221  .request-panel {222    padding: 20px 28px 16px;223    border-bottom: 1px solid var(--border);224    background: var(--bg);225    flex-shrink: 0;226    max-height: 55%;227    overflow-y: auto;228  }229  .route-title {230    font-family: var(--sans);231    font-size: 16px;232    font-weight: 700;233    color: #fff;234    margin-bottom: 3px;235  }236  .route-desc { color: var(--muted); font-size: 11px; margin-bottom: 14px; }237  .url-row { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }238  .method-pill {239    font-size: 11px; font-weight: 700;240    padding: 7px 13px; border-radius: 5px;241    min-width: 66px; text-align: center;242    flex-shrink: 0;243  }244  .url-display {245    flex: 1;246    background: var(--surface);247    border: 1px solid var(--border);248    color: var(--cyan);249    font-family: var(--mono);250    font-size: 12px;251    padding: 7px 12px;252    border-radius: 5px;253    word-break: break-all;254    min-height: 34px;255    line-height: 1.5;256    min-width: 0;257  }258  .send-btn {259    background: var(--accent);260    color: #fff;261    border: none;262    font-family: var(--mono);263    font-size: 12px;264    font-weight: 700;265    padding: 7px 22px;266    border-radius: 5px;267    cursor: pointer;268    transition: opacity .2s, transform .1s;269    white-space: nowrap;270    flex-shrink: 0;271  }272  .send-btn:hover { opacity: .85; }273  .send-btn:active { transform: scale(.97); }274  .send-btn:disabled { opacity: .4; cursor: not-allowed; }275 276  .section-title {277    font-size: 10px;278    text-transform: uppercase;279    letter-spacing: 1px;280    color: var(--muted);281    margin: 12px 0 7px;282  }283  .params-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }284  .param-group { display: flex; flex-direction: column; gap: 5px; }285  .param-group label {286    font-size: 10px;287    text-transform: uppercase;288    letter-spacing: 1px;289    color: var(--muted);290    display: flex;291    align-items: center;292    gap: 6px;293  }294  .param-group input, .param-group textarea, .param-group select {295    background: var(--surface);296    border: 1px solid var(--border);297    color: var(--text);298    font-family: var(--mono);299    font-size: 12px;300    padding: 7px 10px;301    border-radius: 5px;302    outline: none;303    transition: border-color .2s;304    resize: vertical;305  }306  .param-group select { appearance: none; cursor: pointer; }307  .param-group input:focus, .param-group textarea:focus, .param-group select:focus {308    border-color: var(--accent);309  }310  .param-tag-path { color: var(--accent2); }311  .param-tag-query { color: var(--cyan); }312 313  /* ── RESPONSE PANEL ──────────────────────────── */314  .response-panel {315    flex: 1;316    overflow: auto;317    padding: 20px 28px;318    display: flex;319    flex-direction: column;320    gap: 12px;321    min-height: 0;322  }323  .response-header { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }324  .response-label {325    font-size: 10px;326    text-transform: uppercase;327    letter-spacing: 1.5px;328    color: var(--muted);329    font-weight: 700;330  }331  .status-pill {332    font-size: 11px;333    font-weight: 700;334    padding: 2px 11px;335    border-radius: 20px;336  }337  .s2xx { background: #3dffa018; color: var(--green); }338  .s4xx, .s5xx { background: #ff4f6e18; color: var(--red); }339  .spnd { background: #ffcb5718; color: var(--yellow); }340  .time-pill { font-size: 11px; color: var(--muted); margin-left: auto; }341  pre.response-body {342    background: var(--surface);343    border: 1px solid var(--border);344    border-radius: 7px;345    padding: 16px;346    font-size: 12px;347    line-height: 1.7;348    overflow: auto;349    white-space: pre-wrap;350    word-break: break-word;351    flex: 1;352    min-height: 120px;353  }354  .resp-actions { display: flex; gap: 8px; }355  .action-btn {356    background: var(--border);357    border: none;358    color: var(--muted);359    font-family: var(--mono);360    font-size: 11px;361    padding: 4px 12px;362    border-radius: 4px;363    cursor: pointer;364    transition: color .2s;365  }366  .action-btn:hover { color: var(--text); }367 368  .empty-state {369    flex: 1;370    display: flex;371    align-items: center;372    justify-content: center;373    color: var(--muted);374    font-size: 12px;375    flex-direction: column;376    gap: 10px;377  }378  .empty-icon { font-size: 36px; opacity: .25; }379 380  /* ── JSON HIGHLIGHT ──────────────────────────── */381  .jk { color: #a89df7; }    /* key    */382  .js { color: var(--green); } /* string */383  .jn { color: var(--accent2); } /* number */384  .jb { color: var(--yellow); }  /* bool   */385  .jl { color: var(--red); }     /* null   */386 387  /* ── SCROLLBAR ───────────────────────────────── */388  ::-webkit-scrollbar { width: 5px; height: 5px; }389  ::-webkit-scrollbar-track { background: transparent; }390  ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }391 392  /* ── QUICK-COPY TOAST ────────────────────────── */393  #toast {394    position: fixed;395    bottom: 24px;396    right: 24px;397    background: var(--accent);398    color: #fff;399    font-family: var(--mono);400    font-size: 12px;401    padding: 8px 18px;402    border-radius: 6px;403    opacity: 0;404    pointer-events: none;405    transition: opacity .3s;406    z-index: 9999;407  }408  #toast.show { opacity: 1; }409 410  /* ── ADMIN INTERFACE ────────────────────────── */411  .admin-panel {412    display: none;413    flex-direction: column;414    gap: 16px;415    height: 100%;416    overflow-y: auto;417    padding: 20px;418  }419  .admin-panel.active {420    display: flex;421  }422  423  /* Lock Screen */424  .admin-lock-screen {425    flex: 1;426    display: flex;427    align-items: center;428    justify-content: center;429    background: radial-gradient(circle at center, #181824 0%, #0a0a0d 100%);430  }431  .lock-card {432    background: rgba(17, 17, 24, 0.7);433    backdrop-filter: blur(12px);434    -webkit-backdrop-filter: blur(12px);435    border: 1px solid var(--border);436    border-radius: 12px;437    padding: 32px;438    width: 100%;439    max-width: 400px;440    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);441    text-align: center;442    display: flex;443    flex-direction: column;444    gap: 20px;445    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);446  }447  .lock-card:hover {448    transform: translateY(-4px);449    border-color: rgba(108, 99, 255, 0.3);450  }451  .lock-icon {452    font-size: 40px;453    background: rgba(108, 99, 255, 0.1);454    color: var(--accent);455    width: 70px;456    height: 70px;457    border-radius: 50%;458    display: flex;459    align-items: center;460    justify-content: center;461    margin: 0 auto;462    border: 1px solid rgba(108, 99, 255, 0.2);463  }464  .lock-title {465    font-family: var(--sans);466    font-size: 20px;467    font-weight: 700;468    color: #fff;469  }470  .lock-desc {471    color: var(--muted);472    font-size: 11px;473    line-height: 1.5;474  }475  .lock-input-group {476    display: flex;477    flex-direction: column;478    gap: 8px;479    text-align: left;480  }481  .lock-input-group label {482    font-size: 10px;483    text-transform: uppercase;484    letter-spacing: 1px;485    color: var(--muted);486  }487  .lock-input {488    background: var(--bg);489    border: 1px solid var(--border);490    color: var(--text);491    font-family: var(--mono);492    font-size: 13px;493    padding: 10px 14px;494    border-radius: 6px;495    outline: none;496    transition: border-color 0.2s, box-shadow 0.2s;497  }498  .lock-input:focus {499    border-color: var(--accent);500    box-shadow: 0 0 0 2px rgba(108, 99, 255, 0.2);501  }502  .lock-btn {503    background: var(--accent);504    color: #fff;505    border: none;506    font-family: var(--mono);507    font-size: 12px;508    font-weight: 700;509    padding: 12px;510    border-radius: 6px;511    cursor: pointer;512    transition: opacity 0.2s, transform 0.1s;513  }514  .lock-btn:hover { opacity: 0.9; }515  .lock-btn:active { transform: scale(0.98); }516 517  /* Dashboard Stats Grid */518  .stats-grid {519    display: grid;520    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));521    gap: 12px;522  }523  .stat-card {524    background: var(--surface);525    border: 1px solid var(--border);526    border-radius: 8px;527    padding: 16px;528    display: flex;529    flex-direction: column;530    gap: 6px;531    position: relative;532    overflow: hidden;533  }534  .stat-card::after {535    content: '';536    position: absolute;537    top: 0; left: 0; right: 0; height: 2px;538    background: transparent;539  }540  .stat-card.accent::after { background: var(--accent); }541  .stat-card.cyan::after { background: var(--cyan); }542  .stat-card.green::after { background: var(--green); }543  .stat-card.yellow::after { background: var(--yellow); }544  545  .stat-card.clickable {546    cursor: pointer;547    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);548  }549  .stat-card.clickable:hover {550    background: rgba(255, 255, 255, 0.05);551    border-color: rgba(108, 99, 255, 0.35);552    transform: translateY(-2px);553    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);554  }555  .stat-card.clickable:active {556    transform: translateY(0);557  }558  559  .stat-label {560    font-size: 10px;561    color: var(--muted);562    text-transform: uppercase;563    letter-spacing: 1px;564  }565  .stat-value {566    font-family: var(--sans);567    font-size: 22px;568    font-weight: 700;569    color: #fff;570  }571  .stat-desc {572    font-size: 10px;573    color: var(--muted);574  }575 576  /* Admin Toolbar */577  .admin-toolbar {578    display: flex;579    justify-content: space-between;580    align-items: center;581    background: var(--surface);582    border: 1px solid var(--border);583    border-radius: 8px;584    padding: 12px 18px;585    gap: 16px;586    flex-wrap: wrap;587  }588  .toolbar-actions {589    display: flex;590    gap: 8px;591    flex-wrap: wrap;592  }593  .btn {594    background: var(--border);595    color: var(--text);596    border: 1px solid transparent;597    font-family: var(--mono);598    font-size: 11px;599    font-weight: 600;600    padding: 8px 14px;601    border-radius: 5px;602    cursor: pointer;603    display: inline-flex;604    align-items: center;605    gap: 6px;606    transition: background 0.2s, color 0.2s, border-color 0.2s;607  }608  .btn:hover { background: #232336; color: #fff; }609  .btn.primary { background: var(--accent); color: #fff; }610  .btn.primary:hover { opacity: 0.9; }611  .btn.danger { background: rgba(255, 79, 110, 0.1); color: var(--red); border-color: rgba(255, 79, 110, 0.2); }612  .btn.danger:hover { background: var(--red); color: #fff; }613  .btn.success { background: rgba(61, 255, 160, 0.1); color: var(--green); border-color: rgba(61, 255, 160, 0.2); }614  .btn.success:hover { background: var(--green); color: var(--bg); }615  616  /* Sync Info / Progress */617  .sync-status-bar {618    background: rgba(17, 17, 24, 0.5);619    border: 1px solid var(--border);620    border-radius: 6px;621    padding: 10px 14px;622    display: flex;623    flex-direction: column;624    gap: 6px;625    width: 100%;626  }627  .sync-status-header {628    display: flex;629    justify-content: space-between;630    font-size: 11px;631  }632  .progress-bg {633    background: var(--bg);634    border-radius: 4px;635    height: 6px;636    width: 100%;637    overflow: hidden;638  }639  .progress-bar {640    background: linear-gradient(90deg, var(--accent) 0%, var(--cyan) 100%);641    height: 100%;642    width: 0%;643    transition: width 0.3s ease;644    position: relative;645  }646  .progress-bar.animated::after {647    content: '';648    position: absolute;649    top: 0; left: 0; bottom: 0; right: 0;650    background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.2) 50%, rgba(255,255,255,0) 100%);651    animation: shine 1.5s infinite;652  }653  @keyframes shine {654    0% { transform: translateX(-100%); }655    100% { transform: translateX(100%); }656  }657 658  /* Search & Filter Controls */659  .admin-controls {660    display: flex;661    gap: 10px;662    align-items: center;663    flex-wrap: wrap;664  }665  .admin-search-input {666    flex: 1;667    min-width: 200px;668    background: var(--surface);669    border: 1px solid var(--border);670    color: var(--text);671    font-family: var(--mono);672    font-size: 12px;673    padding: 8px 12px;674    border-radius: 6px;675    outline: none;676    transition: border-color 0.2s;677  }678  .admin-search-input:focus { border-color: var(--accent); }679  .admin-select {680    background: var(--surface);681    border: 1px solid var(--border);682    color: var(--text);683    font-family: var(--mono);684    font-size: 12px;685    padding: 8px 12px;686    border-radius: 6px;687    outline: none;688    cursor: pointer;689  }690 691  /* Table Grid */692  .table-wrapper {693    background: var(--surface);694    border: 1px solid var(--border);695    border-radius: 8px;696    overflow: hidden;697    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);698  }699  .admin-table {700    width: 100%;701    border-collapse: collapse;702    text-align: left;703    font-size: 12px;704  }705  .admin-table th, .admin-table td {706    padding: 10px 14px;707    border-bottom: 1px solid var(--border);708  }709  .admin-table th {710    background: rgba(28, 28, 42, 0.4);711    color: var(--muted);712    font-weight: 600;713    text-transform: uppercase;714    font-size: 10px;715    letter-spacing: 1px;716    user-select: none;717  }718  .admin-table tbody tr {719    transition: background 0.15s;720  }721  .admin-table tbody tr:hover {722    background: rgba(108, 99, 255, 0.03);723  }724  .admin-table td img {725    border-radius: 4px;726    object-fit: cover;727    background: var(--bg);728  }729  730  .badge {731    display: inline-block;732    padding: 2px 6px;733    border-radius: 4px;734    font-size: 10px;735    font-weight: 600;736  }737  .badge.success { background: rgba(61, 255, 160, 0.1); color: var(--green); }738  .badge.warning { background: rgba(255, 203, 87, 0.1); color: var(--yellow); }739  .badge.danger { background: rgba(255, 79, 110, 0.1); color: var(--red); }740  .badge.info { background: rgba(56, 217, 245, 0.1); color: var(--cyan); }741  742  .table-actions {743    display: flex;744    gap: 6px;745  }746  .action-btn-sm {747    background: transparent;748    border: 1px solid var(--border);749    color: var(--muted);750    font-family: var(--mono);751    font-size: 10px;752    padding: 4px 8px;753    border-radius: 4px;754    cursor: pointer;755    transition: all 0.2s;756  }757  .action-btn-sm:hover { border-color: var(--accent); color: var(--accent); }758  .action-btn-sm.danger:hover { border-color: var(--red); color: var(--red); background: rgba(255, 79, 110, 0.05); }759  .action-btn-sm.success:hover { border-color: var(--green); color: var(--green); background: rgba(61, 255, 160, 0.05); }760 761  /* Pagination */762  .table-footer {763    display: flex;764    justify-content: space-between;765    align-items: center;766    padding: 10px 14px;767    background: rgba(28, 28, 42, 0.2);768    font-size: 11px;769    color: var(--muted);770  }771  .pagination-controls {772    display: flex;773    gap: 6px;774  }775 776  /* Bulk Downloader Styles */777  .bulk-filter-bar {778    background: rgba(28, 28, 42, 0.4);779    border: 1px solid var(--border);780    border-radius: 8px;781    padding: 12px 16px;782    display: flex;783    flex-wrap: wrap;784    gap: 16px;785    align-items: center;786    justify-content: space-between;787  }788  .bulk-table-container {789    max-height: 380px;790    overflow-y: auto;791    border: 1px solid var(--border);792    border-radius: 8px;793    background: var(--surface);794  }795  .bulk-action-bar {796    background: rgba(28, 28, 42, 0.4);797    border: 1px solid var(--border);798    border-radius: 8px;799    padding: 12px 16px;800    display: flex;801    align-items: center;802    justify-content: space-between;803    flex-wrap: wrap;804    gap: 12px;805  }806  .bulk-checkbox-cell {807    text-align: center;808    cursor: pointer;809  }810  .bulk-checkbox {811    width: 16px;812    height: 16px;813    cursor: pointer;814    accent-color: var(--accent);815  }816  .action-btn-sm.info {817    border-color: var(--cyan);818    color: var(--cyan);819  }820  .action-btn-sm.info:hover {821    background: rgba(0, 242, 254, 0.08);822    border-color: var(--cyan);823    color: var(--cyan);824  }825  .action-btn-sm.primary {826    border-color: var(--accent);827    color: var(--accent);828  }829  .action-btn-sm.primary:hover {830    background: rgba(255, 79, 110, 0.08);831    border-color: var(--accent);832    color: var(--accent);833  }834 835  /* Modals */836  .admin-modal-overlay {837    position: fixed;838    top: 0; left: 0; right: 0; bottom: 0;839    background: rgba(5, 5, 8, 0.85);840    backdrop-filter: blur(8px);841    -webkit-backdrop-filter: blur(8px);842    z-index: 1000;843    display: none;844    align-items: center;845    justify-content: center;846    padding: 20px;847    overflow-y: auto;848  }849  .admin-modal-overlay.active {850    display: flex;851  }852  .admin-modal-card {853    background: var(--surface);854    border: 1px solid var(--border);855    border-radius: 12px;856    width: 100%;857    max-width: 800px;858    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);859    display: flex;860    flex-direction: column;861    max-height: 90vh;862    animation: modalSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1);863  }864  @keyframes modalSlideIn {865    from { transform: translateY(20px); opacity: 0; }866    to { transform: translateY(0); opacity: 1; }867  }868  .modal-header {869    padding: 16px 20px;870    border-bottom: 1px solid var(--border);871    display: flex;872    justify-content: space-between;873    align-items: center;874  }875  .modal-title {876    font-family: var(--sans);877    font-size: 16px;878    font-weight: 700;879    color: #fff;880  }881  .modal-close {882    background: transparent;883    border: none;884    color: var(--muted);885    font-size: 20px;886    cursor: pointer;887    transition: color 0.2s;888  }889  .modal-close:hover { color: #fff; }890  891  .modal-body {892    padding: 20px;893    overflow-y: auto;894    flex: 1;895  }896  .modal-footer {897    padding: 14px 20px;898    border-top: 1px solid var(--border);899    display: flex;900    justify-content: flex-end;901    gap: 10px;902  }903 904  /* Form Layout */905  .form-grid {906    display: grid;907    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));908    gap: 16px;909  }910  .form-group-full {911    grid-column: 1 / -1;912  }913  914  /* Quick Form Tools */915  .enrich-box {916    background: rgba(108, 99, 255, 0.05);917    border: 1px dashed rgba(108, 99, 255, 0.3);918    border-radius: 6px;919    padding: 12px;920    margin-bottom: 16px;921    display: flex;922    align-items: center;923    justify-content: space-between;924    gap: 12px;925  }926 927  /* Modal Tabs */928  .modal-tabs {929    display: flex;930    border-bottom: 1px solid var(--border);931    flex-shrink: 0;932  }933  .mtab {934    padding: 12px 20px;935    font-size: 11px;936    font-weight: bold;937    cursor: pointer;938    color: var(--muted);939    transition: all 0.2s;940    border-bottom: 2px solid transparent;941    font-family: var(--sans);942    text-transform: uppercase;943    letter-spacing: 0.5px;944  }945  .mtab:hover { color: var(--text); }946  .mtab.active { color: var(--accent) !important; border-bottom-color: var(--accent) !important; background: rgba(108, 99, 255, 0.05); }947</style>948</head>949<body>950 951<header>952  <div class="logo">953    <div class="logo-icon">▶</div>954    AV1<span>Encodes</span>955  </div>956  <div class="base-url-pill">957    <div class="status-dot" id="statusDot"></div>958    <input id="baseUrlInput" value="http://localhost:8000" placeholder="http://localhost:8000" />959  </div>960  <span style="font-size:10px;color:var(--muted)">Python API Tester</span>961  <span class="kbd-hint">Send <span class="kbd">Ctrl</span><span class="kbd">↵</span></span>962</header>963 964<div class="layout">965  <aside>966    <div class="sidebar-tabs">967      <div class="stab active" onclick="switchTab('routes',this)">Routes</div>968      <div class="stab"        onclick="switchTab('history',this)">History</div>969      <div class="stab"        onclick="switchTab('admin',this)">Admin</div>970    </div>971    <div class="sidebar-panel active" id="tab-routes"></div>972    <div class="sidebar-panel"        id="tab-history">973      <div id="histList"></div>974    </div>975    <div class="sidebar-panel"        id="tab-admin">976      <div style="padding:14px 16px; font-size:11px; color:var(--muted); line-height: 1.5;">977        <strong>AV1 Headless CMS</strong><br>978        Add, edit, or delete anime and trigger fast background crawls directly from the dashboard.979      </div>980      <div class="divider"></div>981      <div id="adminSidebarContent" style="padding: 10px 16px; display: flex; flex-direction: column; gap: 8px;">982        <div style="font-size:10px; color:var(--muted)">Authenticate to view sidebar operations.</div>983      </div>984    </div>985  </aside>986 987  <main>988    <div class="request-panel" id="requestPanel">989      <div class="empty-state" style="padding:60px 0">990        <div class="empty-icon">⚡</div>991        <div>Pick a route from the sidebar to begin</div>992      </div>993    </div>994    <div class="response-panel" id="responsePanel">995      <div class="empty-state">996        <div class="empty-icon">◎</div>997        <div>Response will appear here</div>998      </div>999    </div>1000    <div class="admin-panel" id="adminPanel">1001      <!-- Loaded dynamically via javascript based on authentication state -->1002    </div>1003  </main>1004</div>1005 1006<div id="toast">Copied!</div>1007 1008<!-- ── ADMIN BULK DOWNLOAD MODAL ──────────────── -->1009<div class="admin-modal-overlay" id="adminBulkDownloadModal">1010  <div class="admin-modal-card" style="max-width: 850px; width: 95%;">1011    <div class="modal-header">1012      <div class="modal-title" id="bulkModalTitle">Bulk Episode Stream Links</div>1013      <button class="modal-close" onclick="closeBulkDownloadModal()">×</button>1014    </div>1015    1016    <div class="modal-body" style="display: flex; flex-direction: column; gap: 16px;">1017      <!-- Controls -->1018      <div class="bulk-filter-bar">1019        <div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">1020          <div style="display: flex; align-items: center; gap: 8px;">1021            <label style="font-size: 11px; font-weight: bold; color: var(--muted); margin: 0; white-space: nowrap;">Quality:</label>1022            <select id="bulkQualityFilter" class="admin-select" style="padding: 6px 12px; font-size: 11px; width: 130px; border-radius: 4px;">1023              <option value="1920 x 1080">1080p</option>1024              <option value="1280 x 720">720p</option>1025              <option value="854 x 480">480p</option>1026            </select>1027          </div>1028          <div style="display: flex; align-items: center; gap: 8px;">1029            <label style="font-size: 11px; font-weight: bold; color: var(--muted); margin: 0; white-space: nowrap;">Link Type:</label>1030            <select id="bulkLinkTypeFilter" class="admin-select" style="padding: 6px 12px; font-size: 11px; width: 130px; border-radius: 4px;" onchange="renderBulkTable()">1031              <option value="download">Download</option>1032              <option value="stream">Stream</option>1033              <option value="watch">Watch</option>1034              <option value="torrent">Torrent</option>1035            </select>1036          </div>1037          <button class="btn primary" type="button" onclick="bulkResolveLinks()" id="bulkResolveBtn" style="font-size: 11px; padding: 6px 14px;">Resolve Links 🔗</button>1038        </div>1039        1040        <div style="display: flex; gap: 8px;">1041          <button class="action-btn-sm success" onclick="toggleSelectAllBulk(true)">Select All</button>1042          <button class="action-btn-sm" onclick="toggleSelectAllBulk(false)">Deselect All</button>1043        </div>1044      </div>1045      1046      <!-- Progress bar (hidden by default) -->1047      <div id="bulkProgressContainer" style="display: none;">1048        <div style="font-size: 11px; color: var(--muted); margin-bottom: 4px;">Resolving video links: <span id="bulkProgressText">0 / 0</span></div>1049        <div style="width: 100%; height: 6px; background: var(--border); border-radius: 3px; overflow: hidden;">1050          <div id="bulkProgressBar" style="width: 0%; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent2)); border-radius: 3px; transition: width 0.3s;"></div>1051        </div>1052      </div>1053      1054      <!-- Table/Tree list of Episodes -->1055      <div class="bulk-table-container">1056        <table class="admin-table" style="font-size: 11px; margin: 0;">1057          <thead style="position: sticky; top: 0; background: var(--surface); z-index: 10; border-bottom: 2px solid var(--border);">1058            <tr>1059              <th style="width: 40px; text-align: center;">✓</th>1060              <th style="width: 70px;">Episode</th>1061              <th>File Name</th>1062              <th style="width: 80px;">Size</th>1063              <th style="width: 70px;">Type</th>1064              <th style="width: 100px; text-align: right;">Action</th>1065            </tr>1066          </thead>1067          <tbody id="bulkTableBody">1068            <tr>1069              <td colspan="6" style="text-align: center; color: var(--muted); padding: 30px;">Select quality and click <strong>Resolve Links 🔗</strong> to fetch episode links.</td>1070            </tr>1071          </tbody>1072        </table>1073      </div>1074      1075      <!-- Selection Summary and Download Actions -->1076      <div class="bulk-action-bar">1077        <div style="font-size: 12px; color: var(--foreground);">1078          Selected: <strong id="bulkSelectedCount" style="color: var(--accent);">0</strong> item(s)1079        </div>1080        <div style="display: flex; gap: 10px;">1081          <button class="btn success" type="button" onclick="bulkCopyAllLinks()">Copy Selected Links 📋</button>1082          <button class="btn primary" type="button" onclick="bulkDownloadAllSelected()">Download Selected ⬇</button>1083        </div>1084      </div>1085      1086    </div>1087    <div class="modal-footer">1088      <button class="btn" onclick="closeBulkDownloadModal()">Close</button>1089    </div>1090  </div>1091</div>1092 1093<!-- ── ADMIN MODAL ────────────────────────────── -->1094<div class="admin-modal-overlay" id="adminModal">1095  <div class="admin-modal-card">1096    <div class="modal-header">1097      <div class="modal-title" id="modalTitle">Add New Anime</div>1098      <button class="modal-close" onclick="closeModal()">×</button>1099    </div>1100    1101    <!-- Modal Tabs (only visible when editing) -->1102    <div class="modal-tabs" id="modalTabsContainer" style="display: none; border-bottom: 1px solid var(--border); background: rgba(28,28,42,0.2);">1103      <div class="mtab active" onclick="switchModalTab('metadata')">Anime Metadata</div>1104      <div class="mtab" onclick="switchModalTab('streams')">Episode Stream Mirrors 📺</div>1105    </div>1106    1107    <div class="modal-body">1108      <!-- AniList Live Explorer -->1109      <div class="enrich-box" id="modalEnrichBox" style="flex-direction: column; align-items: stretch; gap: 10px; border-style: solid; border-color: rgba(108, 99, 255, 0.2); background: rgba(17, 17, 24, 0.4); padding: 16px;">1110        <div style="display: flex; justify-content: space-between; align-items: center;">1111          <div style="font-size:11px; color:var(--text)">1112            <strong style="color: var(--accent);">AniList Live Explorer 🔍</strong><br>1113            <span style="color:var(--muted)">Search the global AniList database to automatically populate this form.</span>1114          </div>1115        </div>1116        <div style="display: flex; gap: 8px; margin-top: 4px;">1117          <input type="text" id="anilistSearchInput" placeholder="Type anime name (e.g. Frieren, Chainsaw Man)..." style="flex: 1; background: var(--bg); border: 1px solid var(--border); padding: 8px 12px; border-radius: 5px; color: #fff; font-family: var(--sans); font-size: 12px; outline: none; transition: border-color 0.2s;" onkeydown="if(event.key === 'Enter') { event.preventDefault(); searchAniListLive(); }" />1118          <button class="btn success" type="button" style="padding:0 16px; font-size:11px; font-weight:700; height: 33px;" onclick="searchAniListLive()">Search 🌐</button>1119        </div>1120        <!-- Search Results Grid -->1121        <div id="anilistSearchResults" style="display: none; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; max-height: 240px; overflow-y: auto; margin-top: 10px; padding: 4px; border-top: 1px dashed var(--border); padding-top: 10px;"></div>1122      </div>1123      1124      <form id="animeForm" onsubmit="submitAnimeForm(event)">1125        <div class="form-grid">1126          <div class="param-group">1127            <label>Slug <span style="color:var(--red)">*</span></label>1128            <input type="text" id="form_slug" required placeholder="e.g. spy-x-family" />1129          </div>1130          <div class="param-group">1131            <label>Master Title <span style="color:var(--red)">*</span></label>1132            <input type="text" id="form_title" required placeholder="e.g. Spy x Family" />1133          </div>1134          <div class="param-group">1135            <label>Romaji Title</label>1136            <input type="text" id="form_romaji_title" placeholder="e.g. SPY×FAMILY" />1137          </div>1138          <div class="param-group">1139            <label>English Title</label>1140            <input type="text" id="form_english_title" placeholder="e.g. SPY x FAMILY" />1141          </div>1142          <div class="param-group">1143            <label>Native Title</label>1144            <input type="text" id="form_native_title" placeholder="e.g. SPY×FAMILY" />1145          </div>1146          <div class="param-group">1147            <label>Format</label>1148            <select id="form_format" class="admin-select">1149              <option value="">Select format...</option>1150              <option value="TV">TV</option>1151              <option value="MOVIE">MOVIE</option>1152              <option value="OVA">OVA</option>1153              <option value="ONA">ONA</option>1154              <option value="SPECIAL">SPECIAL</option>1155            </select>1156          </div>1157          <div class="param-group">1158            <label>Season</label>1159            <select id="form_season" class="admin-select">1160              <option value="">Select season...</option>1161              <option value="WINTER">WINTER</option>1162              <option value="SPRING">SPRING</option>1163              <option value="SUMMER">SUMMER</option>1164              <option value="FALL">FALL</option>1165            </select>1166          </div>1167          <div class="param-group">1168            <label>Year</label>1169            <input type="number" id="form_year" placeholder="e.g. 2022" />1170          </div>1171          <div class="param-group">1172            <label>Episodes Count</label>1173            <input type="number" id="form_episodes_count" placeholder="e.g. 12" />1174          </div>1175          <div class="param-group">1176            <label>Season Count</label>1177            <input type="number" id="form_season_count" value="1" placeholder="e.g. 1" />1178          </div>1179          <div class="param-group">1180            <label>Status</label>1181            <select id="form_status" class="admin-select">1182              <option value="">Select status...</option>1183              <option value="FINISHED">FINISHED</option>1184              <option value="RELEASING">RELEASING</option>1185              <option value="NOT_YET_RELEASED">NOT_YET_RELEASED</option>1186              <option value="CANCELLED">CANCELLED</option>1187              <option value="HIATUS">HIATUS</option>1188            </select>1189          </div>1190          <div class="param-group">1191            <label>Average Score (0-100)</label>1192            <input type="number" id="form_average_score" min="0" max="100" placeholder="e.g. 85" />1193          </div>1194          <div class="param-group">1195            <label>Popularity</label>1196            <input type="number" id="form_popularity" placeholder="e.g. 145000" />1197          </div>1198          <div class="param-group-full param-group">1199            <label>Genres (comma separated)</label>1200            <input type="text" id="form_genres" placeholder="e.g. Action, Comedy, Supernatural" />

Showing the first 1,200 of 3516 lines. Download the file for the rest.