142 lines
5.7 KiB
HTML
142 lines
5.7 KiB
HTML
|
|
<ng-container *ngIf="this.isLoading">
|
||
|
|
<div class="main term">
|
||
|
|
<div class="text-center">
|
||
|
|
Loading, please wait...
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</ng-container>
|
||
|
|
<ng-container *ngIf="this.isError">
|
||
|
|
<div class="main term">
|
||
|
|
<div class="text-center">
|
||
|
|
An error occured. Maybe try again in a bit?
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</ng-container>
|
||
|
|
<ng-container *ngIf="this.pair && !this.isLoading && !this.isError">
|
||
|
|
<div class="main term mb-2">
|
||
|
|
<div class="fade-stuff">
|
||
|
|
<h1 class="mb-4"># viewing replay pair</h1>
|
||
|
|
<div class="image-container" style="margin: auto">
|
||
|
|
<a href="https://osu.ppy.sh/beatmaps/{{ this.pair.replays[0].beatmap_id }}?mode=osu" target="_blank">
|
||
|
|
<img ngSrc="https://assets.ppy.sh/beatmaps/{{ this.pair.replays[0].beatmap_beatmapset_id }}/covers/cover.jpg" width="260" height="72"
|
||
|
|
alt="Beatmap Cover">
|
||
|
|
<div class="overlay">
|
||
|
|
<h4>
|
||
|
|
{{ this.pair.replays[0].beatmap_title }} <span class="text-muted">by</span> {{ this.pair.replays[0].beatmap_artist }}
|
||
|
|
</h4>
|
||
|
|
★{{ this.pair.replays[0].beatmap_star_rating | number: '1.0-2' }} {{ this.pair.replays[0].beatmap_version }}
|
||
|
|
</div>
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="some-page-wrapper text-center">
|
||
|
|
<div class="row">
|
||
|
|
<div class="column" *ngFor="let replay of this.pair.replays; let i = index">
|
||
|
|
<div class="blue-column">
|
||
|
|
<h2>
|
||
|
|
<a [routerLink]="['/s/' + replay.replay_id]">
|
||
|
|
replay #{{ i + 1 }}
|
||
|
|
</a>
|
||
|
|
</h2>
|
||
|
|
<a class="btn" href="https://osu.ppy.sh/scores/osu/{{ replay.replay_id }}" target="_blank">osu!web</a>
|
||
|
|
<h1>
|
||
|
|
{{ replay.score | number }}
|
||
|
|
</h1>
|
||
|
|
|
||
|
|
<div class="badge-list">
|
||
|
|
<span class="badge" *ngFor="let mod of replay.mods">
|
||
|
|
{{ mod }}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<table class="text-center mt-4" style="width: 80%; margin: auto; margin-top: 40px">
|
||
|
|
<tbody>
|
||
|
|
<tr>
|
||
|
|
<td>Player</td>
|
||
|
|
<td>
|
||
|
|
<a [routerLink]="['/u/' + this.pair.replays[0].username]">{{ this.pair.replays[0].username }}</a>
|
||
|
|
<a class="btn" style="margin-left: 5px" href="https://osu.ppy.sh/users/{{ this.pair.replays[0].user_id }}" target="_blank">osu!web</a>
|
||
|
|
</td>
|
||
|
|
<td>
|
||
|
|
<a [routerLink]="['/u/' + this.pair.replays[1].username]">{{ this.pair.replays[1].username }}</a>
|
||
|
|
<a class="btn" style="margin-left: 5px" href="https://osu.ppy.sh/users/{{ this.pair.replays[1].user_id }}" target="_blank">osu!web</a>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>Date</td>
|
||
|
|
<td>{{ this.pair.replays[0].date }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].date }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>PP</td>
|
||
|
|
<td>{{ this.pair.replays[0].pp | number: '1.2-2' }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].pp | number: '1.2-2' }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>Max Combo</td>
|
||
|
|
<td>{{ this.pair.replays[0].max_combo }}x <span *ngIf="this.pair.replays[0].perfect" class="badge badge-green">perfect</span></td>
|
||
|
|
<td>{{ this.pair.replays[1].max_combo }}x <span *ngIf="this.pair.replays[1].perfect" class="badge badge-green">perfect</span></td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>Accuracy</td>
|
||
|
|
<td>{{ calculateAccuracy(this.pair.replays[0]) | number: '1.2-2' }}%</td>
|
||
|
|
<td>{{ calculateAccuracy(this.pair.replays[1]) | number: '1.2-2' }}%</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>300x</td>
|
||
|
|
<td>{{ this.pair.replays[0].count_300 }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].count_300 }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>100x</td>
|
||
|
|
<td>{{ this.pair.replays[0].count_100 }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].count_100 }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>50x</td>
|
||
|
|
<td>{{ this.pair.replays[0].count_50 }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].count_50 }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>Misses</td>
|
||
|
|
<td>{{ this.pair.replays[0].count_miss }}</td>
|
||
|
|
<td>{{ this.pair.replays[1].count_miss }}</td>
|
||
|
|
</tr>
|
||
|
|
<tr>
|
||
|
|
<td>Grade</td>
|
||
|
|
<td><app-osu-grade [grade]="this.pair.replays[0].rank"></app-osu-grade></td>
|
||
|
|
<td><app-osu-grade [grade]="this.pair.replays[1].rank"></app-osu-grade></td>
|
||
|
|
</tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="main term mb-2">
|
||
|
|
<div class="fade-stuff">
|
||
|
|
<h1 class="mb-4"># analysis</h1>
|
||
|
|
<div class="text-center mb-4 flex-container">
|
||
|
|
|
||
|
|
<div>
|
||
|
|
<h2>Similarity</h2>
|
||
|
|
<div style="font-size: 24px">{{ this.pair.statistics.similarity | number: '1.2-3' }}</div>
|
||
|
|
<p>this number can be understood as the average difference between the two replays in pixels.</p>
|
||
|
|
<p>two copies of the same replay would score <strong>0</strong>, so lower values means <strong>more</strong> similarity.</p>
|
||
|
|
<p>a common lower bound for replay stealing would *usually* be around <strong>10 - 15</strong></p>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<h2>Correlation</h2>
|
||
|
|
<div style="font-size: 24px">{{ this.pair.statistics.correlation | number: '1.2-4' }}</div>
|
||
|
|
<p>this number (range: [0, 1]) also takes into account time-shifts and other variables</p>
|
||
|
|
<p>two copies of the same replay would score <strong>1</strong>, so values closer to <strong>1</strong> mean more similarity and lower values closer to <strong>0</strong> mean less.</p>
|
||
|
|
<p>a common upper bound for replay stealing would be *usually* above <strong>0.997</strong></p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</ng-container>
|