forked from retoor/devplacepy
271 lines
15 KiB
HTML
271 lines
15 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block extra_head %}
|
|
<link rel="stylesheet" href="{{ static_url('/static/css/sidebar.css') }}">
|
|
<link rel="stylesheet" href="{{ static_url('/static/css/isslop.css') }}">
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="isslop-layout isslop-report-page" data-isslop-report>
|
|
<aside class="sidebar-card" role="navigation" aria-label="AI Usage Analyzer">
|
|
<div class="sidebar-heading" role="heading" aria-level="2">AI Usage Analyzer</div>
|
|
<div class="sidebar-nav">
|
|
<a href="/tools" class="sidebar-link">
|
|
<span class="icon">🧰</span>
|
|
All tools
|
|
</a>
|
|
<a href="/tools/isslop" class="sidebar-link">
|
|
<span class="icon">🧪</span>
|
|
New analysis
|
|
</a>
|
|
<a href="/docs/tools-isslop.html" class="sidebar-link">
|
|
<span class="icon">📘</span>
|
|
How it works
|
|
</a>
|
|
<a href="/docs/isslop-checks.html" class="sidebar-link">
|
|
<span class="icon">📖</span>
|
|
The criteria
|
|
</a>
|
|
</div>
|
|
|
|
<div class="sidebar-section">
|
|
<div class="sidebar-heading">On this page</div>
|
|
<div class="sidebar-nav">
|
|
{% if status == "completed" %}
|
|
<a href="#verdict" class="sidebar-link">Verdict</a>
|
|
{% if markdown %}<a href="#report" class="sidebar-link">Report</a>{% endif %}
|
|
{% if images %}<a href="#images" class="sidebar-link">Image review</a>{% endif %}
|
|
{% if dom_pages %}<a href="#dom-signals" class="sidebar-link">Rendered page signals</a>{% endif %}
|
|
{% if files %}<a href="#files" class="sidebar-link">File results</a>{% endif %}
|
|
<a href="#badge" class="sidebar-link">Authenticity badge</a>
|
|
{% elif status == "failed" %}
|
|
<a href="#verdict" class="sidebar-link">Failure details</a>
|
|
{% else %}
|
|
<a href="#progress" class="sidebar-link">Live progress</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if status == "completed" %}
|
|
<div class="sidebar-section">
|
|
<div class="sidebar-heading">Export</div>
|
|
<div class="sidebar-nav">
|
|
<a href="/tools/isslop/{{ uid }}/report.md" class="sidebar-link">Download markdown</a>
|
|
<a href="{{ badge.badge_url }}" class="sidebar-link" target="_blank" rel="noopener">Badge SVG</a>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</aside>
|
|
|
|
<div class="isslop-main">
|
|
<header class="isslop-header">
|
|
<h1><span class="icon">🧪</span> AI usage analysis report</h1>
|
|
<div class="isslop-report-target">
|
|
<span class="isslop-chip">{{ source_kind }}</span>
|
|
<code>{{ source_url }}</code>
|
|
</div>
|
|
</header>
|
|
|
|
{% if status == "failed" %}
|
|
<section id="verdict" class="isslop-empty" role="alert">
|
|
<p>This analysis <strong>failed</strong>: {{ error or "unknown error" }}.</p>
|
|
<p>Start a new one from the <a href="/tools/isslop">AI Usage Analyzer</a>.</p>
|
|
</section>
|
|
{% elif status != "completed" %}
|
|
<section id="progress" class="isslop-live-card" aria-label="Analysis progress">
|
|
<dp-isslop-run uid="{{ uid }}" topic="{{ topic }}" events-url="{{ events_url }}"></dp-isslop-run>
|
|
</section>
|
|
{% else %}
|
|
<section id="verdict" class="isslop-score-card" aria-label="Verdict">
|
|
<div class="isslop-gauge isslop-grade-{{ (grade or 'pending')|lower }}" role="img"
|
|
aria-label="Authenticity grade {{ grade }}">
|
|
<span class="isslop-gauge-grade">{{ grade }}</span>
|
|
<span class="isslop-gauge-label">authenticity</span>
|
|
</div>
|
|
<div class="isslop-score-meta">
|
|
{% if human_percent is not none %}
|
|
<div class="isslop-split" role="img"
|
|
aria-label="{{ human_percent }}% human, {{ ai_percent }}% AI">
|
|
<span class="isslop-split-human" style="width: {{ human_percent }}%"></span>
|
|
<span class="isslop-split-ai" style="width: {{ ai_percent }}%"></span>
|
|
</div>
|
|
{% endif %}
|
|
<div class="isslop-facts">
|
|
<span class="isslop-cat isslop-cat-{{ category or 'uncertain' }}">{{ category or "uncertain" }}</span>
|
|
{% if detected_builder %}<span class="isslop-chip isslop-chip-builder">Detected: built with {{ detected_builder }}</span>{% endif %}
|
|
{% if human_percent is not none %}<span class="isslop-chip">{{ human_percent }}% human</span>{% endif %}
|
|
{% if ai_percent is not none %}<span class="isslop-chip">{{ ai_percent }}% AI</span>{% endif %}
|
|
{% if slop_score is not none %}<span class="isslop-chip">slop score {{ slop_score }}</span>{% endif %}
|
|
{% if origin_score is not none %}<span class="isslop-chip">origin {{ origin_score }}</span>{% endif %}
|
|
{% if quality_deficit_score is not none %}<span class="isslop-chip">quality deficit {{ quality_deficit_score }}</span>{% endif %}
|
|
{% if dom_slop_score is not none and dom_slop_score > 0 %}<span class="isslop-chip">rendered-page score {{ dom_slop_score }}</span>{% endif %}
|
|
<span class="isslop-chip">confidence {{ confidence or "unknown" }}</span>
|
|
<span class="isslop-chip">{{ files_analyzed }} files analyzed</span>
|
|
{% if finished_at %}<span class="isslop-chip">analyzed {{ dt_ago(finished_at) }}</span>{% endif %}
|
|
</div>
|
|
<div class="isslop-report-actions">
|
|
<a class="btn btn-secondary" href="/tools/isslop/{{ uid }}/report.md">Download markdown</a>
|
|
<a class="btn btn-secondary" href="/tools/isslop">New analysis</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{% if markdown %}
|
|
<section id="report" class="isslop-report-body" aria-label="Report">
|
|
<div class="rendered-content">{{ render_content(markdown) }}</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if images %}
|
|
<section id="images" class="isslop-images" aria-label="Image review">
|
|
<h2 class="isslop-section-title">Image review</h2>
|
|
<div class="isslop-image-grid">
|
|
{% for image in images %}
|
|
<div class="isslop-image-card">
|
|
{% if image.thumb_url %}
|
|
<div class="isslop-image-thumb-wrap">
|
|
<img src="{{ image.thumb_url }}" class="isslop-image-thumb" data-lightbox
|
|
alt="{{ image.image_kind }}: {{ image.path }}" loading="lazy">
|
|
</div>
|
|
{% endif %}
|
|
<div class="isslop-image-head">
|
|
<span class="isslop-grade-badge isslop-grade-{{ image.grade|lower }}">{{ image.grade }}</span>
|
|
<span class="isslop-image-kind">{{ image.image_kind }}</span>
|
|
<span class="isslop-chip">{{ image.verdict }} · {{ image.ai_probability|round|int }}% AI</span>
|
|
</div>
|
|
<span class="isslop-image-path">{{ image.path }}</span>
|
|
{% if image.description %}<span class="isslop-image-desc">{{ image.description }}</span>{% endif %}
|
|
{% if image.tells %}
|
|
<div class="isslop-facts">
|
|
{% for tell in image.tells %}<span class="isslop-chip">{{ tell }}</span>{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if dom_pages %}
|
|
<section id="dom-signals" class="isslop-dom-pages" aria-label="Rendered page signals">
|
|
<h2 class="isslop-section-title">Rendered page signals</h2>
|
|
<div class="isslop-image-grid">
|
|
{% for page in dom_pages %}
|
|
<div class="isslop-image-card">
|
|
{% if page.screenshot_url %}
|
|
<div class="isslop-image-thumb-wrap">
|
|
<img src="{{ page.screenshot_url }}" class="isslop-image-thumb" data-lightbox
|
|
alt="rendered page screenshot: {{ page.url }}" loading="lazy">
|
|
</div>
|
|
{% endif %}
|
|
<h3 class="isslop-page-url">{{ page.url }}</h3>
|
|
<div class="isslop-facts">
|
|
{% if page.detected_builder %}<span class="isslop-chip isslop-chip-builder">{{ page.detected_builder }}</span>{% endif %}
|
|
<span class="isslop-chip">{{ page.signal_count }} signals</span>
|
|
</div>
|
|
{% if page.signals %}
|
|
<div class="isslop-facts">
|
|
{% for signal in page.signals[:12] %}
|
|
{% set signal_title = signal.title ~ (" (line " ~ signal.line ~ ")" if signal.line else "") %}
|
|
<span class="isslop-signal-chip isslop-signal-{{ signal.severity }}" title="{{ signal_title }}">
|
|
{{- signal.code -}}
|
|
</span>
|
|
{% endfor %}
|
|
{% if page.signals|length > 12 %}<span class="isslop-signal-chip">+{{ page.signals|length - 12 }}</span>{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if files %}
|
|
{% macro metric_level(value, low, mid, high) -%}
|
|
{%- if value < low %}ok{% elif value < mid %}warn{% elif value < high %}high{% else %}critical{% endif -%}
|
|
{%- endmacro %}
|
|
<section id="files" class="isslop-files" aria-label="File results">
|
|
<h2 class="isslop-section-title">File results</h2>
|
|
<div class="isslop-table-wrap">
|
|
<table class="isslop-table">
|
|
<thead>
|
|
<tr>
|
|
<th>File</th>
|
|
<th>Language</th>
|
|
<th>SLOC</th>
|
|
<th>Origin</th>
|
|
<th>Quality deficit</th>
|
|
<th>Category</th>
|
|
<th>Signals</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for file in files|sort(attribute="quality_deficit_score", reverse=True) %}
|
|
<tr>
|
|
<td>{% if file.source_url %}<a class="isslop-source-link" href="{{ file.source_url }}">{{ file.path }}</a>{% else %}{{ file.path }}{% endif %}</td>
|
|
<td>{{ file.language }}</td>
|
|
<td>{{ file.lines }}</td>
|
|
<td><span class="isslop-metric isslop-metric-{{ metric_level(file.origin_score, 35, 55, 75) }}">{{ file.origin_score }}</span></td>
|
|
<td><span class="isslop-metric isslop-metric-{{ metric_level(file.quality_deficit_score, 30, 50, 75) }}">{{ file.quality_deficit_score }}</span></td>
|
|
<td><span class="isslop-cat isslop-cat-{{ file.category }}">{{ file.category }}</span></td>
|
|
<td>
|
|
{% for group in file.signal_groups[:4] %}
|
|
{% set chip_title = group.title ~ (" (" ~ group.count ~ " occurrences, lines " ~ group.lines|join(", ") ~ ")" if group.count > 1 else (" (line " ~ group.lines[0] ~ ")" if group.lines else "")) %}
|
|
{% if file.source_url and group.lines %}
|
|
<a class="isslop-signal-chip isslop-signal-{{ group.severity }}"
|
|
href="{{ file.source_url }}&line={{ group.lines[0] }}#L{{ group.lines[0] }}"
|
|
title="{{ chip_title }}">
|
|
{{- group.code -}}
|
|
{%- if group.count > 1 %}<span class="isslop-signal-count">{{ group.count }}</span>{% endif -%}
|
|
</a>
|
|
{% else %}
|
|
<span class="isslop-signal-chip isslop-signal-{{ group.severity }}" title="{{ chip_title }}">
|
|
{{- group.code -}}
|
|
{%- if group.count > 1 %}<span class="isslop-signal-count">{{ group.count }}</span>{% endif -%}
|
|
</span>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if file.signal_groups|length > 4 %}<span class="isslop-signal-chip">+{{ file.signal_groups|length - 4 }}</span>{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</section>
|
|
{% endif %}
|
|
|
|
<section id="badge" class="isslop-badge-panel" aria-label="Authenticity badge">
|
|
<h2 class="isslop-section-title">Authenticity badge</h2>
|
|
<div class="isslop-badge-preview">
|
|
<img src="{{ badge.badge_url }}" alt="authenticity human score badge">
|
|
</div>
|
|
<div class="isslop-snippet">
|
|
<code>{{ badge.markdown }}</code>
|
|
<button type="button" class="btn btn-secondary" data-copy-text="{{ badge.markdown }}">Copy markdown</button>
|
|
</div>
|
|
<div class="isslop-snippet">
|
|
<code>{{ badge.html }}</code>
|
|
<button type="button" class="btn btn-secondary" data-copy-text="{{ badge.html }}">Copy HTML</button>
|
|
</div>
|
|
<p class="isslop-history-detail">
|
|
Generated by {{ generator_model or "the static engine" }}{% if generated_at %} {{ dt_ago(generated_at) }}{% endif %}.
|
|
{% if content_hash %}Content hash {{ content_hash[:16] }}.{% endif %}
|
|
</p>
|
|
</section>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script type="module">
|
|
document.querySelectorAll("[data-copy-text]").forEach((button) => {
|
|
button.addEventListener("click", async () => {
|
|
await navigator.clipboard.writeText(button.dataset.copyText);
|
|
if (window.app && window.app.toast) window.app.toast.show("Copied to clipboard");
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|