mtg-playerinfo 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +4 -0
- package/.github/workflows/update-test-data.yml +2 -0
- package/README.md +16 -7
- package/package.json +4 -5
- package/scripts/update-test-data.js +2 -1
- package/src/fetchers/melee.js +2 -2
- package/src/fetchers/mtgElo.js +2 -2
- package/src/fetchers/unityLeague.js +2 -2
- package/src/fetchers/untapped.js +4 -3
- package/src/utils/socialMediaExtractor.js +0 -1
- package/test/data/melee.html +33 -33
- package/test/data/mtgElo.html +1 -1
- package/test/data/topdeck.html +3 -3
- package/test/data/unityLeague.html +97 -16
- package/test/data/untapped.json +1 -1
- package/test/melee.test.js +54 -17
- package/test/mtgElo.test.js +62 -23
- package/test/playerInfoManager.test.js +365 -0
- package/test/socialMediaExtractor.test.js +31 -0
- package/test/topdeck.test.js +69 -33
- package/test/unityLeague.test.js +59 -18
- package/test/untapped.test.js +107 -64
- package/test_utils/helpers.js +32 -0
- package/test/edgeCases.test.js +0 -128
- package/test/meleeEdgeCases.test.js +0 -53
- package/test/mtgEloEdgeCases.test.js +0 -92
- package/test/unityLeagueEdgeCases.test.js +0 -123
- package/test/verboseLogging.test.js +0 -213
- package/test/winRatePrecision.test.js +0 -25
package/.github/workflows/ci.yml
CHANGED
|
@@ -11,6 +11,8 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
13
|
- uses: actions/checkout@v4
|
|
14
|
+
env:
|
|
15
|
+
UNTAPPED_SET_CODE: ${{ vars.UNTAPPED_SET_CODE }}
|
|
14
16
|
|
|
15
17
|
- name: Use Node.js
|
|
16
18
|
uses: actions/setup-node@v4
|
|
@@ -35,6 +37,8 @@ jobs:
|
|
|
35
37
|
|
|
36
38
|
steps:
|
|
37
39
|
- uses: actions/checkout@v4
|
|
40
|
+
env:
|
|
41
|
+
UNTAPPED_SET_CODE: ${{ vars.UNTAPPED_SET_CODE }}
|
|
38
42
|
|
|
39
43
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
40
44
|
uses: actions/setup-node@v4
|
package/README.md
CHANGED
|
@@ -53,8 +53,11 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
53
53
|
"facebook": "bjoern.kimminich",
|
|
54
54
|
"twitch": "koshiii",
|
|
55
55
|
"youtube": "@BjörnKimminich",
|
|
56
|
-
"mtga_rank":
|
|
57
|
-
|
|
56
|
+
"mtga_rank": {
|
|
57
|
+
"constructed": "Platinum 3",
|
|
58
|
+
"limited": "Bronze 4"
|
|
59
|
+
},
|
|
60
|
+
"win rate": "47.45%"
|
|
58
61
|
},
|
|
59
62
|
"sources": {
|
|
60
63
|
"Unity League": {
|
|
@@ -69,10 +72,10 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
69
72
|
"team": "Mull to Five",
|
|
70
73
|
"bio": "Smugly held back on an Untimely Malfunction against a Storm player going off, being totally sure that you can redirect the summed-up damage of their Grapeshots back to their face with its \"Change the target of target spell or ability with a single target\" mode.",
|
|
71
74
|
"rank germany": "62",
|
|
72
|
-
"rank europe": "
|
|
73
|
-
"rank points": "
|
|
74
|
-
"record": "
|
|
75
|
-
"win rate": "51.
|
|
75
|
+
"rank europe": "506",
|
|
76
|
+
"rank points": "334",
|
|
77
|
+
"record": "52-47-5",
|
|
78
|
+
"win rate": "51.6%"
|
|
76
79
|
}
|
|
77
80
|
},
|
|
78
81
|
"MTG Elo Project": {
|
|
@@ -101,6 +104,9 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
101
104
|
"data": {
|
|
102
105
|
"name": "Björn Kimminich",
|
|
103
106
|
"photo": "https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/2a7b8d12-5924-4a58-5f9c-c0bf55766800/square",
|
|
107
|
+
"pronouns": "He/Him",
|
|
108
|
+
"twitter": "bkimminich",
|
|
109
|
+
"youtube": "@BjörnKimminich",
|
|
104
110
|
"tournaments": "2",
|
|
105
111
|
"record": "4-6-1",
|
|
106
112
|
"win rate": "36.36%",
|
|
@@ -110,7 +116,10 @@ General meta-data fields like `name`, `photo`, `age`, `country`, and `hometown`
|
|
|
110
116
|
"Untapped.gg": {
|
|
111
117
|
"url": "https://mtga.untapped.gg/profile/7de50700-c3f6-48e4-a38d-2add5b0d9b71/76DCDWCZS5FX5PIEEMUVY6GV74",
|
|
112
118
|
"data": {
|
|
113
|
-
"mtga_rank":
|
|
119
|
+
"mtga_rank": {
|
|
120
|
+
"constructed": "Platinum 3",
|
|
121
|
+
"limited": "Bronze 4"
|
|
122
|
+
}
|
|
114
123
|
}
|
|
115
124
|
}
|
|
116
125
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mtg-playerinfo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A simple NPM module and CLI tool to pull Magic: The Gathering player data from various sources",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -16,10 +16,9 @@
|
|
|
16
16
|
"extension": [
|
|
17
17
|
".js"
|
|
18
18
|
],
|
|
19
|
-
"
|
|
20
|
-
"src/
|
|
21
|
-
"
|
|
22
|
-
"cli.js"
|
|
19
|
+
"exclude": [
|
|
20
|
+
"src/utils/httpClient.js",
|
|
21
|
+
"test/"
|
|
23
22
|
],
|
|
24
23
|
"sourceMap": true,
|
|
25
24
|
"instrument": true
|
|
@@ -2,13 +2,14 @@ const fs = require('fs')
|
|
|
2
2
|
const path = require('path')
|
|
3
3
|
const { request } = require('../src/utils/httpClient')
|
|
4
4
|
|
|
5
|
+
const setCode = process.env.UNTAPPED_SET_CODE || 'ECL'
|
|
5
6
|
const targets = [
|
|
6
7
|
{ id: '16215', url: 'https://unityleague.gg/player/16215/', file: 'unityLeague.html' },
|
|
7
8
|
{ id: '3irvwtmk', url: 'https://mtgeloproject.net/profile/3irvwtmk', file: 'mtgElo.html' },
|
|
8
9
|
{ id: 'k0shiii', url: 'https://melee.gg/Profile/Index/k0shiii', file: 'melee.html' },
|
|
9
10
|
{ id: 'k0shiii', url: 'https://topdeck.gg/profile/@k0shiii', file: 'topdeck.html' },
|
|
10
11
|
{ id: 'm4VSTJShiXR1PCSCWaM9TBY0rcg1', url: 'https://topdeck.gg/profile/m4VSTJShiXR1PCSCWaM9TBY0rcg1/stats', file: 'topdeck.json' },
|
|
11
|
-
{ id: 'e9d6fb9b-1f91-4063-8b28-0d46458d01a9/ZTATRXEQEJHUDOO52NWQCJGMQY', url:
|
|
12
|
+
{ id: 'e9d6fb9b-1f91-4063-8b28-0d46458d01a9/ZTATRXEQEJHUDOO52NWQCJGMQY', url: `https://api.mtga.untapped.gg/api/v1/games/users/e9d6fb9b-1f91-4063-8b28-0d46458d01a9/players/ZTATRXEQEJHUDOO52NWQCJGMQY/?card_set=${setCode}`, file: 'untapped.json' }
|
|
12
13
|
]
|
|
13
14
|
|
|
14
15
|
async function updateTestData () {
|
package/src/fetchers/melee.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const httpClient = require('../utils/httpClient')
|
|
2
2
|
const cheerio = require('cheerio')
|
|
3
3
|
const { extractHandle, getPlatformName } = require('../utils/socialMediaExtractor')
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ class MeleeFetcher {
|
|
|
6
6
|
async fetchById (username) {
|
|
7
7
|
const url = `https://melee.gg/Profile/Index/${username}`
|
|
8
8
|
try {
|
|
9
|
-
const { data } = await request(url)
|
|
9
|
+
const { data } = await httpClient.request(url)
|
|
10
10
|
return this.parseHtml(data, url, username)
|
|
11
11
|
} catch (error) {
|
|
12
12
|
console.error(`Error fetching Melee profile ${username}:`, error.message)
|
package/src/fetchers/mtgElo.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const
|
|
1
|
+
const httpClient = require('../utils/httpClient')
|
|
2
2
|
|
|
3
3
|
class MtgEloFetcher {
|
|
4
4
|
async fetchById (id) {
|
|
5
5
|
const url = `https://mtgeloproject.net/profile/${id}`
|
|
6
6
|
try {
|
|
7
|
-
const { data: html } = await request(url, {
|
|
7
|
+
const { data: html } = await httpClient.request(url, {
|
|
8
8
|
maxRedirects: 10
|
|
9
9
|
})
|
|
10
10
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const
|
|
1
|
+
const httpClient = require('../utils/httpClient')
|
|
2
2
|
const cheerio = require('cheerio')
|
|
3
3
|
|
|
4
4
|
class UnityLeagueFetcher {
|
|
5
5
|
async fetchById (id) {
|
|
6
6
|
const url = `https://unityleague.gg/player/${id}/`
|
|
7
7
|
try {
|
|
8
|
-
const { data } = await request(url)
|
|
8
|
+
const { data } = await httpClient.request(url)
|
|
9
9
|
return this.parseHtml(data, url)
|
|
10
10
|
} catch (error) {
|
|
11
11
|
console.error(`Error fetching Unity League player ${id}:`, error.message)
|
package/src/fetchers/untapped.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const httpClient = require('../utils/httpClient')
|
|
2
2
|
|
|
3
3
|
class UntappedFetcher {
|
|
4
4
|
async fetchById (id) {
|
|
@@ -10,11 +10,12 @@ class UntappedFetcher {
|
|
|
10
10
|
|
|
11
11
|
const userId = parts[0]
|
|
12
12
|
const playerCode = parts[1]
|
|
13
|
+
const setCode = process.env.UNTAPPED_SET_CODE || 'ECL'
|
|
13
14
|
const url = `https://mtga.untapped.gg/profile/${userId}/${playerCode}`
|
|
14
|
-
const apiUrl = `https://api.mtga.untapped.gg/api/v1/games/users/${userId}/players/${playerCode}/?card_set
|
|
15
|
+
const apiUrl = `https://api.mtga.untapped.gg/api/v1/games/users/${userId}/players/${playerCode}/?card_set=${setCode}`
|
|
15
16
|
|
|
16
17
|
try {
|
|
17
|
-
const { data } = await request(apiUrl)
|
|
18
|
+
const { data } = await httpClient.request(apiUrl)
|
|
18
19
|
const matches = typeof data === 'string' ? JSON.parse(data) : data
|
|
19
20
|
|
|
20
21
|
if (!Array.isArray(matches) || matches.length === 0) {
|
package/test/data/melee.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<title>Profile k0shiii | Melee</title>
|
|
8
8
|
<impact-site-verification value="4c243f18-8267-493f-a951-c8659ec151bc"></impact-site-verification>
|
|
9
9
|
<meta content="@MeleePlatform" property="twitter:site"></meta>
|
|
10
|
-
<meta content="0.3.63.
|
|
10
|
+
<meta content="0.3.63.108" name="version"></meta>
|
|
11
11
|
<meta content="https://cdn.melee.gg/images/blankbrandimage.png" property="og:image"></meta>
|
|
12
12
|
<meta content="Melee.gg Logo" property="twitter:image:alt"></meta>
|
|
13
13
|
<meta content="https://melee.gg/" property="og:url"></meta>
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
<meta name="author" content="Keyrune Incorporated"/>
|
|
37
37
|
<meta property="og:site_name" content="Melee.gg"/>
|
|
38
38
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
|
39
|
-
<link href="https://cdn.melee.gg/content/site.dependencies.min.css?v=0.3.63.
|
|
39
|
+
<link href="https://cdn.melee.gg/content/site.dependencies.min.css?v=0.3.63.108" rel="stylesheet"/>
|
|
40
40
|
|
|
41
|
-
<link href="/Content/site.min.css?v=0.3.63.
|
|
41
|
+
<link href="/Content/site.min.css?v=0.3.63.108&lg=en" rel="stylesheet"/>
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
|
|
@@ -579,36 +579,36 @@
|
|
|
579
579
|
</div>
|
|
580
580
|
</script>
|
|
581
581
|
|
|
582
|
-
<script src="https://cdn.melee.gg/scripts/site.min.js?v=0.3.63.
|
|
583
|
-
<script src="https://cdn.melee.gg/scripts/font-awesome.min.js?v=0.3.63.
|
|
584
|
-
<script src="/Scripts/flattsware.core.min.js?v=0.3.63.
|
|
585
|
-
<script src="/Scripts/flattsware.filters.min.js?v=0.3.63.
|
|
586
|
-
<script src="/Scripts/flattsware.enums.min.js?v=0.3.63.
|
|
587
|
-
<script src="/Scripts/flattsware.standings.min.js?v=0.3.63.
|
|
588
|
-
<script src="/Scripts/flattsware.datatables.min.js?v=0.3.63.
|
|
589
|
-
<script src="/Scripts/flattsware.datetime.min.js?v=0.3.63.
|
|
590
|
-
<script src="/Scripts/flattsware.encode.min.js?v=0.3.63.
|
|
591
|
-
<script src="/Scripts/flattsware.regex.min.js?v=0.3.63.
|
|
592
|
-
<script src="/Scripts/flattsware.notify.min.js?v=0.3.63.
|
|
593
|
-
<script src="/Scripts/flattsware.spinner.min.js?v=0.3.63.
|
|
594
|
-
<script src="/Scripts/flattsware.forms.min.js?v=0.3.63.
|
|
595
|
-
<script src="/Scripts/flattsware.decklist.min.js?v=0.3.63.
|
|
596
|
-
<script src="/Scripts/flattsware.idle.min.js?v=0.3.63.
|
|
597
|
-
<script src="/Scripts/flattsware.hovercard.min.js?v=0.3.63.
|
|
598
|
-
<script src="/Scripts/flattsware.chart.min.js?v=0.3.63.
|
|
599
|
-
<script src="/Scripts/flattsware.formats.min.js?v=0.3.63.
|
|
600
|
-
<script src="/Scripts/flattsware.star-rating.min.js?v=0.3.63.
|
|
601
|
-
<script src="/Scripts/flattsware.progress.min.js?v=0.3.63.
|
|
602
|
-
<script src="/Scripts/flattsware.location.min.js?v=0.3.63.
|
|
603
|
-
<script src="/Scripts/flattsware.players.min.js?v=0.3.63.
|
|
604
|
-
<script src="/signalr/hubs?v=0.3.63.
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
<script src="/Scripts/wp-banners.min.js?v=0.3.63.
|
|
582
|
+
<script src="https://cdn.melee.gg/scripts/site.min.js?v=0.3.63.108"></script>
|
|
583
|
+
<script src="https://cdn.melee.gg/scripts/font-awesome.min.js?v=0.3.63.108"></script>
|
|
584
|
+
<script src="/Scripts/flattsware.core.min.js?v=0.3.63.108&lg=en"></script>
|
|
585
|
+
<script src="/Scripts/flattsware.filters.min.js?v=0.3.63.108&lg=en"></script>
|
|
586
|
+
<script src="/Scripts/flattsware.enums.min.js?v=0.3.63.108&lg=en"></script>
|
|
587
|
+
<script src="/Scripts/flattsware.standings.min.js?v=0.3.63.108&lg=en"></script>
|
|
588
|
+
<script src="/Scripts/flattsware.datatables.min.js?v=0.3.63.108&lg=en"></script>
|
|
589
|
+
<script src="/Scripts/flattsware.datetime.min.js?v=0.3.63.108&lg=en"></script>
|
|
590
|
+
<script src="/Scripts/flattsware.encode.min.js?v=0.3.63.108&lg=en"></script>
|
|
591
|
+
<script src="/Scripts/flattsware.regex.min.js?v=0.3.63.108&lg=en"></script>
|
|
592
|
+
<script src="/Scripts/flattsware.notify.min.js?v=0.3.63.108&lg=en"></script>
|
|
593
|
+
<script src="/Scripts/flattsware.spinner.min.js?v=0.3.63.108&lg=en"></script>
|
|
594
|
+
<script src="/Scripts/flattsware.forms.min.js?v=0.3.63.108&lg=en"></script>
|
|
595
|
+
<script src="/Scripts/flattsware.decklist.min.js?v=0.3.63.108&lg=en"></script>
|
|
596
|
+
<script src="/Scripts/flattsware.idle.min.js?v=0.3.63.108&lg=en"></script>
|
|
597
|
+
<script src="/Scripts/flattsware.hovercard.min.js?v=0.3.63.108&lg=en"></script>
|
|
598
|
+
<script src="/Scripts/flattsware.chart.min.js?v=0.3.63.108&lg=en"></script>
|
|
599
|
+
<script src="/Scripts/flattsware.formats.min.js?v=0.3.63.108&lg=en"></script>
|
|
600
|
+
<script src="/Scripts/flattsware.star-rating.min.js?v=0.3.63.108&lg=en"></script>
|
|
601
|
+
<script src="/Scripts/flattsware.progress.min.js?v=0.3.63.108&lg=en"></script>
|
|
602
|
+
<script src="/Scripts/flattsware.location.min.js?v=0.3.63.108&lg=en"></script>
|
|
603
|
+
<script src="/Scripts/flattsware.players.min.js?v=0.3.63.108&lg=en"></script>
|
|
604
|
+
<script src="/signalr/hubs?v=0.3.63.108"></script>
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
<script src="/Scripts/wp-banners.min.js?v=0.3.63.108&lg=en"></script>
|
|
610
610
|
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-162951615-1"></script>
|
|
611
|
-
<script src="/Scripts/google-analytics.min.js?v=0.3.63.
|
|
611
|
+
<script src="/Scripts/google-analytics.min.js?v=0.3.63.108&lg=en"></script>
|
|
612
612
|
|
|
613
613
|
<!-- Datadog RUM (CDN async) -->
|
|
614
614
|
<script>
|
|
@@ -1790,7 +1790,7 @@ $(() => {
|
|
|
1790
1790
|
<div class="footer-corp">
|
|
1791
1791
|
<img width="40" height="54" src="/images/keyrune-logo.png"/>
|
|
1792
1792
|
<span>
|
|
1793
|
-
All original content on this page is © 2019-2026 Keyrune Incorporated, its licensors, or its partners and may not be used or reproduced without explicit permission. All trademarks are the property of their respective owners. v0.3.63.
|
|
1793
|
+
All original content on this page is © 2019-2026 Keyrune Incorporated, its licensors, or its partners and may not be used or reproduced without explicit permission. All trademarks are the property of their respective owners. v0.3.63.108
|
|
1794
1794
|
</span>
|
|
1795
1795
|
</div>
|
|
1796
1796
|
|
package/test/data/mtgElo.html
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
Sep 5, 11pm Eastern: The site is being refreshed. Some data may be a little wonky. Thanks for your patience!
|
|
6
6
|
</span> --> <span class="block w-full lg:w-[860px] text-center text-[16px] py-1 bg-green-300">
|
|
7
7
|
Welcome to Elo 2.0! See the recent <a href="/blog/58" class="text-blink hover:underline">blog post</a> to learn more.
|
|
8
|
-
</span> </div> <div class="linkdiv hidden lg:block" data-astro-cid-lxcip4ca> <ul class="list-none w-[145px] text-[13pt]" data-astro-cid-lxcip4ca> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/" data-astro-cid-lxcip4ca>home</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/leaders/all" data-astro-cid-lxcip4ca>leaders</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/stats" data-astro-cid-lxcip4ca>statistics</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/headtohead" data-astro-cid-lxcip4ca>head to head</a></li> <!--<li><a href="proteams.php">pro teams</a></li>--> <!--<li><a href="team.php">custom team</a></li>--> <!--<li><a href="mplseason.php">MPL</a></li>--> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/faq" data-astro-cid-lxcip4ca>FAQ</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/blog" data-astro-cid-lxcip4ca>blog</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/links" data-astro-cid-lxcip4ca>links</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/contact" data-astro-cid-lxcip4ca>contact</a></li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>events</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>coverage</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>custom team</li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="https://www.patreon.com/mtgeloproject" style="color:#060" data-astro-cid-lxcip4ca>Patreon</a></li> </ul> </div> <!-- <MobileMenu client:only /> --> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();;(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(s+=` (export ${v})`),console.error(`[hydrate] Error parsing props for component ${s}`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(`astro:${c}`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();</script><astro-island uid="12oLMo" prefix="r0" component-url="/_astro/Search.BA4QD767.js" component-export="default" renderer-url="/_astro/client.csHNARWA.js" props="{"first":[0],"last":[0]}" ssr="" client="load" opts="{"name":"Search","value":true}" await-children=""><div class="lg:block lg:w-auto w-full inline-flex flex-row justify-between"><div class="lg:hidden z-10 inline-block" data-headlessui-state=""><button class=" lg:hidden relative inline-flex items-center justify-center rounded-md p-2 hover:bg-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-gray-500" id="headlessui-disclosure-button-:r0R5:" type="button" aria-expanded="false" data-headlessui-state=""><span class="absolute -inset-0.5"></span><span class="sr-only">Open main menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="block h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path></svg></button></div><form class="inline-flex flex-row gap-1 lg:inline-block lg:h-[80px] pt-[2px]" autoComplete="off"><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="last_name[last]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="Last Name" placeholder="last name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1mm:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="first_name[first_name]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="First Name" placeholder="first name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1n6:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="submit" class="text-[14px] bg-gray border border-nines p-1 rounded-[5px] focus:bg-nuts hover:bg-nuts" value="Search"/></form></div><!--astro:end--></astro-island> <main class="mx-4 lg:mx-[150px]"> <div class="w-[710px] inline-block"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="
|
|
8
|
+
</span> </div> <div class="linkdiv hidden lg:block" data-astro-cid-lxcip4ca> <ul class="list-none w-[145px] text-[13pt]" data-astro-cid-lxcip4ca> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/" data-astro-cid-lxcip4ca>home</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/leaders/all" data-astro-cid-lxcip4ca>leaders</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/stats" data-astro-cid-lxcip4ca>statistics</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/headtohead" data-astro-cid-lxcip4ca>head to head</a></li> <!--<li><a href="proteams.php">pro teams</a></li>--> <!--<li><a href="team.php">custom team</a></li>--> <!--<li><a href="mplseason.php">MPL</a></li>--> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/faq" data-astro-cid-lxcip4ca>FAQ</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/blog" data-astro-cid-lxcip4ca>blog</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/links" data-astro-cid-lxcip4ca>links</a></li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="/contact" data-astro-cid-lxcip4ca>contact</a></li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>events</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>coverage</li> <li class="block py-[3px] px-1 hover:bg-gray text-nines" data-astro-cid-lxcip4ca>custom team</li> <li data-astro-cid-lxcip4ca><a class="block py-[3px] px-1 hover:bg-gray" href="https://www.patreon.com/mtgeloproject" style="color:#060" data-astro-cid-lxcip4ca>Patreon</a></li> </ul> </div> <!-- <MobileMenu client:only /> --> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();;(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[o]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let[l,e]=t;return l in i?i[l](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([l,e])=>[l,o(e)]));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template[data-astro-template]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("data-astro-template")||"default"]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n[r.getAttribute("name")||"default"]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(s+=` (export ${v})`),console.error(`[hydrate] Error parsing props for component ${s}`,this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro[c]===void 0){window.addEventListener(`astro:${c}`,()=>this.start(),{once:!0});return}try{await Astro[c](async()=>{let n=this.getAttribute("renderer-url"),[h,{default:p}]=await Promise.all([import(this.getAttribute("component-url")),n?import(n):()=>()=>{}]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h[u];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component[f]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",["props"]),customElements.get("astro-island")||customElements.define("astro-island",y)}})();</script><astro-island uid="12oLMo" prefix="r0" component-url="/_astro/Search.BA4QD767.js" component-export="default" renderer-url="/_astro/client.csHNARWA.js" props="{"first":[0],"last":[0]}" ssr="" client="load" opts="{"name":"Search","value":true}" await-children=""><div class="lg:block lg:w-auto w-full inline-flex flex-row justify-between"><div class="lg:hidden z-10 inline-block" data-headlessui-state=""><button class=" lg:hidden relative inline-flex items-center justify-center rounded-md p-2 hover:bg-white focus:outline-none focus:ring-2 focus:ring-inset focus:ring-gray-500" id="headlessui-disclosure-button-:r0R5:" type="button" aria-expanded="false" data-headlessui-state=""><span class="absolute -inset-0.5"></span><span class="sr-only">Open main menu</span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="block h-6 w-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"></path></svg></button></div><form class="inline-flex flex-row gap-1 lg:inline-block lg:h-[80px] pt-[2px]" autoComplete="off"><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="last_name[last]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="Last Name" placeholder="last name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1mm:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="hidden" hidden="" readonly="" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none"/><input type="hidden" hidden="" readonly="" name="first_name[first_name]" style="position:fixed;top:1px;left:1px;width:1px;height:0;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0;display:none" value=""/><input aria-label="First Name" placeholder="first name" class="lg:mr-4 rounded-lg border border-cookie focus:bg-gray py-1.5 px-2" id="headlessui-combobox-input-:r0R1n6:" role="combobox" type="text" aria-expanded="false" aria-autocomplete="list" data-headlessui-state=""/><input type="submit" class="text-[14px] bg-gray border border-nines p-1 rounded-[5px] focus:bg-nuts hover:bg-nuts" value="Search"/></form></div><!--astro:end--></astro-island> <main class="mx-4 lg:mx-[150px]"> <div class="w-[710px] inline-block"> <script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();</script><astro-island uid="Z1jDnfy" component-url="/_astro/Profile.D6E0cspP.js" component-export="default" renderer-url="/_astro/client.csHNARWA.js" props="{"playerid":[0,"3irvwtmk"],"info":[0,{"id":[0,"3irvwtmk"],"first_name":[0,"Bjoern"],"last_name":[0,"Kimminich"],"record":[1,[[0,9],[0,12],[0,1]]],"pro_record":[1,[[0,null],[0,null],[0,null]]],"current_rating":[0,1465.65],"ranking":[0,162097],"active_ranking":[0,29237],"best_event":[0,"ssutr25"],"best_round":[0,"7"],"best_id":[0,3852351],"nakamura_number":[0,2],"nakamura_match_id":[0,3959107]}]}" ssr="" client="only" opts="{"name":"Profile","value":"react"}"></astro-island> </div> </main> </body></html>
|
package/test/data/topdeck.html
CHANGED
|
@@ -96,7 +96,7 @@ gtag('config', 'G-56527VG23P');
|
|
|
96
96
|
}).then((ret) => {
|
|
97
97
|
location.reload();
|
|
98
98
|
});
|
|
99
|
-
}</script><!-- Page content--><div class="offcanvas offcanvas-end w-100" id="viewDecklistOffcanvas" tabindex="-1" aria-labelledby="viewDecklistOffcanvasLabel" aria-hidden="true"><div class="offcanvas-header bg-primary"><h5 class="offcanvas-title" id="viewDecklistOffcanvasLabel">Decklist</h5><button class="btn-close btn-close-white" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button></div><div class="offcanvas-body bg-dark"><pre class="mb-3"><code class="language-json" id="decklistContent"></code></pre></div></div><script src="/js/supportedGames?t=
|
|
99
|
+
}</script><!-- Page content--><div class="offcanvas offcanvas-end w-100" id="viewDecklistOffcanvas" tabindex="-1" aria-labelledby="viewDecklistOffcanvasLabel" aria-hidden="true"><div class="offcanvas-header bg-primary"><h5 class="offcanvas-title" id="viewDecklistOffcanvasLabel">Decklist</h5><button class="btn-close btn-close-white" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button></div><div class="offcanvas-body bg-dark"><pre class="mb-3"><code class="language-json" id="decklistContent"></code></pre></div></div><script src="/js/supportedGames?t=1772334609342"></script><script>function viewTextDecklist(decklist, title, tournamentId = null, playerId = null, game = null) {
|
|
100
100
|
// Use dynamically served games list
|
|
101
101
|
const supportedGames = window.SUPPORTED_GAMES;
|
|
102
102
|
|
|
@@ -139,7 +139,7 @@ gtag('config', 'G-56527VG23P');
|
|
|
139
139
|
#viewDecklistOffcanvas {
|
|
140
140
|
width: 660px !important;
|
|
141
141
|
}
|
|
142
|
-
}</style><!-- Hero Section with Cover Photo--><div class="position-relative overflow-hidden"><div class="position-relative" style="height: 280px; background-image: url(https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/aa6d70ad-de73-4c09-a4d7-1e64d5ed6d00/cover); background-size: cover; background-position: center;"><div class="position-absolute top-0 start-0 w-100 h-100 bg-dark" style="opacity: 0.2"></div></div><!-- Decorative wave divider--><div class="position-absolute bottom-0 w-100"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 100" preserveAspectRatio="none" style="height: 50px; width: 100%;"><path fill="#0a0e17" d="M0,32L60,42.7C120,53,240,75,360,74.7C480,75,600,53,720,42.7C840,32,960,32,1080,37.3C1200,43,1320,53,1380,58.7L1440,64L1440,100L1380,100C1320,100,1200,100,1080,100C960,100,840,100,720,100C600,100,480,100,360,100C240,100,120,100,60,100L0,100Z"></path></svg></div></div><!-- Profile Card--><div class="container position-relative"><div class="card bg-dark text-white shadow-lg border-0 rounded-4 mt-n5 position-relative" style="z-index: 2;"><div class="card-body py-4 px-md-4"><div class="row align-items-start"><!-- Avatar Column--><div class="col-lg-2 col-md-3 text-center text-md-start mb-4 mb-md-0"><div class="position-relative mx-auto" style="width: fit-content;"><img class="rounded-circle shadow-lg" src="https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/2a7b8d12-5924-4a58-5f9c-c0bf55766800/square" alt="Profile Picture" style="width: 140px; height: 140px; object-fit: cover; margin-top: -70px; border: 4px solid #0a0e17; background-color: #0a0e17;"><span class="badge text-white position-absolute start-100 translate-middle-y" style="background-color: #5A4F9E; margin-left: -20px; margin-top: -30px; font-size: 0.8rem">He/Him</span></div></div><!-- Player Info & About--><div class="col-lg-5 col-md-9 my-sm-auto mb-4"><h2 class="text-white fw-bold mb-1">Björn Kimminich</h2><div class="d-flex flex-wrap mt-2 gap-2"><a class="btn btn-social bs-outline bs-twitter bs-dark me-2" href="https://twitter.com/bkimminich" target="_blank"><i class="fa-brands fa-twitter"></i></a><a class="btn btn-social bs-outline bs-youtube bs-dark" href="https://www.youtube.com/@Bj%C3%B6rnKimminich" target="_blank"><i class="fa-brands fa-youtube"></i></a></div><div class="d-flex flex-wrap gap-2 mt-3" id="badgeContainer"></div></div><!-- Stats Card--><div class="col-lg-5 mx-auto"><div class="card bg-dark border-0 shadow-lg rounded-4 position-relative overflow-hidden"><!-- Decorative gradient background--><div class="position-absolute top-0 start-0 w-100 h-100" style="background: linear-gradient(45deg, rgba(90, 79, 158, 0.2), rgba(0, 0, 0, 0)); opacity: 0.7; z-index: 0;"></div><div class="card-body position-relative p-4" style="z-index: 1;"><h4 class="text-white fw-bold mb-4" id="statsTitle">Player Stats</h4><div class="row g-3"><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-trophy text-warning fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="totalTournaments">0</h5><p class="text-light small mb-0">Tournaments</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-chart-line text-success fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallRecord">0-0-0</h5><p class="text-light small mb-0">Record</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-percentage text-info fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallWinRate">0%</h5><p class="text-light small mb-0">Win Rate</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-bolt text-danger fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="conversionRate">0%</h5><p class="text-light small mb-0">Conversion</p></div></div></div></div></div></div></div></div></div></div><!-- Modern Pill Tabs--><div class="card bg-dark border-0 shadow-sm rounded-4 mt-4 p-3"><div class="card-body p-0"><ul class="nav nav-pills gap-2 mb-0" role="tablist"><li class="nav-item"><a class="nav-link active py-3 rounded-3" href="#history" data-bs-toggle="tab"><i class="fa-solid fa-trophy me-2"></i>Tournaments</a></li></ul></div></div><!-- Content tabs--><div class="tab-content mt-4 mb-5"><!-- Tournament History Tab--><div class="tab-pane fade show active" id="history"><div class="card bg-dark border-0 rounded-4 shadow-lg py-4 px-3 px-sm-4"><!-- Filters Section--><div class="d-flex flex-wrap gap-3 mb-4 align-items-center"><!-- Format Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="formatDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-layer-group me-2"></i><span id="formatDropdownLabel">All Formats</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Formats</a></li></ul></div><!-- Year Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="yearDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-calendar-alt me-2"></i><span id="yearDropdownLabel">All Years</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Years</a></li></ul></div></div><h3 class="card-title text-white fw-bold"><i class="fa-solid fa-history me-2 text-info"></i>Tournament History</h3><div class="tournament-list" id="tournamentList"></div></div></div></div></div></main><footer class="footer bg-black py-5"><div class="container pt-md-2 pt-lg-3"><div class="row pt-sm-2"><!-- Logo, description, and social column--><div class="col-md-4 col-lg-3 pb-2 pb-md-0 mb-4 mb-md-0"><a class="d-block mb-3 mb-md-4" href="/"><img class="img-fluid" src="/img/logo/TopDeckFullWhiteNS.png" alt="TopDeck.gg" style="max-width: 200px;"></a><p class="text-muted pb-2 pb-md-3 mb-3 fs-sm">Discover, organize, and compete in trading card game events. Connect with players worldwide and elevate your game.</p><div class="d-flex gap-1"><a class="btn-social bs-outline bs-light bs-facebook bs-lg me-2" href="https://discord.gg/RjS3mDf3wt" target="_blank"><i class="fa-brands fa-discord"></i></a><a class="btn-social bs-outline bs-light bs-youtube bs-lg me-2" href="https://www.youtube.com/@TopDeckGG_" target="_blank"><i class="fa-brands fa-youtube"></i></a></div></div><!-- Nested columns for links--><div class="col-md-8 col-lg-7 offset-lg-2"><div class="row row-cols-1 row-cols-sm-3"><!-- Company column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Company</h4><ul><li><a class="widget-link" href="/subscribe">Run a Tournament</a></li><li><a class="widget-link" href="https://newsletter.topdeck.gg/">Newsletter</a></li><li><a class="widget-link" href="/docs/tournaments-v2">API Documentation</a></li><li><a class="widget-link" href="/championship-series-2026">Championship Series</a></li></ul></div></div><!-- Support column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Support</h4><ul><li><a class="widget-link" href="/cdn-cgi/l/email-protection#
|
|
142
|
+
}</style><!-- Hero Section with Cover Photo--><div class="position-relative overflow-hidden"><div class="position-relative" style="height: 280px; background-image: url(https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/aa6d70ad-de73-4c09-a4d7-1e64d5ed6d00/cover); background-size: cover; background-position: center;"><div class="position-absolute top-0 start-0 w-100 h-100 bg-dark" style="opacity: 0.2"></div></div><!-- Decorative wave divider--><div class="position-absolute bottom-0 w-100"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 100" preserveAspectRatio="none" style="height: 50px; width: 100%;"><path fill="#0a0e17" d="M0,32L60,42.7C120,53,240,75,360,74.7C480,75,600,53,720,42.7C840,32,960,32,1080,37.3C1200,43,1320,53,1380,58.7L1440,64L1440,100L1380,100C1320,100,1200,100,1080,100C960,100,840,100,720,100C600,100,480,100,360,100C240,100,120,100,60,100L0,100Z"></path></svg></div></div><!-- Profile Card--><div class="container position-relative"><div class="card bg-dark text-white shadow-lg border-0 rounded-4 mt-n5 position-relative" style="z-index: 2;"><div class="card-body py-4 px-md-4"><div class="row align-items-start"><!-- Avatar Column--><div class="col-lg-2 col-md-3 text-center text-md-start mb-4 mb-md-0"><div class="position-relative mx-auto" style="width: fit-content;"><img class="rounded-circle shadow-lg" src="https://imagedelivery.net/kN_u_RUfFF6xsGMKYWhO1g/2a7b8d12-5924-4a58-5f9c-c0bf55766800/square" alt="Profile Picture" style="width: 140px; height: 140px; object-fit: cover; margin-top: -70px; border: 4px solid #0a0e17; background-color: #0a0e17;"><span class="badge text-white position-absolute start-100 translate-middle-y" style="background-color: #5A4F9E; margin-left: -20px; margin-top: -30px; font-size: 0.8rem">He/Him</span></div></div><!-- Player Info & About--><div class="col-lg-5 col-md-9 my-sm-auto mb-4"><h2 class="text-white fw-bold mb-1">Björn Kimminich</h2><div class="d-flex flex-wrap mt-2 gap-2"><a class="btn btn-social bs-outline bs-twitter bs-dark me-2" href="https://twitter.com/bkimminich" target="_blank"><i class="fa-brands fa-twitter"></i></a><a class="btn btn-social bs-outline bs-youtube bs-dark" href="https://www.youtube.com/@Bj%C3%B6rnKimminich" target="_blank"><i class="fa-brands fa-youtube"></i></a></div><div class="d-flex flex-wrap gap-2 mt-3" id="badgeContainer"></div></div><!-- Stats Card--><div class="col-lg-5 mx-auto"><div class="card bg-dark border-0 shadow-lg rounded-4 position-relative overflow-hidden"><!-- Decorative gradient background--><div class="position-absolute top-0 start-0 w-100 h-100" style="background: linear-gradient(45deg, rgba(90, 79, 158, 0.2), rgba(0, 0, 0, 0)); opacity: 0.7; z-index: 0;"></div><div class="card-body position-relative p-4" style="z-index: 1;"><h4 class="text-white fw-bold mb-4" id="statsTitle">Player Stats</h4><div class="row g-3"><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-trophy text-warning fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="totalTournaments">0</h5><p class="text-light small mb-0">Tournaments</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-chart-line text-success fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallRecord">0-0-0</h5><p class="text-light small mb-0">Record</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-percentage text-info fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="overallWinRate">0%</h5><p class="text-light small mb-0">Win Rate</p></div></div></div><div class="col-6"><div class="d-flex align-items-center"><i class="fa-solid fa-bolt text-danger fs-3 me-3"></i><div><h5 class="text-white mb-0 fw-bold" id="conversionRate">0%</h5><p class="text-light small mb-0">Conversion</p></div></div></div></div></div></div></div></div></div></div><!-- Modern Pill Tabs--><div class="card bg-dark border-0 shadow-sm rounded-4 mt-4 p-3"><div class="card-body p-0"><ul class="nav nav-pills gap-2 mb-0" role="tablist"><li class="nav-item"><a class="nav-link active py-3 rounded-3" href="#history" data-bs-toggle="tab"><i class="fa-solid fa-trophy me-2"></i>Tournaments</a></li></ul></div></div><!-- Content tabs--><div class="tab-content mt-4 mb-5"><!-- Tournament History Tab--><div class="tab-pane fade show active" id="history"><div class="card bg-dark border-0 rounded-4 shadow-lg py-4 px-3 px-sm-4"><!-- Filters Section--><div class="d-flex flex-wrap gap-3 mb-4 align-items-center"><!-- Format Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="formatDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-layer-group me-2"></i><span id="formatDropdownLabel">All Formats</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Formats</a></li></ul></div><!-- Year Dropdown - Modern style--><div class="dropdown"><button class="btn btn-outline-secondary dropdown-toggle" id="yearDropdown" type="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fa-solid fa-calendar-alt me-2"></i><span id="yearDropdownLabel">All Years</span></button><ul class="dropdown-menu border-0 shadow"><li><a class="dropdown-item" href="#" data-value="all">All Years</a></li></ul></div></div><h3 class="card-title text-white fw-bold"><i class="fa-solid fa-history me-2 text-info"></i>Tournament History</h3><div class="tournament-list" id="tournamentList"></div></div></div></div></div></main><footer class="footer bg-black py-5"><div class="container pt-md-2 pt-lg-3"><div class="row pt-sm-2"><!-- Logo, description, and social column--><div class="col-md-4 col-lg-3 pb-2 pb-md-0 mb-4 mb-md-0"><a class="d-block mb-3 mb-md-4" href="/"><img class="img-fluid" src="/img/logo/TopDeckFullWhiteNS.png" alt="TopDeck.gg" style="max-width: 200px;"></a><p class="text-muted pb-2 pb-md-3 mb-3 fs-sm">Discover, organize, and compete in trading card game events. Connect with players worldwide and elevate your game.</p><div class="d-flex gap-1"><a class="btn-social bs-outline bs-light bs-facebook bs-lg me-2" href="https://discord.gg/RjS3mDf3wt" target="_blank"><i class="fa-brands fa-discord"></i></a><a class="btn-social bs-outline bs-light bs-youtube bs-lg me-2" href="https://www.youtube.com/@TopDeckGG_" target="_blank"><i class="fa-brands fa-youtube"></i></a></div></div><!-- Nested columns for links--><div class="col-md-8 col-lg-7 offset-lg-2"><div class="row row-cols-1 row-cols-sm-3"><!-- Company column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Company</h4><ul><li><a class="widget-link" href="/subscribe">Run a Tournament</a></li><li><a class="widget-link" href="https://newsletter.topdeck.gg/">Newsletter</a></li><li><a class="widget-link" href="/docs/tournaments-v2">API Documentation</a></li><li><a class="widget-link" href="/championship-series-2026">Championship Series</a></li></ul></div></div><!-- Support column--><div class="col mb-4 mb-md-0"><div class="widget widget-light"><h4 class="widget-title mb-3">Support</h4><ul><li><a class="widget-link" href="/cdn-cgi/l/email-protection#23404c4d5742405763574c53474640480d4444">Contact Us</a></li><li><a class="widget-link" href="/cdn-cgi/l/email-protection#375a52535e56774358475352545c195050">Media Inquiries</a></li><li><a class="widget-link" href="/privacy-policy" target="_blank">Privacy Policy</a></li><li><a class="widget-link" href="/terms-and-conditions" target="_blank">Terms & Conditions</a></li></ul></div></div><!-- Install App column--><div class="col"><h4 class="h6 fw-bold pb-2 mb-0 mb-lg-1">Install App</h4><a class="btn btn-outline-secondary d-inline-flex align-items-center px-3 py-2 mt-3 me-3 me-md-0" href="https://apple.co/3A4Z0FK" role="button" style="min-width: 160px;"><i class="fa-brands fa-apple fs-xl me-2"></i><span class="d-flex flex-column align-items-start"><small class="fs-xs text-white-50">Download on the</small><span class="fs-sm">App Store</span></span></a><a class="btn btn-outline-secondary d-inline-flex align-items-center px-3 py-2 mt-3 me-3 me-md-0" href="https://play.google.com/store/apps/details?id=com.topdeck.app" role="button" style="min-width: 160px;"><i class="fa-brands fa-google-play fs-xl me-2"></i><span class="d-flex flex-column align-items-start"><small class="fs-xs text-white-50">Get it on</small><span class="fs-sm">Google Play</span></span></a></div></div></div></div></div></footer><script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>document.addEventListener('DOMContentLoaded', function () {
|
|
143
143
|
// Template variables for decklist viewing
|
|
144
144
|
const playerUsername = "@k0shiii";
|
|
145
145
|
const playerId = "m4VSTJShiXR1PCSCWaM9TBY0rcg1";
|
|
@@ -774,5 +774,5 @@ gtag('config', 'G-56527VG23P');
|
|
|
774
774
|
|
|
775
775
|
return formatStats;
|
|
776
776
|
}
|
|
777
|
-
});</script><!-- Back to top button--><a class="btn-scroll-top" href="#top" data-scroll data-fixed-element><span class="btn-scroll-top-tooltip text-muted fs-sm me-2">Top</span><i class="btn-scroll-top-icon ai-arrow-up"> </i></a><!-- Vendor scrits: js libraries and plugins--><script src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js"></script><script src="/vendor/simplebar/dist/simplebar.min.js"></script><script src="/vendor/smooth-scroll/dist/smooth-scroll.polyfills.min.js"></script><!-- Main theme script--><script src="/js/theme.min.js"></script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/
|
|
777
|
+
});</script><!-- Back to top button--><a class="btn-scroll-top" href="#top" data-scroll data-fixed-element><span class="btn-scroll-top-tooltip text-muted fs-sm me-2">Top</span><i class="btn-scroll-top-icon ai-arrow-up"> </i></a><!-- Vendor scrits: js libraries and plugins--><script src="/vendor/bootstrap/dist/js/bootstrap.bundle.min.js"></script><script src="/vendor/simplebar/dist/simplebar.min.js"></script><script src="/vendor/smooth-scroll/dist/smooth-scroll.polyfills.min.js"></script><!-- Main theme script--><script src="/js/theme.min.js"></script><script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"0e3ccdaf832b48f5a3585d27a3a6e921","r":1,"server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
|
|
778
778
|
</body></html>
|
|
@@ -156,9 +156,9 @@
|
|
|
156
156
|
<td>62nd</td>
|
|
157
157
|
|
|
158
158
|
|
|
159
|
-
<td>
|
|
159
|
+
<td>554th</td>
|
|
160
160
|
|
|
161
|
-
<td>
|
|
161
|
+
<td>352</td>
|
|
162
162
|
</tr>
|
|
163
163
|
</tbody>
|
|
164
164
|
</table>
|
|
@@ -199,9 +199,9 @@
|
|
|
199
199
|
<td>62nd</td>
|
|
200
200
|
|
|
201
201
|
|
|
202
|
-
<td>
|
|
202
|
+
<td>554th</td>
|
|
203
203
|
|
|
204
|
-
<td>
|
|
204
|
+
<td>352</td>
|
|
205
205
|
</tr>
|
|
206
206
|
</tbody>
|
|
207
207
|
</table>
|
|
@@ -295,9 +295,9 @@
|
|
|
295
295
|
|
|
296
296
|
<td>78</td>
|
|
297
297
|
|
|
298
|
-
<td>
|
|
298
|
+
<td>238</td>
|
|
299
299
|
|
|
300
|
-
<td>
|
|
300
|
+
<td>352</td>
|
|
301
301
|
|
|
302
302
|
</tr>
|
|
303
303
|
|
|
@@ -309,10 +309,10 @@
|
|
|
309
309
|
|
|
310
310
|
<td>1</td>
|
|
311
311
|
|
|
312
|
-
<td>24</td>
|
|
313
|
-
|
|
314
312
|
<td>26</td>
|
|
315
313
|
|
|
314
|
+
<td>28</td>
|
|
315
|
+
|
|
316
316
|
</tr>
|
|
317
317
|
|
|
318
318
|
</tbody>
|
|
@@ -361,14 +361,25 @@
|
|
|
361
361
|
</thead>
|
|
362
362
|
<tbody>
|
|
363
363
|
|
|
364
|
+
<tr>
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
<td>Other</td>
|
|
368
|
+
<td>2 - 1 - 0</td>
|
|
369
|
+
<td>66.7%</td>
|
|
370
|
+
<td>66.7%</td>
|
|
371
|
+
<td>0.0%</td>
|
|
372
|
+
|
|
373
|
+
</tr>
|
|
374
|
+
|
|
364
375
|
<tr>
|
|
365
376
|
|
|
366
377
|
|
|
367
378
|
<td>Standard</td>
|
|
368
|
-
<td>
|
|
369
|
-
<td>50.
|
|
370
|
-
<td>51.
|
|
371
|
-
<td>4.
|
|
379
|
+
<td>34 - 32 - 3</td>
|
|
380
|
+
<td>50.7%</td>
|
|
381
|
+
<td>51.5%</td>
|
|
382
|
+
<td>4.3%</td>
|
|
372
383
|
|
|
373
384
|
</tr>
|
|
374
385
|
|
|
@@ -398,10 +409,10 @@
|
|
|
398
409
|
|
|
399
410
|
|
|
400
411
|
<td><b>Overall</b></td>
|
|
401
|
-
<td><b>
|
|
402
|
-
<td><b>
|
|
403
|
-
<td><b>52.
|
|
404
|
-
<td><b>4.
|
|
412
|
+
<td><b>56 - 50 - 5</b></td>
|
|
413
|
+
<td><b>52.0%</b></td>
|
|
414
|
+
<td><b>52.8%</b></td>
|
|
415
|
+
<td><b>4.5%</b></td>
|
|
405
416
|
|
|
406
417
|
</tr>
|
|
407
418
|
|
|
@@ -435,6 +446,76 @@
|
|
|
435
446
|
</thead>
|
|
436
447
|
<tbody>
|
|
437
448
|
|
|
449
|
+
<tr>
|
|
450
|
+
<td>3rd</td>
|
|
451
|
+
<td>
|
|
452
|
+
<div class="d-flex flex-column-reverse flex-lg-row">
|
|
453
|
+
<div style="min-width: 150px;" >Fri, 27.02.2026</div>
|
|
454
|
+
<a href="/events/30770/">TMNT Prerelease</a>
|
|
455
|
+
</div>
|
|
456
|
+
</td>
|
|
457
|
+
<td>
|
|
458
|
+
<span data-bs-toggle="tooltip"
|
|
459
|
+
data-bs-placement="left"
|
|
460
|
+
data-bs-html="true"
|
|
461
|
+
data-bs-title="
|
|
462
|
+
<ul>
|
|
463
|
+
<li>Match points: 6</li>
|
|
464
|
+
<li>Participation: 3</li>
|
|
465
|
+
</ul>
|
|
466
|
+
<span>Multiplied by 1x: 9 total</span>
|
|
467
|
+
">
|
|
468
|
+
9
|
|
469
|
+
</span>
|
|
470
|
+
</td>
|
|
471
|
+
<td class="text-nowrap">2 - 1 - 0</td>
|
|
472
|
+
<td>
|
|
473
|
+
<div class="d-flex flex-column flex-lg-row">
|
|
474
|
+
<div style="min-width: 150px;">
|
|
475
|
+
|
|
476
|
+
<img src="/static/types/text_icons/regular.svg" alt="Regular" style="height: 24px;" title="Regular" itemprop="image">
|
|
477
|
+
|
|
478
|
+
</div>
|
|
479
|
+
<div>Other</div>
|
|
480
|
+
</div>
|
|
481
|
+
</td>
|
|
482
|
+
</tr>
|
|
483
|
+
|
|
484
|
+
<tr>
|
|
485
|
+
<td>6th</td>
|
|
486
|
+
<td>
|
|
487
|
+
<div class="d-flex flex-column-reverse flex-lg-row">
|
|
488
|
+
<div style="min-width: 150px;" >Mon, 23.02.2026</div>
|
|
489
|
+
<a href="/events/21170/">Standard @ Mulligan</a>
|
|
490
|
+
</div>
|
|
491
|
+
</td>
|
|
492
|
+
<td>
|
|
493
|
+
<span data-bs-toggle="tooltip"
|
|
494
|
+
data-bs-placement="left"
|
|
495
|
+
data-bs-html="true"
|
|
496
|
+
data-bs-title="
|
|
497
|
+
<ul>
|
|
498
|
+
<li>Match points: 6</li>
|
|
499
|
+
<li>Participation: 3</li>
|
|
500
|
+
</ul>
|
|
501
|
+
<span>Multiplied by 1x: 9 total</span>
|
|
502
|
+
">
|
|
503
|
+
9
|
|
504
|
+
</span>
|
|
505
|
+
</td>
|
|
506
|
+
<td class="text-nowrap">2 - 2 - 0</td>
|
|
507
|
+
<td>
|
|
508
|
+
<div class="d-flex flex-column flex-lg-row">
|
|
509
|
+
<div style="min-width: 150px;">
|
|
510
|
+
|
|
511
|
+
<img src="/static/types/text_icons/regular.svg" alt="Regular" style="height: 24px;" title="Regular" itemprop="image">
|
|
512
|
+
|
|
513
|
+
</div>
|
|
514
|
+
<div>Standard</div>
|
|
515
|
+
</div>
|
|
516
|
+
</td>
|
|
517
|
+
</tr>
|
|
518
|
+
|
|
438
519
|
<tr>
|
|
439
520
|
<td>6th</td>
|
|
440
521
|
<td>
|