Compare commits

131 Commits
Author SHA1 Message Date
zephyr 55aa03aa41 umadump/replay: start of race replay json decoding 2026-09-20 11:44:09 -04:00
zephyr 0ffd2c099a horse, mdb: include id in lobby conversations
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-09-17 12:59:28 -04:00
zephyr 6828b1bd88 horse, mdb: put skill groups in skills
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #13.
2026-09-15 11:00:10 -04:00
zephyr 78aee43e5f zenno: format
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
why the h*ck does vscode not format my .ts files on save even though i
have it configured to always format on save!!!!!!
2026-09-14 17:21:51 -04:00
zephyr 745c9d01dd zenno/doc/frbm: delete jbc sprint
Fixes #46.
2026-09-14 17:20:40 -04:00
zephyr e00fe0965a zenno/doc/mdb: emphasize that support card event outcomes are not in the mdb
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-09-14 17:07:25 -04:00
zephyr caa19dd85a zenno/doc/mdb: document races
ci/woodpecker/push/horsebot Pipeline failed
ci/woodpecker/push/zenno Pipeline failed
2026-09-11 18:14:14 -04:00
zephyr 3bf17944b3 horse, mdb, cmd/horsebot: racecourses
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-09-08 15:56:01 -04:00
zephyr 30f89e86f0 doc: add a recent dump 2026-09-08 15:56:01 -04:00
zephyr 8850dd4a08 zenno/doc/mdb: document skills
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-09-07 16:12:32 -04:00
zephyr 8946091b93 zenno: add ability type for all stats up 2026-09-07 16:08:52 -04:00
zephyr 9e3e06f0a0 zenno: rename missed Greate Escape -> Runaway 2026-09-07 12:28:49 -04:00
zephyr 12fea4c37e zenno/doc/tagged-skills: tag 403 is lane movement too 2026-09-06 22:08:37 -04:00
zephyr ad02e0711d zenno/chara/convo: include character icons
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-09-06 14:21:09 -04:00
zephyr 869235a8c2 zenno/chara/convo: use condition_type
Fixes #8.
2026-09-06 11:56:50 -04:00
zephyr 15f6d2c59a zenno/doc/frbm: update for GL
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-09-04 21:47:32 -04:00
zephyr d0c11aa527 zenno: section speed does not use base wit
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Per analysis by Aya, only final wit is used for section speed.

Fixes #40.
2026-09-03 15:30:29 -04:00
zephyr c7a847f677 zenno/race/stam: add disclaimers
Also minor adjustments to chart size and how effective HP is calculated.
2026-09-03 15:10:47 -04:00
zephyr 0791fdd3d4 zenno: stamina calculator first pass
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-09-03 06:51:47 -04:00
zephyr e5f18d3c78 zenno/race/stam: remove the hard parts for now 2026-08-30 16:08:58 -04:00
zephyr 0d3cf24714 zenno: rebase stamina calculator & format 2026-08-30 15:45:42 -04:00
zephyr a8ed0dbbe0 zenno/race/stam: start showing outputs 2026-08-30 15:45:42 -04:00
zephyr 84f4f8e358 zenno/race/stam: beginning of stamina calculator 2026-08-30 15:45:42 -04:00
zephyr 7085fea1b7 umadump/replay: implement race sim decoding
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-08-30 01:56:43 -04:00
zephyr 1f195024e1 umadump/ism: idle single mode model 2026-08-26 21:08:46 -04:00
zephyr a91980e603 doc: mention race_course_set
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-08-26 20:29:14 -04:00
zephyr 8de957b59b zenno: allow both stats in threshold modifier to be null
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-08-26 18:57:31 -04:00
zephyr 206fee797c zenno/race/carryover: stat threshold modifier 2026-08-26 18:54:25 -04:00
zephyr 6ef2a190cd zenno: format
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-08-26 18:22:03 -04:00
zephyr 9a7028a44f zenno/race/carryover: add tables and disclaimers
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-26 18:01:10 -04:00
zephyr a7218c68ed zenno/race/carryover: calculator for late race carrover and accel
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-26 17:46:14 -04:00
zephyr 1f31ef223d zenno/racelib: allow accel skills to be delayed 2026-08-26 17:12:56 -04:00
zephyr 444fea85f0 zenno: lint fixes
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-08-21 15:45:53 -04:00
zephyr e92ce64b17 zenno: fix aptitude level type for umas
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-21 15:34:39 -04:00
zephyr 8d2a0e6c0d zenno/doc/mdb: include succession_initial_factor 2026-08-21 15:31:22 -04:00
zephyr 6b8b494739 zenno/doc/mdb: divide support card docs into sections 2026-08-21 15:12:42 -04:00
zephyr d8d9ec6543 zenno/doc/mdb: document sparks 2026-08-21 15:02:57 -04:00
zephyr cb48e238a8 zenno: account for ism data with no start stats
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-19 16:30:49 -04:00
zephyr 2bf229b5da zenno/career/ismdata: start visualization
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-19 16:10:54 -04:00
zephyr bde080eadd zenno: add support card level and effect functonality
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-13 17:39:23 -04:00
zephyr 1fe397ca81 zenno/career/ismdata: start of auto career analysis
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-07 17:01:33 -04:00
zephyr 5a13519189 zenno: scenario data 2026-08-05 16:00:59 -04:00
zephyr 9f4574e176 cmd/horsebot: also download support type icons 2026-08-04 17:14:57 -04:00
zephyr eaee64dca4 cmd/horsebot: download support card icons
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-08-02 23:36:32 -04:00
zephyr a232f78ac7 zenno: support card type definitions 2026-08-02 23:27:43 -04:00
zephyr 061fe89b7f remove vestiges of an ancient past 2026-08-02 22:48:02 -04:00
zephyr c0ddc32997 horse, mdb, cmd/horsebot: support cards
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #37.
2026-08-02 22:45:34 -04:00
zephyr 9521b5e7c5 horse: go generate 2026-08-02 02:37:24 -04:00
zephyr efcdf5d525 zenno/doc/mdb: document support card hints 2026-08-02 02:37:10 -04:00
zephyr 8faf5cadc7 horse: improve single target ahead/behind skills wording
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #28.
2026-07-31 22:33:59 -04:00
zephyr 656e155625 zenno: improve single target ahead/behind skills wording
For #28.
2026-07-31 22:30:44 -04:00
zephyr ff07b90c73 horse, zenno: fans ability value scaling
Fixes #30.
2026-07-31 22:27:52 -04:00
zephyr d265c81735 horse: add 564 ability type
While we're here adding the formatting, also adjust DD's wording and fix
the units on lane change speed skills.

Fixes #25.
2026-07-31 22:24:03 -04:00
zephyr 998156d345 zenno: gl skills are tag 803
Fixes #32.
2026-07-31 22:14:25 -04:00
zephyr aaa7c6d5b5 zenno/doc/mdb: start the mdb doc
For #12.
2026-07-31 22:12:38 -04:00
zephyr 48118efeeb doc: document grand live mechanics
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-28 00:19:14 -04:00
zephyr 79d4e76090 mdb: sort scenarios by sort id
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #33.
2026-07-25 11:57:24 -04:00
zephyr ea39be0510 zenno: include character icons in character picks
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-24 23:09:24 -04:00
zephyr 7bac55ca43 zenno: show icons on skills 2026-07-24 22:56:31 -04:00
zephyr 435da61405 cmd: move toradl into horsebot
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #31.
2026-07-24 17:18:44 -04:00
zephyr f3e7c7b43b all: update deps
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-23 22:55:17 -04:00
zephyr eded415df4 cmd/toradl: program for downloading icons from gametora 2026-07-23 22:48:12 -04:00
zephyr 34029fe001 zenno/doc/tagged-skills: more skill info
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-21 17:01:23 -04:00
zephyr ffb700545f zenno/doc/tagged-skills: new page
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-19 22:29:15 -04:00
zephyr 70ad09a13e zenno/chara/convo: list characters in convos even when they don't have their own
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
Fixes #24.
2026-07-19 15:46:41 -04:00
zephyr 74c22c7313 zenno: rename Great Escape -> Runaway everywhere
Fixes #26.
2026-07-19 15:38:01 -04:00
zephyr 2c1b4b9261 zenno/doc/race: lint fix
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-18 16:58:20 -04:00
zephyr e5128b6783 zenno/race/spurt: add dueling info 2026-07-18 16:58:12 -04:00
zephyr b22c8307fd zenno/race: common component for calculator outputs 2026-07-18 16:38:07 -04:00
zephyr cb54bbe414 zenno/doc/frbm: add doccy references to some sections
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-07-13 18:59:52 -04:00
zephyr 096cff28b6 zenno/doc/frbm: change of cm16 plans 2026-07-13 18:45:51 -04:00
zephyr 197df8f022 zenno/doc/race: add reference links to doccy 2026-07-13 18:41:18 -04:00
zephyr 009dd1d695 zenno: add page titles and descriptions
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-12 14:37:43 -04:00
zephyr bdafc93315 zenno: lint fix
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline was successful
2026-07-10 20:01:20 -04:00
zephyr ef5b06d66e zenno: pull vite config from stam calc branch
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
ci/woodpecker/manual/horsebot Pipeline was successful
ci/woodpecker/manual/zenno Pipeline failed
2026-07-10 17:34:02 -04:00
zephyr 65b81612bc ci: allow running manually
ci/woodpecker/push/horsebot Pipeline was successful
ci/woodpecker/push/zenno Pipeline failed
2026-07-10 17:29:35 -04:00
zephyr 6269665e79 ci: always run zenno workflow 2026-07-10 16:20:02 -04:00
zephyr cae7d5b8f4 zenno: format 2026-07-10 15:37:29 -04:00
zephyr fca43e64b5 zenno/doc/spark: make spark select searchable 2026-07-09 15:40:07 -04:00
zephyr bc395a0788 zenno: refactor CharaPick to generic component 2026-07-09 14:54:03 -04:00
zephyr 1d879cbf9f zenno/race/gate: add velocity/time chart 2026-07-07 20:47:20 -04:00
zephyr 240a3d9a73 zenno/doc/spark: decribe & clarify 2026-07-07 16:23:15 -04:00
zephyr 3d73460934 zenno: link up doc/spark 2026-07-07 15:55:31 -04:00
zephyr 0c518a9ce2 zenno/doc/spark: spark explorer 2026-07-07 15:51:28 -04:00
zephyr 5cbb6d7b1d zenno/doc/frbm: updates for 7-1 patch 2026-07-07 11:16:09 -04:00
zephyr b0bd16fd04 zenno/index: move discord bot to its own section 2026-07-06 09:45:07 -04:00
zephyr 55175c9c40 zenno: format & lint 2026-07-06 09:41:11 -04:00
zephyr 06e5a06680 zenno/race/gate: caveats 2026-07-06 09:39:36 -04:00
zephyr dbb0dcd2dc zenno: link up race/gate 2026-07-06 09:23:37 -04:00
zephyr 02f723b83a zenno/race/gate: new calculator 2026-07-06 09:01:11 -04:00
zephyr 1f58dec491 zenno/doc/race: conserve power 2026-07-01 23:39:31 -04:00
zephyr a6d264c79d zenno: pull race mechanics lib update from stam-calc 2026-07-01 22:40:11 -04:00
zephyr d62e729052 zenno: update stat charts for new limits 2026-07-01 22:12:10 -04:00
zephyr 9ce665865e zenno/doc/race: fix 4 skill activation chance chart 2026-06-26 13:13:30 -04:00
zephyr 7d395b2cc7 ci: set up
ci/woodpecker/push/horsebot Pipeline was successful
2026-06-17 10:50:04 -04:00
zephyr 2b69211a6c horse: update deps 2026-06-17 09:58:02 -04:00
zephyr 67377c4690 zenno: format 2026-06-16 14:20:03 -04:00
zephyr 1d65a0ec14 zenno/doc/race: add missing chart controls
Fixes #21.
2026-06-16 13:40:16 -04:00
zephyr ad58edbfe1 zenno: make character selects searchable
Fixes #20.
2026-06-16 13:37:59 -04:00
zephyr f8e7bfbec6 zenno/doc/race: skill activation chance is not integer percent 2026-06-14 20:00:27 -04:00
zephyr 2e618b613f zenno/lib/race: constrain poskeep chances to hundredths 2026-06-14 19:05:52 -04:00
zephyr cc2b5fcfcb zenno: make stat chart tooltips attach vertically 2026-06-14 18:59:33 -04:00
zephyr 8ef3936be5 zenno/doc/race: fix mobile 2026-06-14 18:57:43 -04:00
zephyr b06e4b537b zenno: link up doc/race
Fixes #16.
2026-06-14 17:55:21 -04:00
zephyr 7b4cd41d3b zenno/doc/frbm: remove stat summaries
For #16.
2026-06-14 17:45:29 -04:00
zephyr 2c9434729a zenno/doc/race: interactive graphs for race mechanics
For #16.
2026-06-14 17:36:00 -04:00
zephyr 7f02925ff7 horse: define rushed chance mod and current speed up ability types
Fixes #17.
2026-06-14 12:04:07 -04:00
zephyr b217691c8a zenno/doc/lanecalc: lint fixes 2026-06-14 10:45:39 -04:00
zephyr 4bce196c09 zenno/doc/frbm: effects on other styles in cm comps
Fixes #18.
2026-06-14 10:34:34 -04:00
zephyr aa17d8ccf3 zenno: beg
Fixes #15.
2026-06-13 22:59:49 -04:00
zephyr 26a5ca4496 zenno/doc/lanecalc: typo 2026-06-13 22:12:59 -04:00
zephyr 51f942ee18 zenno: mention doc/lanecalc as appropriate
Fixes #14.
2026-06-13 22:09:09 -04:00
zephyr 2c773391f0 zenno: link up doc/lanecalc 2026-06-13 22:04:49 -04:00
zephyr c66d969c82 zenno/doc/lanecalc: english manual for lanecalc
For #14.
2026-06-13 22:02:16 -04:00
zephyr bc9d722ee0 zenno/doc/frbm: cm14 results and cm15 plans 2026-06-13 13:20:54 -04:00
zephyr 6482f11620 zenno/doc/frbm: rename chariot -> rabbit
jern on the Hakuraku discord informs me that chariot is a different
style of build.

Fixes #19.
2026-06-13 12:35:07 -04:00
zephyr 75024c7c11 zenno: categorize tools 2026-06-10 14:03:42 -04:00
zephyr dc78d51def zenno: link up affinity tool 2026-06-08 16:45:12 -04:00
zephyr 5f0ad1b0e0 zenno/affinity: new tool 2026-06-08 16:42:04 -04:00
zephyr 6db0ca5230 mdb, cmd/horsebot: affinity details 2026-06-07 15:58:29 -04:00
zephyr 049617c22e zenno/doc/frbm: cm14 round 1 win rates 2026-06-07 15:04:29 -04:00
zephyr d431d3382a global, cmd/horsegen: don't generate json anymore
Everything gets the data from the mdb directly instead now.
2026-06-05 15:13:36 -04:00
zephyr a848c8eb72 zenno: use data from api 2026-06-05 15:13:11 -04:00
zephyr 871fd5fdcc cmd/horsebot: allow acting only as api server 2026-06-05 15:13:11 -04:00
zephyr e3dd37f515 cmd/horsebot: serve data under /api/global 2026-06-05 15:13:11 -04:00
zephyr 3557b32298 cmd/horsebot: serve data from mdb instead of json 2026-06-05 15:13:11 -04:00
zephyr 20db674d25 cmd/horsegen: generate using package mdb 2026-06-05 15:13:11 -04:00
zephyr 2a4da0a73e mdb: don't list carnival bonus sparks to exclude them 2026-06-05 15:13:11 -04:00
zephyr e6335c1d6e global: generate with deleted lobby location names 2026-06-05 15:13:11 -04:00
zephyr f40fea0ec5 mdb: package for interacting with game's local database 2026-06-05 15:13:10 -04:00
zephyr 96503e40f6 doc: add query to get skill condition types 2026-06-05 15:13:10 -04:00
301 changed files with 237774 additions and 270457 deletions
+12
View File
@@ -0,0 +1,12 @@
when:
- event: push
branch: main
- event: pull_request
- event: manual
steps:
- name: test
image: golang:1.26-alpine
commands:
- go vet ./...
- go test ./...
+15
View File
@@ -0,0 +1,15 @@
when:
- event: push
branch: main
- event: pull_request
- event: manual
steps:
- name: test
image: node:24-alpine
commands:
- cd zenno
- npm ci
- npm run check
- npm run lint
- npm run test
+2 -2
View File
@@ -27,13 +27,13 @@ const (
_AbilityTarget_name_0 = "selfothers with Sympathy"
_AbilityTarget_name_1 = "others in view"
_AbilityTarget_name_2 = "frontmost"
_AbilityTarget_name_3 = "others aheadothers behindall teammates"
_AbilityTarget_name_3 = "aheadbehindall teammates"
_AbilityTarget_name_4 = "using stylerushing others aheadrushing others behindrushing using stylespecific characterwhosoever triggered this skill"
)
var (
_AbilityTarget_index_0 = [...]uint8{0, 4, 24}
_AbilityTarget_index_3 = [...]uint8{0, 12, 25, 38}
_AbilityTarget_index_3 = [...]uint8{0, 5, 11, 24}
_AbilityTarget_index_4 = [...]uint8{0, 11, 31, 52, 71, 89, 119}
)
+15 -7
View File
@@ -20,27 +20,32 @@ func _() {
_ = x[AbilityFrenzy-13]
_ = x[AbilityAddGateDelay-14]
_ = x[AbilityCurrentSpeed-21]
_ = x[AbilityCurrentSpeedUp-22]
_ = x[AbilityTargetSpeed-27]
_ = x[AbilityLaneSpeed-28]
_ = x[AbilityRushedChance-29]
_ = x[AbilityAccel-31]
_ = x[AbilityLaneChange-35]
_ = x[AbilityActivateRare-37]
}
const (
_AbilityType_name_0 = "SpeedStaminaPowerGutsWitEnable Great Escape"
_AbilityType_name_1 = "VisionHPGate delay multiplier"
_AbilityType_name_2 = "FrenzyAdded gate delay"
_AbilityType_name_3 = "Current speed"
_AbilityType_name_4 = "Target speedLane change speed"
_AbilityType_name_3 = "Current speedCurrent speed"
_AbilityType_name_4 = "Target speedLane change speedRushed chance"
_AbilityType_name_5 = "Acceleration"
_AbilityType_name_6 = "Forced lane change"
_AbilityType_name_6 = "Set target lane"
_AbilityType_name_7 = "Activate rare skills"
)
var (
_AbilityType_index_0 = [...]uint8{0, 5, 12, 17, 21, 24, 43}
_AbilityType_index_1 = [...]uint8{0, 6, 8, 29}
_AbilityType_index_2 = [...]uint8{0, 6, 22}
_AbilityType_index_4 = [...]uint8{0, 12, 29}
_AbilityType_index_3 = [...]uint8{0, 13, 26}
_AbilityType_index_4 = [...]uint8{0, 12, 29, 42}
)
func (i AbilityType) String() string {
@@ -54,15 +59,18 @@ func (i AbilityType) String() string {
case 13 <= i && i <= 14:
i -= 13
return _AbilityType_name_2[_AbilityType_index_2[i]:_AbilityType_index_2[i+1]]
case i == 21:
return _AbilityType_name_3
case 27 <= i && i <= 28:
case 21 <= i && i <= 22:
i -= 21
return _AbilityType_name_3[_AbilityType_index_3[i]:_AbilityType_index_3[i+1]]
case 27 <= i && i <= 29:
i -= 27
return _AbilityType_name_4[_AbilityType_index_4[i]:_AbilityType_index_4[i+1]]
case i == 31:
return _AbilityType_name_5
case i == 35:
return _AbilityType_name_6
case i == 37:
return _AbilityType_name_7
default:
return "AbilityType(" + strconv.FormatInt(int64(i), 10) + ")"
}
+7 -6
View File
@@ -18,6 +18,7 @@ func _() {
_ = x[ValueUsageRandom-8]
_ = x[ValueUsageRandom2-9]
_ = x[ValueUsageClimax-10]
_ = x[ValueUsageFans-12]
_ = x[ValueUsageMaxStat-13]
_ = x[ValueUsageGreenCount-14]
_ = x[ValueUsageDistAdd-19]
@@ -29,15 +30,15 @@ func _() {
}
const (
_AbilityValueUsage_name_0 = "directlyscaling with the number of skillsscaling with team Speedscaling with team Staminascaling with team Powerscaling with team Gutsscaling with team Witwith a random 0× to 0.04× multiplierwith a random 0× to 0.04× multiplierscaling with the number of races won in training"
_AbilityValueUsage_name_1 = "scaling with the highest raw statscaling with the number of Passive skills activated"
_AbilityValueUsage_name_0 = "directlyscaling with the number of skillsscaling with team Speedscaling with team Staminascaling with team Powerscaling with team Gutsscaling with team Witwith a random 0× to 0.04× multiplierwith a random 0× to 0.04× multiplierscaling with the number of races won in the career"
_AbilityValueUsage_name_1 = "scaling with the number of fans earned in the careerscaling with the highest raw statscaling with the number of Passive skills activated"
_AbilityValueUsage_name_2 = "plus extra when far from the leadscaling with mid-race phase blocked side time"
_AbilityValueUsage_name_3 = "scaling with overall speedscaling with overall speedscaling with L'Arc global potentialscaling with the longest lead obtained in the first ⅔"
)
var (
_AbilityValueUsage_index_0 = [...]uint16{0, 8, 41, 64, 89, 112, 134, 155, 193, 231, 279}
_AbilityValueUsage_index_1 = [...]uint8{0, 33, 84}
_AbilityValueUsage_index_0 = [...]uint16{0, 8, 41, 64, 89, 112, 134, 155, 193, 231, 281}
_AbilityValueUsage_index_1 = [...]uint8{0, 52, 85, 136}
_AbilityValueUsage_index_2 = [...]uint8{0, 33, 78}
_AbilityValueUsage_index_3 = [...]uint8{0, 26, 52, 87, 142}
)
@@ -47,8 +48,8 @@ func (i AbilityValueUsage) String() string {
case 1 <= i && i <= 10:
i -= 1
return _AbilityValueUsage_name_0[_AbilityValueUsage_index_0[i]:_AbilityValueUsage_index_0[i+1]]
case 13 <= i && i <= 14:
i -= 13
case 12 <= i && i <= 14:
i -= 12
return _AbilityValueUsage_name_1[_AbilityValueUsage_index_1[i]:_AbilityValueUsage_index_1[i+1]]
case 19 <= i && i <= 20:
i -= 19
+14 -6
View File
@@ -11,15 +11,25 @@ func (c Character) String() string {
return c.Name
}
// AffinityRelation holds precomputed affinity values for a pair or trio.
type AffinityRelation struct {
IDA int `json:"chara_a"`
IDB int `json:"chara_b"`
IDC int `json:"chara_c,omitzero"`
Affinity int `json:"affinity"`
IDA CharacterID `json:"chara_a"`
IDB CharacterID `json:"chara_b"`
IDC CharacterID `json:"chara_c,omitzero"`
Affinity int `json:"affinity"`
}
// AffinityDetail holds a single affinity entry.
type AffinityDetail struct {
CharaID CharacterID `json:"chara_id"`
Relation uint16 `json:"relation"`
Affinity uint16 `json:"affinity"`
}
// Conversation describes a lobby conversation.
type Conversation struct {
// ID is the conversation ID.
ID int32 `json:"id"`
// CharacterID is the ID of the character who has the conversation as
// a gallery entry.
CharacterID CharacterID `json:"chara_id"`
@@ -27,8 +37,6 @@ type Conversation struct {
Number int `json:"number"`
// Location is the ID of the location the conversation occurs in the lobby.
Location LobbyConversationLocationID `json:"location"`
// LocationName is the name of the lobby location, for convenience.
LocationName string `json:"location_name"`
// Chara1 is the first conversation participant ID.
// It does not necessarily match CharacterID.
Chara1 CharacterID `json:"chara_1"`
+12 -2
View File
@@ -1,10 +1,20 @@
# horsebot
Discord bot serving horse game data.
Website and Discord bot serving horse game data.
Production instance is named Zenno Rob Roy, because she has read all about Umamusume and is always happy to share her knowledge and give recommendations.
## Running
The `-mdb` flag is mandatory for both website and Discord bot modes.
It provides data for both the horsebot API and the discord bot.
## Running the Website
If the `-public` flag is provided, its value gives the directory to serve at `/`.
The `-img` flag gives a separate directory into which images are synced from GameTora; obtain permission from Gertas prior to using it.
The images are served on `/img/`.
## Running the Discord Bot
Provide the `-token` flag pointing to a file containing the token.
The bot always uses the Gateway API.
If the `-http` argument is provided, it will also use the HTTP API, and `-key` must also be provided.
+123 -79
View File
@@ -13,7 +13,7 @@ import (
"net/http"
"os"
"os/signal"
"path/filepath"
"strconv"
"time"
"github.com/disgoorg/disgo"
@@ -24,16 +24,19 @@ import (
"github.com/disgoorg/disgo/httpserver"
"github.com/disgoorg/disgo/rest"
httpmiddle "github.com/go-chi/chi/v5/middleware"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
"git.sunturtle.xyz/zephyr/horse"
"git.sunturtle.xyz/zephyr/horse/mdb"
)
func main() {
var (
// public site
addr string
dataDir string
public string
addr string
mdbf string
public string
img string
// discord
tokenFile string
apiRoute string
@@ -42,9 +45,10 @@ func main() {
level slog.Level
textfmt string
)
flag.StringVar(&addr, "http", ":80", "`address` to bind HTTP server")
flag.StringVar(&dataDir, "data", "", "`dir`ectory containing exported json data")
flag.StringVar(&addr, "http", ":13669", "`address` to bind HTTP server")
flag.StringVar(&mdbf, "mdb", "", "`path` to master.mdb")
flag.StringVar(&public, "public", "", "`dir`ectory containing the website to serve")
flag.StringVar(&img, "img", "", "`dir`ectory to save and serve images")
flag.StringVar(&tokenFile, "token", "", "`file` containing the Discord bot token")
flag.StringVar(&apiRoute, "route", "/interactions/callback", "`path` to serve Discord HTTP API calls")
flag.StringVar(&pubkey, "key", "", "Discord public key")
@@ -64,56 +68,95 @@ func main() {
}
slog.SetDefault(slog.New(lh))
stat, err := os.Stat(public)
if err != nil {
slog.Error("public", slog.Any("err", err))
os.Exit(1)
if public != "" {
stat, err := os.Stat(public)
if err != nil {
slog.Error("public", slog.Any("err", err))
os.Exit(1)
}
if !stat.IsDir() {
slog.Error("public", slog.String("err", "not a directory"))
os.Exit(1)
}
}
if !stat.IsDir() {
slog.Error("public", slog.String("err", "not a directory"))
os.Exit(1)
}
skills, err := loadSkills(filepath.Join(dataDir, "skill.json"))
slog.Info("loaded skills", slog.Int("count", len(skills)))
groups, err2 := loadSkillGroups(filepath.Join(dataDir, "skill-group.json"))
slog.Info("loaded skill groups", slog.Int("count", len(groups)))
if err = errors.Join(err, err2); err != nil {
slog.Error("loading data", slog.Any("err", err))
os.Exit(1)
}
skillSrv := newSkillServer(skills, groups)
slog.Info("skill server ready")
token, err := os.ReadFile(tokenFile)
if err != nil {
slog.Error("reading token", slog.Any("err", err))
os.Exit(1)
}
token = bytes.TrimSuffix(token, []byte{'\n'})
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
r := handler.New()
r.DefaultContext(func() context.Context { return ctx })
r.Use(middleware.Go)
r.Use(logMiddleware)
r.Route("/skill", func(r handler.Router) {
r.SlashCommand("/", skillSrv.slash)
r.Autocomplete("/", skillSrv.autocomplete)
r.SelectMenuComponent("/swap", skillSrv.menu)
r.ButtonComponent("/swap/{id}", skillSrv.button)
})
slog.Info("connect", slog.String("disgo", disgo.Version))
client, err := disgo.New(string(token), bot.WithDefaultGateway(), bot.WithEventListeners(r))
db, err := sqlitex.NewPool(mdbf, sqlitex.PoolOptions{Flags: sqlite.OpenReadOnly})
if err != nil {
slog.Error("building bot", slog.Any("err", err))
slog.Error("mdb", slog.Any("err", err))
os.Exit(1)
}
if img != "" {
// Ensure the img directory is in fact a directory
// before we start trying to fill it out.
err := os.MkdirAll(img, 0777)
if err != nil {
slog.Error("img", slog.Any("err", err))
os.Exit(1)
}
go saveImgs(ctx, db, img)
}
var client *bot.Client
if tokenFile != "" {
skills, err := mdb.Skills(ctx, db)
slog.Info("loaded skills", slog.Int("count", len(skills)))
groups, err2 := mdb.SkillGroups(ctx, db)
slog.Info("loaded skill groups", slog.Int("count", len(groups)))
if err = errors.Join(err, err2); err != nil {
slog.Error("loading data", slog.Any("err", err))
os.Exit(1)
}
skillSrv := newSkillServer(skills, groups)
slog.Info("skill server ready")
r := handler.New()
r.DefaultContext(func() context.Context { return ctx })
r.Use(middleware.Go)
r.Use(logMiddleware)
r.Route("/skill", func(r handler.Router) {
r.SlashCommand("/", skillSrv.slash)
r.Autocomplete("/", skillSrv.autocomplete)
r.SelectMenuComponent("/swap", skillSrv.menu)
r.ButtonComponent("/swap/{id}", skillSrv.button)
})
slog.Info("connect", slog.String("disgo", disgo.Version))
token, err := os.ReadFile(tokenFile)
if err != nil {
slog.Error("reading token", slog.Any("err", err))
os.Exit(1)
}
token = bytes.TrimSuffix(token, []byte{'\n'})
client, err = disgo.New(string(token), bot.WithDefaultGateway(), bot.WithEventListeners(r))
if err != nil {
slog.Error("building bot", slog.Any("err", err))
os.Exit(1)
}
}
mux := http.NewServeMux()
mux.Handle("GET /", httpmiddle.Compress(5)(http.FileServerFS(os.DirFS(public))))
mux.Handle("GET /api/data/", httpmiddle.Compress(5)(http.StripPrefix("/api/data", http.FileServerFS(os.DirFS(dataDir)))))
if public != "" {
mux.Handle("GET /", httpmiddle.Compress(5)(http.FileServerFS(os.DirFS(public))))
}
if img != "" {
mux.Handle("GET /img/", http.StripPrefix("/img", http.FileServerFS(os.DirFS(img))))
}
mux.Handle("GET /api/global/affinity", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.AffinitySummary)))
mux.Handle("GET /api/global/affinity-detail", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.AffinityDetail)))
mux.Handle("GET /api/global/character", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Characters)))
mux.Handle("GET /api/global/conversation", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Conversations)))
mux.Handle("GET /api/global/race", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Races)))
mux.Handle("GET /api/global/racecourse", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Racecourses)))
mux.Handle("GET /api/global/saddle", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Saddles)))
mux.Handle("GET /api/global/scenario", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Scenarios)))
mux.Handle("GET /api/global/skill", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Skills)))
mux.Handle("GET /api/global/skill-group", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.SkillGroups)))
mux.Handle("GET /api/global/spark", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Sparks)))
mux.Handle("GET /api/global/support", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.SupportCards)))
mux.Handle("GET /api/global/uma", httpmiddle.Compress(5)(dataroute(ctx, db, mdb.Umas)))
if pubkey != "" {
pk, err := hex.DecodeString(pubkey)
if err != nil {
@@ -130,7 +173,7 @@ func main() {
}
srv := http.Server{
Addr: addr,
Handler: mux,
Handler: httpmiddle.Logger(mux),
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
BaseContext: func(l net.Listener) context.Context { return ctx },
@@ -144,23 +187,28 @@ func main() {
slog.Error("HTTP server closed", slog.Any("err", err))
}()
if err := handler.SyncCommands(client, commands, nil, rest.WithCtx(ctx)); err != nil {
slog.Error("syncing commands", slog.Any("err", err))
os.Exit(1)
if client != nil {
if err := handler.SyncCommands(client, commands, nil, rest.WithCtx(ctx)); err != nil {
slog.Error("syncing commands", slog.Any("err", err))
os.Exit(1)
}
slog.Info("start gateway")
if err := client.OpenGateway(ctx); err != nil {
slog.Error("starting gateway", slog.Any("err", err))
stop()
}
}
slog.Info("start gateway")
if err := client.OpenGateway(ctx); err != nil {
slog.Error("starting gateway", slog.Any("err", err))
stop()
}
slog.Info("ready")
<-ctx.Done()
stop()
ctx, stop = context.WithTimeout(context.Background(), 5*time.Second)
defer stop()
client.Close(ctx)
if client != nil {
client.Close(ctx)
}
if err := srv.Shutdown(ctx); err != nil {
slog.Error("HTTP API shutdown", slog.Any("err", err))
os.Exit(1)
@@ -186,26 +234,22 @@ var commands = []discord.ApplicationCommandCreate{
},
}
func loadSkills(file string) ([]horse.Skill, error) {
b, err := os.ReadFile(file)
if err != nil {
return nil, err
func dataroute[T any](ctx context.Context, db *sqlitex.Pool, f func(context.Context, *sqlitex.Pool) ([]T, error)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
data, err := f(ctx, db)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
b, err := json.Marshal(data)
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(b)))
if _, err := w.Write(b); err != nil {
slog.Error("writing response", slog.Any("err", err))
return
}
}
var skills []horse.Skill
if err := json.Unmarshal(b, &skills); err != nil {
return nil, err
}
return skills, nil
}
func loadSkillGroups(file string) ([]horse.SkillGroup, error) {
b, err := os.ReadFile(file)
if err != nil {
return nil, err
}
var groups []horse.SkillGroup
if err := json.Unmarshal(b, &groups); err != nil {
return nil, err
}
return groups, nil
}
+185
View File
@@ -0,0 +1,185 @@
package main
import (
"context"
"errors"
"fmt"
"image"
"image/png"
"log/slog"
"net/http"
"os"
"path/filepath"
"strconv"
"time"
"github.com/gen2brain/avif"
"golang.org/x/image/draw"
"golang.org/x/sync/errgroup"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
)
func saveImgs(ctx context.Context, db *sqlitex.Pool, out string) {
skill, err := skillIconIDs(ctx, db)
if err != nil {
slog.Error("skills", slog.Any("err", err))
}
chara, err := charaIDs(ctx, db)
if err != nil {
slog.Error("characters", slog.Any("err", err))
}
rank, err := rankIDs(ctx, db)
if err != nil {
slog.Error("ranks", slog.Any("err", err))
}
supps, err := suppIDs(ctx, db)
if err != nil {
slog.Error("supports", slog.Any("err", err))
}
g, ctx := errgroup.WithContext(ctx)
tick := time.NewTicker(250 * time.Millisecond)
idouts(ctx, g, tick, skill, filepath.Join(out, "skill"), "https://media.gametora.com/umamusume/skills/icon/%d.png", image.Pt(64, 64), image.Pt(32, 32), image.Pt(16, 16))
idouts(ctx, g, tick, chara, filepath.Join(out, "chara"), "https://gametora.com/images/umamusume/characters/icons/chr_icon_%d.png", image.Pt(256, 256), image.Pt(64, 64), image.Pt(32, 32), image.Pt(16, 16))
idouts(ctx, g, tick, rank, filepath.Join(out, "rank"), "https://media.gametora.com/umamusume/ui/rank/%02d.png", image.Pt(128, 128), image.Pt(64, 64), image.Pt(32, 32), image.Pt(16, 16))
idouts(ctx, g, tick, rank, filepath.Join(out, "rank", "simple"), "https://media.gametora.com/umamusume/ui/rank/simple/%02d.png", image.Pt(50, 50), image.Pt(32, 32), image.Pt(16, 16))
idouts(ctx, g, tick, supps, filepath.Join(out, "support"), "https://gametora.com/images/umamusume/supports/support_card_s_%d.png", image.Pt(128, 128), image.Pt(64, 64), image.Pt(32, 32))
idouts(ctx, g, tick, []int32{0, 1, 2, 3, 4, 5, 6}, filepath.Join(out, "support", "type"), "https://gametora.com/images/umamusume/icons/utx_ico_obtain_%02d.png", image.Pt(70, 70), image.Pt(35, 35), image.Pt(16, 16))
if err := g.Wait(); err != nil {
slog.Error("output", slog.Any("err", err))
}
}
// load scans all results of sql and appends them to r.
func load[T any](ctx context.Context, db *sqlitex.Pool, r []T, sql string, row func(*sqlite.Stmt) T) ([]T, error) {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return nil, err
}
stmt, err := conn.Prepare(sql)
if err != nil {
return nil, err
}
for {
ok, err := stmt.Step()
if err != nil {
return r, err
}
if !ok {
break
}
r = append(r, row(stmt))
}
return r, err
}
func skillIconIDs(ctx context.Context, db *sqlitex.Pool) ([]int32, error) {
return load(ctx, db, nil, "SELECT DISTINCT icon_id FROM skill_data", func(s *sqlite.Stmt) int32 {
return s.ColumnInt32(0)
})
}
func charaIDs(ctx context.Context, db *sqlitex.Pool) ([]int32, error) {
return load(ctx, db, nil, "SELECT id FROM chara_data", func(s *sqlite.Stmt) int32 {
return s.ColumnInt32(0)
})
}
func rankIDs(ctx context.Context, db *sqlitex.Pool) ([]int32, error) {
return load(ctx, db, nil, "SELECT id-1 FROM single_mode_rank", func(s *sqlite.Stmt) int32 {
return s.ColumnInt32(0)
})
}
func suppIDs(ctx context.Context, db *sqlitex.Pool) ([]int32, error) {
return load(ctx, db, nil, "SELECT id FROM support_card_data", func(s *sqlite.Stmt) int32 {
return s.ColumnInt32(0)
})
}
var pngenc = &png.Encoder{CompressionLevel: png.BestCompression}
func idouts(ctx context.Context, g *errgroup.Group, tick *time.Ticker, ids []int32, p, urlf string, sizes ...image.Point) {
for _, id := range ids {
g.Go(func() error {
n := strconv.Itoa(int(id))
p := filepath.Join(p, n)
_, err := os.Stat(p)
if !errors.Is(err, os.ErrNotExist) {
slog.DebugContext(ctx, "exists", slog.String("path", p))
return nil
}
if err := os.MkdirAll(p, 0777); err != nil {
return err
}
url := fmt.Sprintf(urlf, id)
select {
case <-ctx.Done():
return ctx.Err()
case <-tick.C: // continue on
}
img, err := dlimg(ctx, url)
if err != nil {
return err
}
slog.InfoContext(ctx, "resize", slog.String("url", url))
rs := resize(img, sizes...)
for _, r := range rs {
g.Go(func() error {
m := r.Bounds().Max
o := filepath.Join(p, fmt.Sprintf("%dx%d.png", m.X, m.Y))
slog.InfoContext(ctx, "write", slog.String("path", o))
f, err := os.Create(o)
if err != nil {
return err
}
defer f.Close()
return pngenc.Encode(f, r)
})
g.Go(func() error {
m := r.Bounds().Max
o := filepath.Join(p, fmt.Sprintf("%dx%d.avif", m.X, m.Y))
slog.InfoContext(ctx, "write", slog.String("path", o))
f, err := os.Create(o)
if err != nil {
return err
}
defer f.Close()
return avif.Encode(f, r)
})
}
return nil
})
}
}
func dlimg(ctx context.Context, url string) (image.Image, error) {
slog.InfoContext(ctx, "download", slog.String("url", url))
ctx, stop := context.WithTimeout(ctx, 5*time.Second)
defer stop()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
slog.InfoContext(ctx, "decode", slog.String("url", url))
img, _, err := image.Decode(resp.Body)
return img, err
}
func resize(img image.Image, sizes ...image.Point) []image.Image {
rs := make([]image.Image, 0, len(sizes))
for _, sz := range sizes {
d := image.NewNRGBA(image.Rectangle{Min: image.Point{}, Max: sz})
draw.CatmullRom.Scale(d, d.Bounds(), img, img.Bounds(), draw.Src, nil)
rs = append(rs, d)
}
return rs
}
-435
View File
@@ -1,435 +0,0 @@
package main
import (
"bufio"
"cmp"
"context"
_ "embed"
"encoding/json"
"errors"
"flag"
"fmt"
"log/slog"
"maps"
"os"
"os/signal"
"path/filepath"
"slices"
"strconv"
"strings"
"golang.org/x/sync/errgroup"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
"git.sunturtle.xyz/zephyr/horse"
)
func main() {
var (
mdb string
out string
region string
)
flag.StringVar(&mdb, "mdb", os.ExpandEnv(`$USERPROFILE\AppData\LocalLow\Cygames\Umamusume\master\master.mdb`), "`path` to Umamusume master.mdb")
flag.StringVar(&out, "o", `.`, "`dir`ectory for output files")
flag.StringVar(&region, "region", "global", "region the database is for (global, jp)")
flag.Parse()
slog.Info("open", slog.String("mdb", mdb))
db, err := sqlitex.NewPool(mdb, sqlitex.PoolOptions{Flags: sqlite.OpenReadOnly})
if err != nil {
slog.Error("opening mdb", slog.String("mdb", mdb), slog.Any("err", err))
os.Exit(1)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
go func() {
<-ctx.Done()
stop()
}()
loadgroup, ctx1 := errgroup.WithContext(ctx)
charas := load(ctx1, loadgroup, db, "characters", characterSQL, func(s *sqlite.Stmt) horse.Character {
return horse.Character{
ID: horse.CharacterID(s.ColumnInt(0)),
Name: s.ColumnText(1),
}
})
aff := load(ctx1, loadgroup, db, "pair affinity", affinitySQL, func(s *sqlite.Stmt) horse.AffinityRelation {
return horse.AffinityRelation{
IDA: s.ColumnInt(0),
IDB: s.ColumnInt(1),
IDC: s.ColumnInt(2),
Affinity: s.ColumnInt(3),
}
})
umas := load(ctx1, loadgroup, db, "umas", umaSQL, func(s *sqlite.Stmt) horse.Uma {
return horse.Uma{
ID: horse.UmaID(s.ColumnInt(0)),
CharacterID: horse.CharacterID(s.ColumnInt(1)),
Name: s.ColumnText(2),
Variant: s.ColumnText(3),
Sprint: horse.AptitudeLevel(s.ColumnInt(4)),
Mile: horse.AptitudeLevel(s.ColumnInt(6)),
Medium: horse.AptitudeLevel(s.ColumnInt(7)),
Long: horse.AptitudeLevel(s.ColumnInt(8)),
Front: horse.AptitudeLevel(s.ColumnInt(9)),
Pace: horse.AptitudeLevel(s.ColumnInt(10)),
Late: horse.AptitudeLevel(s.ColumnInt(11)),
End: horse.AptitudeLevel(s.ColumnInt(12)),
Turf: horse.AptitudeLevel(s.ColumnInt(13)),
Dirt: horse.AptitudeLevel(s.ColumnInt(14)),
Unique: horse.SkillID(s.ColumnInt(15)),
Skill1: horse.SkillID(s.ColumnInt(16)),
Skill2: horse.SkillID(s.ColumnInt(17)),
Skill3: horse.SkillID(s.ColumnInt(18)),
SkillPL2: horse.SkillID(s.ColumnInt(19)),
SkillPL3: horse.SkillID(s.ColumnInt(20)),
SkillPL4: horse.SkillID(s.ColumnInt(21)),
SkillPL5: horse.SkillID(s.ColumnInt(22)),
}
})
sg := load(ctx1, loadgroup, db, "skill groups", skillGroupSQL, func(s *sqlite.Stmt) horse.SkillGroup {
return horse.SkillGroup{
ID: horse.SkillGroupID(s.ColumnInt(0)),
Skill1: horse.SkillID(s.ColumnInt(1)),
Skill2: horse.SkillID(s.ColumnInt(2)),
Skill3: horse.SkillID(s.ColumnInt(3)),
SkillBad: horse.SkillID(s.ColumnInt(4)),
}
})
skills := load(ctx1, loadgroup, db, "skills", skillSQL, func(s *sqlite.Stmt) horse.Skill {
return horse.Skill{
ID: horse.SkillID(s.ColumnInt(0)),
Name: s.ColumnText(1),
Description: s.ColumnText(2),
Group: horse.SkillGroupID(s.ColumnInt32(3)),
Rarity: int8(s.ColumnInt(5)),
GroupRate: int8(s.ColumnInt(6)),
GradeValue: s.ColumnInt32(7),
WitCheck: s.ColumnBool(8),
Activations: trimActivations([]horse.Activation{
{
Precondition: s.ColumnText(9),
Condition: s.ColumnText(10),
Duration: horse.TenThousandths(s.ColumnInt(11)),
DurScale: horse.DurScale(s.ColumnInt(12)),
Cooldown: horse.TenThousandths(s.ColumnInt(13)),
Abilities: trimAbilities([]horse.Ability{
{
Type: horse.AbilityType(s.ColumnInt(14)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(15)),
Value: horse.TenThousandths(s.ColumnInt(16)),
Target: horse.AbilityTarget(s.ColumnInt(17)),
TargetValue: s.ColumnInt32(18),
},
{
Type: horse.AbilityType(s.ColumnInt(19)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(20)),
Value: horse.TenThousandths(s.ColumnInt(21)),
Target: horse.AbilityTarget(s.ColumnInt(22)),
TargetValue: s.ColumnInt32(23),
},
{
Type: horse.AbilityType(s.ColumnInt(24)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(25)),
Value: horse.TenThousandths(s.ColumnInt(26)),
Target: horse.AbilityTarget(s.ColumnInt(27)),
TargetValue: s.ColumnInt32(28),
},
}),
},
{
Precondition: s.ColumnText(29),
Condition: s.ColumnText(30),
Duration: horse.TenThousandths(s.ColumnInt(31)),
DurScale: horse.DurScale(s.ColumnInt(32)),
Cooldown: horse.TenThousandths(s.ColumnInt(33)),
Abilities: trimAbilities([]horse.Ability{
{
Type: horse.AbilityType(s.ColumnInt(34)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(35)),
Value: horse.TenThousandths(s.ColumnInt(36)),
Target: horse.AbilityTarget(s.ColumnInt(37)),
TargetValue: s.ColumnInt32(38),
},
{
Type: horse.AbilityType(s.ColumnInt(39)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(40)),
Value: horse.TenThousandths(s.ColumnInt(41)),
Target: horse.AbilityTarget(s.ColumnInt(42)),
TargetValue: s.ColumnInt32(43),
},
{
Type: horse.AbilityType(s.ColumnInt(44)),
ValueUsage: horse.AbilityValueUsage(s.ColumnInt(45)),
Value: horse.TenThousandths(s.ColumnInt(46)),
Target: horse.AbilityTarget(s.ColumnInt(47)),
TargetValue: s.ColumnInt32(48),
},
}),
},
}),
UniqueOwner: s.ColumnText(52), // TODO(zeph): should be id, not name
Tags: parseTags(s.ColumnText(54)),
SPCost: s.ColumnInt(49),
IconID: s.ColumnInt(53),
}
})
races := load(ctx1, loadgroup, db, "races", raceSQL, func(s *sqlite.Stmt) horse.Race {
return horse.Race{
ID: horse.RaceID(s.ColumnInt(0)),
Name: s.ColumnText(1),
// TODO(zeph): grade
Thumbnail: s.ColumnInt(3),
Primary: horse.RaceID(s.ColumnInt(4)),
}
})
saddles := load(ctx1, loadgroup, db, "saddles", saddleSQL, func(s *sqlite.Stmt) horse.Saddle {
return horse.Saddle{
ID: horse.SaddleID(s.ColumnInt(0)),
Name: s.ColumnText(1),
Races: trimZeros(
horse.RaceID(s.ColumnInt(2)),
horse.RaceID(s.ColumnInt(3)),
horse.RaceID(s.ColumnInt(4)),
),
Type: horse.SaddleType(s.ColumnInt(5)),
Primary: horse.SaddleID(s.ColumnInt(6)),
}
})
scenarios := load(ctx1, loadgroup, db, "scenarios", scenarioSQL, func(s *sqlite.Stmt) horse.Scenario {
return horse.Scenario{
ID: horse.ScenarioID(s.ColumnInt(0)),
Name: s.ColumnText(1),
Title: s.ColumnText(2),
}
})
sparks := load(ctx1, loadgroup, db, "sparks", sparkSQL, func(s *sqlite.Stmt) horse.Spark {
return horse.Spark{
ID: horse.SparkID(s.ColumnInt(0)),
Name: s.ColumnText(1),
Description: s.ColumnText(2),
Group: horse.SparkGroupID(s.ColumnInt(3)),
Rarity: horse.SparkRarity(s.ColumnInt(4)),
Type: horse.SparkType(s.ColumnInt(5)),
// Effects filled in later.
}
})
sparkeffs := load(ctx1, loadgroup, db, "spark effects", sparkEffectSQL, func(s *sqlite.Stmt) SparkEffImm {
return SparkEffImm{
Group: horse.SparkGroupID(s.ColumnInt(0)),
Effect: s.ColumnInt(1),
Target: horse.SparkTarget(s.ColumnInt(2)),
Value1: s.ColumnInt32(3),
Value2: s.ColumnInt32(4),
}
})
convos := load(ctx1, loadgroup, db, "lobby conversations", conversationSQL, func(s *sqlite.Stmt) horse.Conversation {
return horse.Conversation{
CharacterID: horse.CharacterID(s.ColumnInt(0)),
Number: s.ColumnInt(1),
Location: horse.LobbyConversationLocationID(s.ColumnInt(2)),
LocationName: horse.LobbyConversationLocationID(s.ColumnInt(2)).String(),
Chara1: horse.CharacterID(s.ColumnInt(3)),
Chara2: horse.CharacterID(s.ColumnInt(4)),
Chara3: horse.CharacterID(s.ColumnInt(5)),
ConditionType: s.ColumnInt(6),
}
})
if err := os.MkdirAll(filepath.Join(out, region), 0775); err != nil {
slog.Error("create output dir", slog.Any("err", err))
os.Exit(1)
}
writegroup, ctx2 := errgroup.WithContext(ctx)
writegroup.Go(func() error { return write(ctx2, out, region, "character.json", charas) })
writegroup.Go(func() error { return write(ctx2, out, region, "affinity.json", aff) })
writegroup.Go(func() error { return write(ctx2, out, region, "uma.json", umas) })
writegroup.Go(func() error { return write(ctx2, out, region, "skill-group.json", sg) })
writegroup.Go(func() error { return write(ctx2, out, region, "skill.json", skills) })
writegroup.Go(func() error { return write(ctx2, out, region, "race.json", races) })
writegroup.Go(func() error { return write(ctx2, out, region, "saddle.json", saddles) })
writegroup.Go(func() error { return write(ctx2, out, region, "scenario.json", scenarios) })
writegroup.Go(func() error { return write(ctx2, out, region, "spark.json", mergesparks(sparks, sparkeffs)) })
writegroup.Go(func() error { return write(ctx2, out, region, "conversation.json", convos) })
if err := writegroup.Wait(); err != nil {
slog.ErrorContext(ctx, "write", slog.Any("err", err))
os.Exit(1)
}
slog.InfoContext(ctx, "done")
}
var (
//go:embed sql/character.sql
characterSQL string
//go:embed sql/affinity.sql
affinitySQL string
//go:embed sql/uma.sql
umaSQL string
//go:embed sql/skill-group.sql
skillGroupSQL string
//go:embed sql/skill.sql
skillSQL string
//go:embed sql/race.sql
raceSQL string
//go:embed sql/saddle.sql
saddleSQL string
//go:embed sql/scenario.sql
scenarioSQL string
//go:embed sql/spark.sql
sparkSQL string
//go:embed sql/spark-effect.sql
sparkEffectSQL string
//go:embed sql/conversation.sql
conversationSQL string
)
func load[T any](ctx context.Context, group *errgroup.Group, db *sqlitex.Pool, kind, sql string, row func(*sqlite.Stmt) T) func() ([]T, error) {
slog.InfoContext(ctx, "load", slog.String("kind", kind))
var r []T
group.Go(func() error {
conn, err := db.Take(ctx)
defer db.Put(conn)
if err != nil {
return fmt.Errorf("couldn't get connection for %s: %w", kind, err)
}
stmt, _, err := conn.PrepareTransient(sql)
if err != nil {
return fmt.Errorf("couldn't prepare statement for %s: %w", kind, err)
}
for {
ok, err := stmt.Step()
if err != nil {
return fmt.Errorf("error stepping %s: %w", kind, err)
}
if !ok {
break
}
r = append(r, row(stmt))
}
return nil
})
return func() ([]T, error) {
err := group.Wait()
if err == context.Canceled {
// After the first wait, all future ones return context.Canceled.
// We want to be able to wait any number of times, so hide it.
err = nil
}
return r, err
}
}
func write[T any](ctx context.Context, out, region, name string, v func() (T, error)) error {
p := filepath.Join(out, region, name)
r, err := v()
if err != nil {
return err
}
slog.InfoContext(ctx, "write", slog.String("path", p))
f, err := os.Create(p)
if err != nil {
return err
}
defer f.Close()
w := bufio.NewWriter(f)
enc := json.NewEncoder(w)
enc.SetEscapeHTML(false)
enc.SetIndent("", "\t")
err = enc.Encode(r)
err = errors.Join(err, w.Flush())
slog.InfoContext(ctx, "marshaled", slog.String("path", p))
return err
}
func mergesparks(sparks func() ([]horse.Spark, error), effs func() ([]SparkEffImm, error)) func() ([]horse.Spark, error) {
return func() ([]horse.Spark, error) {
sp, err := sparks()
if err != nil {
return nil, err
}
ef, err := effs()
if err != nil {
return nil, err
}
// Spark effects are sorted by group ID, but groups apply to multiple
// sparks, and we don't rely on sparks and groups being in the same order.
// It is possible to merge in linear time, but not worth the effort:
// n log n is fine since this is an AOT step.
for i := range sp {
k, ok := slices.BinarySearchFunc(ef, sp[i].Group, func(e SparkEffImm, v horse.SparkGroupID) int { return cmp.Compare(e.Group, v) })
if !ok {
panic(fmt.Errorf("mergesparks: no spark group for %+v", &sp[i]))
}
// Back up to the first effect in the group.
for k > 0 && ef[k-1].Group == sp[i].Group {
k--
}
// Map effect IDs to the lists of their effects.
m := make(map[int][]horse.SparkEffect)
for _, e := range ef[k:] {
if e.Group != sp[i].Group {
// Done with this group.
break
}
m[e.Effect] = append(m[e.Effect], horse.SparkEffect{Target: e.Target, Value1: e.Value1, Value2: e.Value2})
}
// Now get effects in order.
keys := slices.Sorted(maps.Keys(m))
sp[i].Effects = make([][]horse.SparkEffect, 0, len(keys))
for _, key := range keys {
sp[i].Effects = append(sp[i].Effects, m[key])
}
}
return sp, nil
}
}
type SparkEffImm struct {
Group horse.SparkGroupID
Effect int
Target horse.SparkTarget
Value1 int32
Value2 int32
}
func parseTags(s string) []uint16 {
r := make([]uint16, 0, 8)
for s != "" {
t, u, _ := strings.Cut(s, "/")
s = u
v, err := strconv.ParseUint(t, 10, 16)
if err != nil {
panic(fmt.Errorf("parsing skill tags: %w", err))
}
r = append(r, uint16(v))
}
return trimZeros(r...)
}
func trimAbilities(s []horse.Ability) []horse.Ability {
for len(s) > 0 && s[len(s)-1].Type == 0 {
s = s[:len(s)-1]
}
return s
}
func trimActivations(s []horse.Activation) []horse.Activation {
for len(s) > 0 && s[len(s)-1].Condition == "" {
s = s[:len(s)-1]
}
return s
}
func trimZeros[T comparable](s ...T) []T {
var zero T
for len(s) > 0 && s[len(s)-1] == zero {
s = s[:len(s)-1]
}
return s
}
File diff suppressed because it is too large Load Diff
+94
View File
@@ -15,6 +15,9 @@ This file is my notes from exploring the database.
- 119 is scenario full titles (e.g. The Beginning: URA Finale), 120 is scenario descriptions, 237 is scenario names (e.g. URA Finale)
- 130 is epithet names, 131 is epithet descriptions
in the decomp, text data categories are named in `public enum MasterString.Category`.
some categories seem to be missing, though.
# succession factor (sparks)
tables are succession_factor and succession_factor_effect
@@ -228,6 +231,63 @@ tag_id is a slash-separated list of numeric IDs that roughly describe all effect
- 614 base stat threshold passive
- 615 mood passive
unrelated, query to get all condition types:
```sql
WITH RECURSIVE condition AS (
SELECT DISTINCT precondition_1 AS c FROM skill_data
UNION
SELECT DISTINCT condition_1 AS c FROM skill_data
UNION
SELECT DISTINCT precondition_2 AS c FROM skill_data
UNION
SELECT DISTINCT condition_2 AS c FROM skill_data
), disj AS (
SELECT
IIF(INSTR(c, '@') != 0, SUBSTR(c, 1, INSTR(c, '@')-1), c) AS c,
IIF(INSTR(c, '@') != 0, SUBSTR(c, 1 + INSTR(c, '@')), '') AS rest
FROM condition
UNION
SELECT
IIF(INSTR(rest, '@') != 0, SUBSTR(rest, 1, INSTR(rest, '@')-1), rest) AS c,
IIF(INSTR(rest, '@') != 0, SUBSTR(rest, 1 + INSTR(rest, '@')), '') AS rest
FROM disj
WHERE rest != ''
), term AS (
SELECT
IIF(INSTR(c, '&') != 0, SUBSTR(c, 1, INSTR(c, '&')-1), c) AS term,
IIF(INSTR(c, '&') != 0, SUBSTR(c, 1 + INSTR(c, '&')), '') AS rest
FROM disj
UNION
SELECT
IIF(INSTR(rest, '&') != 0, SUBSTR(rest, 1, INSTR(rest, '&')-1), rest) AS term,
IIF(INSTR(rest, '&') != 0, SUBSTR(rest, 1 + INSTR(rest, '&')), '') AS rest
FROM term
WHERE rest != ''
), op AS (
SELECT
term,
CASE
WHEN INSTR(term, '==') != 0 THEN '=='
WHEN INSTR(term, '!=') != 0 THEN '!='
WHEN INSTR(term, '<=') != 0 THEN '<='
WHEN INSTR(term, '>=') != 0 THEN '>='
WHEN INSTR(term, '<') != 0 THEN '<'
WHEN INSTR(term, '>') != 0 THEN '>'
END AS op
FROM term WHERE term != ''
), type_op_arg AS (
SELECT DISTINCT
term,
SUBSTR(term, 1, INSTR(term, op) - 1) AS "type",
op,
CAST(SUBSTR(term, INSTR(term, op) + LENGTH(op)) AS INTEGER) AS arg
FROM op
)
SELECT DISTINCT CONCAT(type, op), arg FROM type_op_arg
```
final select can be adjusted to get different info, but type+op together seems most useful
# races
- group 1, grade: g1 100, g2 200, g3 300, op 400, pre-op 700
@@ -252,6 +312,9 @@ grade_rate_id appears to be consistently 800 iff maiden race and 900 iff debut r
recommend_class_id appears to be consistently 1 iff maiden race or debut race, 2 iff pre-op, 3 iff op; but other values are confusing.
so, it doesn't seem like there's a particular flag that identifies maiden races, despite the restrictions on when they appear in the ui.
race_course_set defines the racecourse, e.g. hanshin 1600 turf, that a given race occurs on.
notably, stat thresholds are defined here via join to race_course_set_status, rather than in course event data.
# trainee definitions
- card_data has universal trainee stats: base skill set, stat growth bonuses ("talent"), default running style
@@ -260,6 +323,37 @@ so, it doesn't seem like there's a particular flag that identifies maiden races,
- card_talent_hint_upgrade has costs to raise hint levels, but it's actually universal, only six rows
- single_mode_route_race is career goals (not only races)
- available_skill_set has starting skills including those unlocked by potential level given under need_rank (0 for pl1, 2 for pl2)
- single_mode_special_chara is scenario links
# gl
single_mode_live_song_list has the song list for lives ha ha.
this is defined from the perspective of bonuses they grant when you have them, not the shop per se.
- text_data category for song names is 210, look up by live_id; for post-concert effect text, category 208 indexed by song list id
- command_id and live_id are always equal
- level is 1 for all songs except the two instances of girls' legend u
- master_bonus_content_text_id corresponds to text_data categories 207 for pickup effect text and 209 for song name
- live_bonus_type is 1 for specialty prio, 2 for chain frequency, 3 for fb
- girls' legend u is defined twice as ids 22 and 24
costs are in single_mode_live_square.
- square_type is 1 for stat up, 2 for skill up, 3 for energy up, 4 for live
- perf_type_n is token type: 1 for dance, 2 for passion, 3 for vocals, 4 for visuals, 5 for composure
- perf_value_n is number of tokens
immediate bonuses are in single_mode_live_master_bonus.
- master_bonus_type is 1 for stat up, 2 for skill hint, 3 for energy up, 4 for song
- master_bonus_type_value is 1 for type 1, live id for type 4, 0 otherwise
- master_bonus_gain_type_n is 1 for stat, 2 for skill hint, 3 for energy, 5 for permanent training bonus
+ 1 for stat: then master_bonus_gain_value_n_1 is 1-5 for stat id or 6 for sp, n_2 is 1 for fixed or 2 for random (not actually in the game), n_3 is lower bound on gain, n_4 is 0 for fixed or upper bound for random
+ 2 for skill hint: then gain_value_n_1 is 3(*), n_2 is skill tag, n_3 is hint level
+ 3 for energy: then gain_value_n_1 is amount
+ 5 for permanent training bonus: then gain_value_n_1 is stat id (6 for sp), n_2 is amount
(*) MasterSingleModeLiveMasterBonus.SingleModeLiveMasterBonus.GainSkillHintTypeEnum defines values of Random = 1 and SkillId = 2, but they are unused in the db.
there is some ostensibly unused data.
- master bonus ids 12001-12206 grant random amounts of stats
- id 20000 corresponds to "Group Lesson" "Skill hint appropriate for aptitude"
# lobby conversations!!!
-199328
View File
File diff suppressed because it is too large Load Diff
-346
View File
@@ -1,346 +0,0 @@
[
{
"chara_id": 1001,
"name": "Special Week"
},
{
"chara_id": 1002,
"name": "Silence Suzuka"
},
{
"chara_id": 1003,
"name": "Tokai Teio"
},
{
"chara_id": 1004,
"name": "Maruzensky"
},
{
"chara_id": 1005,
"name": "Fuji Kiseki"
},
{
"chara_id": 1006,
"name": "Oguri Cap"
},
{
"chara_id": 1007,
"name": "Gold Ship"
},
{
"chara_id": 1008,
"name": "Vodka"
},
{
"chara_id": 1009,
"name": "Daiwa Scarlet"
},
{
"chara_id": 1010,
"name": "Taiki Shuttle"
},
{
"chara_id": 1011,
"name": "Grass Wonder"
},
{
"chara_id": 1012,
"name": "Hishi Amazon"
},
{
"chara_id": 1013,
"name": "Mejiro McQueen"
},
{
"chara_id": 1014,
"name": "El Condor Pasa"
},
{
"chara_id": 1015,
"name": "T.M. Opera O"
},
{
"chara_id": 1016,
"name": "Narita Brian"
},
{
"chara_id": 1017,
"name": "Symboli Rudolf"
},
{
"chara_id": 1018,
"name": "Air Groove"
},
{
"chara_id": 1019,
"name": "Agnes Digital"
},
{
"chara_id": 1020,
"name": "Seiun Sky"
},
{
"chara_id": 1021,
"name": "Tamamo Cross"
},
{
"chara_id": 1022,
"name": "Fine Motion"
},
{
"chara_id": 1023,
"name": "Biwa Hayahide"
},
{
"chara_id": 1024,
"name": "Mayano Top Gun"
},
{
"chara_id": 1025,
"name": "Manhattan Cafe"
},
{
"chara_id": 1026,
"name": "Mihono Bourbon"
},
{
"chara_id": 1027,
"name": "Mejiro Ryan"
},
{
"chara_id": 1028,
"name": "Hishi Akebono"
},
{
"chara_id": 1029,
"name": "Yukino Bijin"
},
{
"chara_id": 1030,
"name": "Rice Shower"
},
{
"chara_id": 1031,
"name": "Ines Fujin"
},
{
"chara_id": 1032,
"name": "Agnes Tachyon"
},
{
"chara_id": 1033,
"name": "Admire Vega"
},
{
"chara_id": 1034,
"name": "Inari One"
},
{
"chara_id": 1035,
"name": "Winning Ticket"
},
{
"chara_id": 1036,
"name": "Air Shakur"
},
{
"chara_id": 1037,
"name": "Eishin Flash"
},
{
"chara_id": 1038,
"name": "Curren Chan"
},
{
"chara_id": 1039,
"name": "Kawakami Princess"
},
{
"chara_id": 1040,
"name": "Gold City"
},
{
"chara_id": 1041,
"name": "Sakura Bakushin O"
},
{
"chara_id": 1042,
"name": "Seeking the Pearl"
},
{
"chara_id": 1043,
"name": "Shinko Windy"
},
{
"chara_id": 1044,
"name": "Sweep Tosho"
},
{
"chara_id": 1045,
"name": "Super Creek"
},
{
"chara_id": 1046,
"name": "Smart Falcon"
},
{
"chara_id": 1047,
"name": "Zenno Rob Roy"
},
{
"chara_id": 1048,
"name": "Tosen Jordan"
},
{
"chara_id": 1049,
"name": "Nakayama Festa"
},
{
"chara_id": 1050,
"name": "Narita Taishin"
},
{
"chara_id": 1051,
"name": "Nishino Flower"
},
{
"chara_id": 1052,
"name": "Haru Urara"
},
{
"chara_id": 1053,
"name": "Bamboo Memory"
},
{
"chara_id": 1054,
"name": "Biko Pegasus"
},
{
"chara_id": 1055,
"name": "Marvelous Sunday"
},
{
"chara_id": 1056,
"name": "Matikanefukukitaru"
},
{
"chara_id": 1057,
"name": "Mr. C.B."
},
{
"chara_id": 1058,
"name": "Meisho Doto"
},
{
"chara_id": 1059,
"name": "Mejiro Dober"
},
{
"chara_id": 1060,
"name": "Nice Nature"
},
{
"chara_id": 1061,
"name": "King Halo"
},
{
"chara_id": 1062,
"name": "Matikanetannhauser"
},
{
"chara_id": 1063,
"name": "Ikuno Dictus"
},
{
"chara_id": 1064,
"name": "Mejiro Palmer"
},
{
"chara_id": 1065,
"name": "Daitaku Helios"
},
{
"chara_id": 1066,
"name": "Twin Turbo"
},
{
"chara_id": 1067,
"name": "Satono Diamond"
},
{
"chara_id": 1068,
"name": "Kitasan Black"
},
{
"chara_id": 1069,
"name": "Sakura Chiyono O"
},
{
"chara_id": 1070,
"name": "Sirius Symboli"
},
{
"chara_id": 1071,
"name": "Mejiro Ardan"
},
{
"chara_id": 1072,
"name": "Yaeno Muteki"
},
{
"chara_id": 1073,
"name": "Tsurumaru Tsuyoshi"
},
{
"chara_id": 1074,
"name": "Mejiro Bright"
},
{
"chara_id": 1077,
"name": "Narita Top Road"
},
{
"chara_id": 1078,
"name": "Yamanin Zephyr"
},
{
"chara_id": 2001,
"name": "Happy Meek"
},
{
"chara_id": 2002,
"name": "Bitter Glasse"
},
{
"chara_id": 2003,
"name": "Little Cocon"
},
{
"chara_id": 2004,
"name": "Montjeu"
},
{
"chara_id": 9001,
"name": "Tazuna Hayakawa"
},
{
"chara_id": 9002,
"name": "Director Akikawa"
},
{
"chara_id": 9003,
"name": "Etsuko Otonashi"
},
{
"chara_id": 9004,
"name": "Trainer Kiryuin"
},
{
"chara_id": 9005,
"name": "Sasami Anshinzawa"
},
{
"chara_id": 9006,
"name": "Riko Kashimoto"
}
]
File diff suppressed because it is too large Load Diff
-1712
View File
File diff suppressed because it is too large Load Diff
-1420
View File
File diff suppressed because it is too large Load Diff
-17
View File
@@ -1,17 +0,0 @@
[
{
"scenario_id": 1,
"name": "URA Finale",
"title": "The Beginning: URA Finale"
},
{
"scenario_id": 2,
"name": "Unity Cup",
"title": "Unity Cup: Shine On, Team Spirit!"
},
{
"scenario_id": 4,
"name": "TS Climax",
"title": "Trackblazer: Start of the Climax"
}
]
File diff suppressed because it is too large Load Diff
-19649
View File
File diff suppressed because it is too large Load Diff
-38522
View File
File diff suppressed because it is too large Load Diff
-2018
View File
File diff suppressed because it is too large Load Diff
+19 -12
View File
@@ -3,31 +3,38 @@ module git.sunturtle.xyz/zephyr/horse
go 1.25.5
require (
github.com/disgoorg/disgo v0.19.0-rc.15
github.com/go-chi/chi/v5 v5.2.5
github.com/junegunn/fzf v0.67.0
golang.org/x/sync v0.20.0
github.com/disgoorg/disgo v0.19.6
github.com/gen2brain/avif v0.6.0
github.com/go-chi/chi/v5 v5.3.1
github.com/google/go-cmp v0.7.0
github.com/junegunn/fzf v0.74.1
golang.org/x/image v0.44.0
golang.org/x/sync v0.22.0
zombiezen.com/go/sqlite v1.4.2
)
require (
github.com/disgoorg/godave v0.3.0 // indirect
github.com/disgoorg/json/v2 v2.0.0 // indirect
github.com/disgoorg/omit v1.0.0 // indirect
github.com/disgoorg/snowflake/v2 v2.0.3 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.10.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741 // indirect
github.com/klauspost/compress v1.19.1 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad // indirect
golang.org/x/crypto v0.46.0 // indirect
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
golang.org/x/sys v0.39.0 // indirect
modernc.org/libc v1.65.7 // indirect
github.com/tetratelabs/wazero v1.12.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/tools v0.48.0 // indirect
modernc.org/libc v1.74.3 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.37.1 // indirect
modernc.org/sqlite v1.54.0 // indirect
)
+56 -41
View File
@@ -1,7 +1,9 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disgoorg/disgo v0.19.0-rc.15 h1:x0NsV2gcbdjwuztsg2wYXw76p1Cpc8f6ByDrkPcfQtU=
github.com/disgoorg/disgo v0.19.0-rc.15/go.mod h1:14mgXzenkJqifkDmsEgU0zI1di6jNXodwX6L8geW33A=
github.com/disgoorg/disgo v0.19.6 h1:1xJQt6KZgiqvBOnjuziG1gE4Iqd0aJn8DNfE6eE+0qw=
github.com/disgoorg/disgo v0.19.6/go.mod h1:NnV63iw4lJdF1fnV0gX27XR43ZgRGqnL122svRMTgTE=
github.com/disgoorg/godave v0.3.0 h1:37F3ZuiMd8/EXeoCtTeE8iP2eT2nWsfEa4/ITwoKfe4=
github.com/disgoorg/godave v0.3.0/go.mod h1:OreAC3hpabr39bMVA+jwOVDq1EUPXH5A0XUBiZaDI1Y=
github.com/disgoorg/json/v2 v2.0.0 h1:U16yy/ARK7/aEpzjjqK1b/KaqqGHozUdeVw/DViEzQI=
github.com/disgoorg/json/v2 v2.0.0/go.mod h1:jZTBC0nIE1WeetSEI3/Dka8g+qglb4FPVmp5I5HpEfI=
github.com/disgoorg/omit v1.0.0 h1:y0LkVUOyUHT8ZlnhIAeOZEA22UYykeysK8bLJ0SfT78=
@@ -10,22 +12,30 @@ github.com/disgoorg/snowflake/v2 v2.0.3 h1:3B+PpFjr7j4ad7oeJu4RlQ+nYOTadsKapJIzg
github.com/disgoorg/snowflake/v2 v2.0.3/go.mod h1:W6r7NUA7DwfZLwr00km6G4UnZ0zcoLBRufhkFWgAc4c=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/ebitengine/purego v0.10.2 h1:W809HbnvzAxgdm+aOvlSekrM16wGCdT/e76+9tS7gzE=
github.com/ebitengine/purego v0.10.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/gen2brain/avif v0.6.0 h1:/8WSgcU+IEF0jhKYsUZ/mzlziFuTeJFpIKBj2siTQps=
github.com/gen2brain/avif v0.6.0/go.mod h1:QgrYqdVE9y40PCfArK9VakcMIpYeDYpZmCSLkW6C1n8=
github.com/go-chi/chi/v5 v5.3.1 h1:3j4HZLGZQ3JpMCrPJF/Jl3mYJfWLKBfNJ6quurUGCf8=
github.com/go-chi/chi/v5 v5.3.1/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/junegunn/fzf v0.67.0 h1:naiOdIkV5/ZCfHgKQIV/f5YDWowl95G6yyOQqW8FeSo=
github.com/junegunn/fzf v0.67.0/go.mod h1:xlXX2/rmsccKQUnr9QOXPDi5DyV9cM0UjKy/huScBeE=
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/junegunn/fzf v0.74.1 h1:rCGVdCSoOkfcfTxtxCO/vG2yceDjRlKSlv7IfCGkc/Y=
github.com/junegunn/fzf v0.74.1/go.mod h1:hKDkO8orBWT5VLIZOL8oyhxn7mRLXdGyu+gz1Ss58pU=
github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741 h1:7dYDtfMDfKzjT+DVfIS4iqknSEKtZpEcXtu6vuaasHs=
github.com/junegunn/go-shellwords v0.0.0-20250127100254-2aa3b3277741/go.mod h1:6EILKtGpo5t+KLb85LNZLAF6P9LKp78hJI80PXMcn3c=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -36,43 +46,48 @@ github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad h1:qIQkSlF5vAUHxE
github.com/sasha-s/go-csync v0.0.0-20240107134140-fcbab37b09ad/go.mod h1:/pA7k3zsXKdjjAiUhB5CjuKib9KJGCaLvZwtxGC8U0s=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU=
github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8=
modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/cc/v4 v4.29.1 h1:MKgdCV3WykTSPqpVrnxdEDS0HEd2FHpKZDzxzU5LyeI=
modernc.org/cc/v4 v4.29.1/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
modernc.org/ccgo/v4 v4.34.6/go.mod h1:SZ8YcN9NG7XVsQYdm6jYBvi8PQP1qi+kqB6OhjqI3Fk=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/libc v1.65.7 h1:Ia9Z4yzZtWNtUIuiPuQ7Qf7kxYrxP1/jeHZzG8bFu00=
modernc.org/libc v1.65.7/go.mod h1:011EQibzzio/VX3ygj1qGFt5kMjP0lHb0qCW5/D/pQU=
modernc.org/gc/v3 v3.1.4 h1:2g65LGVSmFQrXeITAw97x7hCRvZFcyE1uDP+7Vng7JI=
modernc.org/gc/v3 v3.1.4/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.74.3 h1:a4J+Z8aVaxPyjyxRAdJzw246PqpcFGvVPnfT/AuM5Ws=
modernc.org/libc v1.74.3/go.mod h1:4H7h/MJ8wnjL8RAbp9v3OXgnk22X7MouHIhDbvP3gj4=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.37.1 h1:EgHJK/FPoqC+q2YBXg7fUmES37pCHFc97sI7zSayBEs=
modernc.org/sqlite v1.37.1/go.mod h1:XwdRtsE1MpiBcL54+MbKcaDvcuej+IYSMfLN6gSKV8g=
modernc.org/sqlite v1.54.0 h1:JCxR4qwkJvOaqAoYcgDoO25Nc+ROg6EJ2LfBVzdrgog=
modernc.org/sqlite v1.54.0/go.mod h1:4ntCLuNmnH8+GNqjka1wNg7KJd5/Hi5FYp8K+XQ7GZw=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+102
View File
@@ -0,0 +1,102 @@
package mdb
import (
"context"
_ "embed"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
"git.sunturtle.xyz/zephyr/horse"
)
var (
//go:embed sql/character.sql
characterSQL string
//go:embed sql/affinity.sql
affinitySQL string
//go:embed sql/affinity-detail.sql
affinityDetailSQL string
//go:embed sql/uma.sql
umaSQL string
//go:embed sql/conversation.sql
conversationSQL string
)
// Characters retrieves all named characters.
func Characters(ctx context.Context, db *sqlitex.Pool) ([]horse.Character, error) {
return load(ctx, db, make([]horse.Character, 0, 128), characterSQL, func(s *sqlite.Stmt) horse.Character {
return horse.Character{
ID: horse.CharacterID(s.ColumnInt(0)),
Name: s.ColumnText(1),
}
})
}
// AffinitySummary gets precomputed base affinity for all pairs and trios of characters.
func AffinitySummary(ctx context.Context, db *sqlitex.Pool) ([]horse.AffinityRelation, error) {
return load(ctx, db, nil, affinitySQL, func(s *sqlite.Stmt) horse.AffinityRelation {
return horse.AffinityRelation{
IDA: horse.CharacterID(s.ColumnInt(0)),
IDB: horse.CharacterID(s.ColumnInt(1)),
IDC: horse.CharacterID(s.ColumnInt(2)),
Affinity: s.ColumnInt(3),
}
})
}
// AffinityDetail gets all individual affinity group entries.
func AffinityDetail(ctx context.Context, db *sqlitex.Pool) ([]horse.AffinityDetail, error) {
return load(ctx, db, nil, affinityDetailSQL, func(s *sqlite.Stmt) horse.AffinityDetail {
return horse.AffinityDetail{
CharaID: horse.CharacterID(s.ColumnInt(0)),
Relation: uint16(s.ColumnInt(1)),
Affinity: uint16(s.ColumnInt(2)),
}
})
}
// Umas retrieves all trainable Uma variants.
func Umas(ctx context.Context, db *sqlitex.Pool) ([]horse.Uma, error) {
return load(ctx, db, make([]horse.Uma, 0, 128), umaSQL, func(s *sqlite.Stmt) horse.Uma {
return horse.Uma{
ID: horse.UmaID(s.ColumnInt(0)),
CharacterID: horse.CharacterID(s.ColumnInt(1)),
Name: s.ColumnText(2),
Variant: s.ColumnText(3),
Sprint: horse.AptitudeLevel(s.ColumnInt(5)),
Mile: horse.AptitudeLevel(s.ColumnInt(6)),
Medium: horse.AptitudeLevel(s.ColumnInt(7)),
Long: horse.AptitudeLevel(s.ColumnInt(8)),
Front: horse.AptitudeLevel(s.ColumnInt(9)),
Pace: horse.AptitudeLevel(s.ColumnInt(10)),
Late: horse.AptitudeLevel(s.ColumnInt(11)),
End: horse.AptitudeLevel(s.ColumnInt(12)),
Turf: horse.AptitudeLevel(s.ColumnInt(13)),
Dirt: horse.AptitudeLevel(s.ColumnInt(14)),
Unique: horse.SkillID(s.ColumnInt(15)),
Skill1: horse.SkillID(s.ColumnInt(16)),
Skill2: horse.SkillID(s.ColumnInt(17)),
Skill3: horse.SkillID(s.ColumnInt(18)),
SkillPL2: horse.SkillID(s.ColumnInt(19)),
SkillPL3: horse.SkillID(s.ColumnInt(20)),
SkillPL4: horse.SkillID(s.ColumnInt(21)),
SkillPL5: horse.SkillID(s.ColumnInt(22)),
}
})
}
func Conversations(ctx context.Context, db *sqlitex.Pool) ([]horse.Conversation, error) {
return load(ctx, db, make([]horse.Conversation, 0, 1024), conversationSQL, func(s *sqlite.Stmt) horse.Conversation {
return horse.Conversation{
ID: s.ColumnInt32(0),
CharacterID: horse.CharacterID(s.ColumnInt(1)),
Number: s.ColumnInt(2),
Location: horse.LobbyConversationLocationID(s.ColumnInt(3)),
Chara1: horse.CharacterID(s.ColumnInt(4)),
Chara2: horse.CharacterID(s.ColumnInt(5)),
Chara3: horse.CharacterID(s.ColumnInt(6)),
ConditionType: s.ColumnInt(7),
}
})
}
+336
View File
@@ -0,0 +1,336 @@
package mdb_test
import (
_ "embed"
"testing"
"git.sunturtle.xyz/zephyr/horse"
"git.sunturtle.xyz/zephyr/horse/mdb"
"github.com/google/go-cmp/cmp"
)
//go:embed testdata/character.sql
var characterSQL string
func TestCharacters(t *testing.T) {
db := testdb(t.Context(), "file:TestCharacters?mode=memory&cache=shared", characterSQL)
got, err := mdb.Characters(t.Context(), db)
if err != nil {
t.Error(err)
}
want := []horse.Character{
{ID: 1001, Name: "Special Week"},
{ID: 1002, Name: "Silence Suzuka"},
{ID: 1078, Name: "Yamanin Zephyr"},
{ID: 2001, Name: "Happy Meek"},
{ID: 9001, Name: "Tazuna Hayakawa"},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("wrong characters (+got/-want):\n%s", diff)
}
}
func TestAffinitySummary(t *testing.T) {
db := testdb(t.Context(), "file:TestAffinitySummary?mode=memory&cache=shared", characterSQL)
got, err := mdb.AffinitySummary(t.Context(), db)
if err != nil {
t.Error(err)
}
want := []horse.AffinityRelation{
{IDA: 1001, IDB: 1002, Affinity: 23},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("wrong affinity (+got/-want):\n%s", diff)
}
}
func TestAffinityDetail(t *testing.T) {
db := testdb(t.Context(), "file:TestAffinityDetail?mode=memory&cache=shared", characterSQL)
got, err := mdb.AffinityDetail(t.Context(), db)
if err != nil {
t.Error(err)
}
want := []horse.AffinityDetail{
{CharaID: 1001, Relation: 103, Affinity: 2},
{CharaID: 1001, Relation: 202, Affinity: 2},
{CharaID: 1001, Relation: 301, Affinity: 2},
{CharaID: 1001, Relation: 401, Affinity: 2},
{CharaID: 1001, Relation: 502, Affinity: 2},
{CharaID: 1001, Relation: 510, Affinity: 2},
{CharaID: 1001, Relation: 2001, Affinity: 1},
{CharaID: 1001, Relation: 2102, Affinity: 1},
{CharaID: 1001, Relation: 2301, Affinity: 1},
{CharaID: 1001, Relation: 2406, Affinity: 1},
{CharaID: 1001, Relation: 2506, Affinity: 1},
{CharaID: 1001, Relation: 2510, Affinity: 1},
{CharaID: 1001, Relation: 2516, Affinity: 1},
{CharaID: 1001, Relation: 2519, Affinity: 1},
{CharaID: 1001, Relation: 2601, Affinity: 1},
{CharaID: 1001, Relation: 2603, Affinity: 1},
{CharaID: 1001, Relation: 2811, Affinity: 1},
{CharaID: 1001, Relation: 2903, Affinity: 7},
{CharaID: 1001, Relation: 3003, Affinity: 7},
{CharaID: 1001, Relation: 3004, Affinity: 7},
{CharaID: 1001, Relation: 3101, Affinity: 7},
{CharaID: 1001, Relation: 3205, Affinity: 1},
{CharaID: 1001, Relation: 7003, Affinity: 1},
{CharaID: 1001, Relation: 7004, Affinity: 1},
{CharaID: 1001, Relation: 7005, Affinity: 1},
{CharaID: 1001, Relation: 7006, Affinity: 1},
{CharaID: 1001, Relation: 7007, Affinity: 1},
{CharaID: 1001, Relation: 8001, Affinity: 1},
{CharaID: 1001, Relation: 8002, Affinity: 1},
{CharaID: 1001, Relation: 8003, Affinity: 1},
{CharaID: 1001, Relation: 8004, Affinity: 1},
{CharaID: 1001, Relation: 8005, Affinity: 1},
{CharaID: 1001, Relation: 8006, Affinity: 1},
{CharaID: 1001, Relation: 8007, Affinity: 1},
{CharaID: 1001, Relation: 8008, Affinity: 1},
{CharaID: 1001, Relation: 8009, Affinity: 1},
{CharaID: 1001, Relation: 8010, Affinity: 1},
{CharaID: 1001, Relation: 8011, Affinity: 1},
{CharaID: 1001, Relation: 8012, Affinity: 1},
{CharaID: 1001, Relation: 8013, Affinity: 1},
{CharaID: 1001, Relation: 8014, Affinity: 1},
{CharaID: 1001, Relation: 8015, Affinity: 1},
{CharaID: 1001, Relation: 8016, Affinity: 1},
{CharaID: 1001, Relation: 8443, Affinity: 1},
{CharaID: 1001, Relation: 8479, Affinity: 1},
{CharaID: 1001, Relation: 8511, Affinity: 1},
{CharaID: 1001, Relation: 8536, Affinity: 1},
{CharaID: 1001, Relation: 8640, Affinity: 1},
{CharaID: 1002, Relation: 104, Affinity: 2},
{CharaID: 1002, Relation: 202, Affinity: 2},
{CharaID: 1002, Relation: 301, Affinity: 2},
{CharaID: 1002, Relation: 402, Affinity: 2},
{CharaID: 1002, Relation: 2001, Affinity: 1},
{CharaID: 1002, Relation: 2406, Affinity: 1},
{CharaID: 1002, Relation: 2512, Affinity: 1},
{CharaID: 1002, Relation: 2601, Affinity: 1},
{CharaID: 1002, Relation: 2603, Affinity: 1},
{CharaID: 1002, Relation: 2810, Affinity: 1},
{CharaID: 1002, Relation: 2901, Affinity: 7},
{CharaID: 1002, Relation: 3003, Affinity: 7},
{CharaID: 1002, Relation: 3101, Affinity: 7},
{CharaID: 1002, Relation: 3205, Affinity: 1},
{CharaID: 1002, Relation: 7000, Affinity: 1},
{CharaID: 1002, Relation: 7001, Affinity: 1},
{CharaID: 1002, Relation: 7002, Affinity: 1},
{CharaID: 1002, Relation: 7013, Affinity: 1},
{CharaID: 1002, Relation: 7015, Affinity: 1},
{CharaID: 1002, Relation: 8017, Affinity: 1},
{CharaID: 1002, Relation: 8018, Affinity: 1},
{CharaID: 1002, Relation: 8019, Affinity: 1},
{CharaID: 1002, Relation: 8020, Affinity: 1},
{CharaID: 1002, Relation: 8021, Affinity: 1},
{CharaID: 1002, Relation: 8022, Affinity: 1},
{CharaID: 1002, Relation: 8023, Affinity: 1},
{CharaID: 1002, Relation: 8024, Affinity: 1},
{CharaID: 1002, Relation: 8025, Affinity: 1},
{CharaID: 1002, Relation: 8026, Affinity: 1},
{CharaID: 1002, Relation: 8027, Affinity: 1},
{CharaID: 1002, Relation: 8028, Affinity: 1},
{CharaID: 1002, Relation: 8029, Affinity: 1},
{CharaID: 1002, Relation: 8030, Affinity: 1},
{CharaID: 1002, Relation: 8031, Affinity: 1},
{CharaID: 1002, Relation: 8032, Affinity: 1},
{CharaID: 1002, Relation: 8444, Affinity: 1},
{CharaID: 1002, Relation: 8480, Affinity: 1},
{CharaID: 1002, Relation: 8512, Affinity: 1},
{CharaID: 1002, Relation: 8537, Affinity: 1},
{CharaID: 1002, Relation: 8641, Affinity: 1},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("wrong affinity details (+got/-want):\n%s", diff)
}
}
func TestUmas(t *testing.T) {
db := testdb(t.Context(), "file:TestUmas?mode=memory&cache=shared", characterSQL)
got, err := mdb.Umas(t.Context(), db)
if err != nil {
t.Error(err)
}
want := []horse.Uma{
{
ID: 100101,
CharacterID: 1001,
Name: `[Special Dreamer] Special Week`,
Variant: `[Special Dreamer]`,
Sprint: 2,
Mile: 5,
Medium: 7,
Long: 7,
Front: 1,
Pace: 7,
Late: 7,
End: 5,
Turf: 7,
Dirt: 1,
Unique: 100011,
Skill1: 200512,
Skill2: 201352,
Skill3: 200732,
SkillPL2: 200162,
SkillPL3: 201351,
SkillPL4: 200612,
SkillPL5: 200511,
},
{
ID: 100102,
CharacterID: 1001,
Name: `[Hopp'n♪Happy Heart] Special Week`,
Variant: `[Hopp'n♪Happy Heart]`,
Sprint: 2,
Mile: 5,
Medium: 7,
Long: 7,
Front: 1,
Pace: 7,
Late: 7,
End: 5,
Turf: 7,
Dirt: 1,
Unique: 110011,
Skill1: 200462,
Skill2: 200592,
Skill3: 201132,
SkillPL2: 200212,
SkillPL3: 200591,
SkillPL4: 201611,
SkillPL5: 200461,
},
{
ID: 100201,
CharacterID: 1002,
Name: `[Innocent Silence] Silence Suzuka`,
Variant: `[Innocent Silence]`,
Sprint: 4,
Mile: 7,
Medium: 7,
Long: 3,
Front: 7,
Pace: 5,
Late: 3,
End: 1,
Turf: 7,
Dirt: 1,
Unique: 100021,
Skill1: 200432,
Skill2: 200552,
Skill3: 200712,
SkillPL2: 200022,
SkillPL3: 200431,
SkillPL4: 200542,
SkillPL5: 200551,
},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("wrong umas (+got/-want):\n%s", diff)
}
}
func TestConversations(t *testing.T) {
db := testdb(t.Context(), "file:TestConversations?mode=memory&cache=shared", characterSQL)
got, err := mdb.Conversations(t.Context(), db)
if err != nil {
t.Error(err)
}
want := []horse.Conversation{
{
ID: 1,
CharacterID: 1001,
Number: 1,
Location: 410,
Chara1: 1001,
},
{
ID: 2,
CharacterID: 1001,
Number: 2,
Location: 510,
Chara1: 1001,
ConditionType: 1,
},
{
ID: 3,
CharacterID: 1001,
Number: 3,
Location: 310,
Chara1: 1001,
ConditionType: 1,
},
{
ID: 76,
CharacterID: 1001,
Number: 4,
Location: 120,
Chara1: 1001,
Chara2: 1002,
ConditionType: 2,
},
{
ID: 77,
CharacterID: 1001,
Number: 5,
Location: 520,
Chara1: 1003,
Chara2: 1001,
ConditionType: 3,
},
{
ID: 126,
CharacterID: 1001,
Number: 6,
Location: 430,
Chara1: 1001,
Chara2: 1014,
Chara3: 1011,
ConditionType: 1,
},
{
ID: 4,
CharacterID: 1002,
Number: 1,
Location: 310,
Chara1: 1002,
},
{
ID: 5,
CharacterID: 1002,
Number: 2,
Location: 210,
Chara1: 1002,
ConditionType: 1,
},
{
ID: 6,
CharacterID: 1002,
Number: 3,
Location: 110,
Chara1: 1002,
ConditionType: 1,
},
{
ID: 78,
CharacterID: 1002,
Number: 4,
Location: 520,
Chara1: 1010,
Chara2: 1002,
ConditionType: 3,
},
{
ID: 79,
CharacterID: 1002,
Number: 5,
Location: 220,
Chara1: 1002,
Chara2: 1018,
ConditionType: 2,
},
}
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("wrong conversations (+got/-want):\n%s", diff)
}
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 400.0
},
{
"_paramType": 0,
"_values": [
4,
259
],
"_distance": 675.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 400.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 934.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 725.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 735.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 725.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 735.0
}
]
}
+80
View File
@@ -0,0 +1,80 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
2,
275
],
"_distance": 150.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 700.0
},
{
"_paramType": 0,
"_values": [
4,
259
],
"_distance": 975.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 425.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1234.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1500.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1035.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1035.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
275
],
"_distance": 175.0
},
{
"_paramType": 0,
"_values": [
2,
275
],
"_distance": 450.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1000.0
},
{
"_paramType": 0,
"_values": [
4,
259
],
"_distance": 1275.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 175.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 725.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1534.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1325.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1335.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1325.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1335.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
275
],
"_distance": 375.0
},
{
"_paramType": 0,
"_values": [
2,
275
],
"_distance": 650.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1200.0
},
{
"_paramType": 0,
"_values": [
4,
259
],
"_distance": 1475.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 375.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 925.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1200.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1734.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1525.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1535.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1525.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1535.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 175.0
},
{
"_paramType": 0,
"_values": [
4,
275
],
"_distance": 450.0
},
{
"_paramType": 0,
"_values": [
1,
275
],
"_distance": 975.0
},
{
"_paramType": 0,
"_values": [
2,
275
],
"_distance": 1250.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1800.0
},
{
"_paramType": 0,
"_values": [
4,
259
],
"_distance": 2075.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 175.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 725.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 975.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1525.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1800.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2334.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2125.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2135.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2125.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2135.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
230
],
"_distance": 280.0
},
{
"_paramType": 0,
"_values": [
4,
226
],
"_distance": 510.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 280.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 736.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 550.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 560.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 550.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 560.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
230
],
"_distance": 240.0
},
{
"_paramType": 0,
"_values": [
2,
230
],
"_distance": 470.0
},
{
"_paramType": 0,
"_values": [
3,
230
],
"_distance": 980.0
},
{
"_paramType": 0,
"_values": [
4,
226
],
"_distance": 1210.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 240.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 980.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1436.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1700.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1250.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1260.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1250.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1260.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
230
],
"_distance": 200.0
},
{
"_paramType": 0,
"_values": [
4,
230
],
"_distance": 430.0
},
{
"_paramType": 0,
"_values": [
1,
230
],
"_distance": 940.0
},
{
"_paramType": 0,
"_values": [
2,
230
],
"_distance": 1170.0
},
{
"_paramType": 0,
"_values": [
3,
230
],
"_distance": 1680.0
},
{
"_paramType": 0,
"_values": [
4,
226
],
"_distance": 1910.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 200.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 660.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 940.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1408.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1680.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2136.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1950.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1960.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1950.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1960.0
}
]
}
+80
View File
@@ -0,0 +1,80 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
220
],
"_distance": 310.0
},
{
"_paramType": 0,
"_values": [
4,
208
],
"_distance": 530.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 310.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 738.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 600.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 610.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 600.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 610.0
},
{
"_paramType": 11,
"_values": [
10000,
555
],
"_distance": 0.0
}
]
}
+80
View File
@@ -0,0 +1,80 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
220
],
"_distance": 510.0
},
{
"_paramType": 0,
"_values": [
4,
208
],
"_distance": 730.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 510.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 938.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 810.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 810.0
},
{
"_paramType": 11,
"_values": [
10000,
755
],
"_distance": 0.0
}
]
}
+120
View File
@@ -0,0 +1,120 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
220
],
"_distance": 320.0
},
{
"_paramType": 0,
"_values": [
2,
220
],
"_distance": 540.0
},
{
"_paramType": 0,
"_values": [
3,
220
],
"_distance": 1110.0
},
{
"_paramType": 0,
"_values": [
4,
208
],
"_distance": 1330.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 320.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 760.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1110.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1538.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1400.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1410.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1400.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1410.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 220.0
},
{
"_paramType": 11,
"_values": [
10000,
720
],
"_distance": 665.0
}
]
}
+120
View File
@@ -0,0 +1,120 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
220
],
"_distance": 520.0
},
{
"_paramType": 0,
"_values": [
2,
220
],
"_distance": 740.0
},
{
"_paramType": 0,
"_values": [
3,
220
],
"_distance": 1310.0
},
{
"_paramType": 0,
"_values": [
4,
208
],
"_distance": 1530.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 520.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 960.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1310.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1738.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1600.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1610.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1600.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1610.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 420.0
},
{
"_paramType": 11,
"_values": [
10000,
720
],
"_distance": 865.0
}
]
}
+160
View File
@@ -0,0 +1,160 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
240
],
"_distance": 260.0
},
{
"_paramType": 0,
"_values": [
4,
230
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
1,
220
],
"_distance": 1120.0
},
{
"_paramType": 0,
"_values": [
2,
220
],
"_distance": 1340.0
},
{
"_paramType": 0,
"_values": [
3,
220
],
"_distance": 1910.0
},
{
"_paramType": 0,
"_values": [
4,
208
],
"_distance": 2130.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 260.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 730.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1120.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1560.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1910.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2338.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2200.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2210.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2200.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2210.0
},
{
"_paramType": 11,
"_values": [
10000,
495
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 970.0
},
{
"_paramType": 11,
"_values": [
10000,
720
],
"_distance": 1425.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
190
],
"_distance": 370.0
},
{
"_paramType": 0,
"_values": [
4,
180
],
"_distance": 560.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 370.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 740.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 600.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 610.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 600.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 610.0
}
]
}
+120
View File
@@ -0,0 +1,120 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
190
],
"_distance": 350.0
},
{
"_paramType": 0,
"_values": [
2,
190
],
"_distance": 540.0
},
{
"_paramType": 0,
"_values": [
3,
190
],
"_distance": 1070.0
},
{
"_paramType": 0,
"_values": [
4,
180
],
"_distance": 1260.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 350.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 730.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1070.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1440.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1700.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 11,
"_values": [
-10000,
340
],
"_distance": 275.0
},
{
"_paramType": 11,
"_values": [
10000,
670
],
"_distance": 615.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
190
],
"_distance": 292.0
},
{
"_paramType": 0,
"_values": [
4,
190
],
"_distance": 482.0
},
{
"_paramType": 0,
"_values": [
1,
190
],
"_distance": 1040.0
},
{
"_paramType": 0,
"_values": [
2,
190
],
"_distance": 1230.0
},
{
"_paramType": 0,
"_values": [
3,
190
],
"_distance": 1770.0
},
{
"_paramType": 0,
"_values": [
4,
180
],
"_distance": 1960.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 292.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 672.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1040.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1420.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1770.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2140.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2010.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2010.0
}
]
}
+63
View File
@@ -0,0 +1,63 @@
{
"courseParams": [
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 649.9000244140625
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 690.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 7,
"_values": [
2
],
"_distance": 30.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 696.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 706.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 450.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 842.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 725.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 735.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 760.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 650.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 850.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1042.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 925.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 935.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 950.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 960.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 550.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 550.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 942.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 810.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 810.0
},
{
"_paramType": 11,
"_values": [
10000,
350
],
"_distance": 250.0
},
{
"_paramType": 11,
"_values": [
-15000,
300
],
"_distance": 600.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 750.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1142.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1000.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1010.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1000.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1010.0
},
{
"_paramType": 11,
"_values": [
10000,
350
],
"_distance": 450.0
},
{
"_paramType": 11,
"_values": [
-15000,
300
],
"_distance": 800.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 420.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 620.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1250.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 420.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 820.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1250.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1642.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1525.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1535.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1525.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1535.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 950.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1150.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1342.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1200.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1210.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1200.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1210.0
},
{
"_paramType": 11,
"_values": [
-15000,
300
],
"_distance": 1000.0
},
{
"_paramType": 11,
"_values": [
10000,
350
],
"_distance": 650.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 650.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 850.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1450.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1050.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1842.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1725.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1735.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1725.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1735.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 810.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 1010.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1650.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1850.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 810.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1210.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2042.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1925.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1935.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1925.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1935.0
}
]
}
+86
View File
@@ -0,0 +1,86 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
160
],
"_distance": 540.0
},
{
"_paramType": 0,
"_values": [
4,
147
],
"_distance": 700.0
},
{
"_paramType": 1,
"_values": [
1
],
"_distance": 0.0
},
{
"_paramType": 1,
"_values": [
2
],
"_distance": 80.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 540.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 847.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 760.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 815.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 825.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
160
],
"_distance": 400.0
},
{
"_paramType": 0,
"_values": [
2,
160
],
"_distance": 560.0
},
{
"_paramType": 0,
"_values": [
3,
160
],
"_distance": 1140.0
},
{
"_paramType": 0,
"_values": [
4,
147
],
"_distance": 1300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 400.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 720.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1140.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1447.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1350.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1360.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1350.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1360.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
160
],
"_distance": 380.0
},
{
"_paramType": 0,
"_values": [
4,
160
],
"_distance": 540.0
},
{
"_paramType": 0,
"_values": [
1,
160
],
"_distance": 1120.0
},
{
"_paramType": 0,
"_values": [
2,
160
],
"_distance": 1280.0
},
{
"_paramType": 0,
"_values": [
3,
160
],
"_distance": 1850.0
},
{
"_paramType": 0,
"_values": [
4,
160
],
"_distance": 2010.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 380.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1120.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1440.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1850.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2170.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2500.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2050.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2060.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2050.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2060.0
}
]
}
+80
View File
@@ -0,0 +1,80 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
300
],
"_distance": 420.0
},
{
"_paramType": 0,
"_values": [
4,
188
],
"_distance": 720.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 420.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 908.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 760.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 748.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 758.0
},
{
"_paramType": 11,
"_values": [
15000,
100
],
"_distance": 180.0
}
]
}
+112
View File
@@ -0,0 +1,112 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 330.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 530.0
},
{
"_paramType": 0,
"_values": [
3,
300
],
"_distance": 1020.0
},
{
"_paramType": 0,
"_values": [
4,
188
],
"_distance": 1320.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 330.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 730.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1020.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1508.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1350.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1360.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1350.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1360.0
},
{
"_paramType": 11,
"_values": [
15000,
100
],
"_distance": 780.0
}
]
}
+112
View File
@@ -0,0 +1,112 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 530.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 730.0
},
{
"_paramType": 0,
"_values": [
3,
300
],
"_distance": 1220.0
},
{
"_paramType": 0,
"_values": [
4,
188
],
"_distance": 1520.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 530.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 930.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1220.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1708.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1550.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1560.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1550.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1560.0
},
{
"_paramType": 11,
"_values": [
15000,
100
],
"_distance": 980.0
}
]
}
+152
View File
@@ -0,0 +1,152 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
300
],
"_distance": 220.0
},
{
"_paramType": 0,
"_values": [
4,
200
],
"_distance": 520.0
},
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 1130.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 1330.0
},
{
"_paramType": 0,
"_values": [
3,
300
],
"_distance": 1820.0
},
{
"_paramType": 0,
"_values": [
4,
188
],
"_distance": 2120.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 220.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 720.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1130.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1530.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1820.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2308.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2150.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2160.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2150.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2160.0
},
{
"_paramType": 11,
"_values": [
15000,
80
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
15000,
100
],
"_distance": 1580.0
}
]
}
+86
View File
@@ -0,0 +1,86 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
210
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
4,
145
],
"_distance": 710.0
},
{
"_paramType": 1,
"_values": [
1
],
"_distance": 0.0
},
{
"_paramType": 1,
"_values": [
2
],
"_distance": 110.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 855.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1150.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 751.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 761.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 751.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 761.0
}
]
}
+132
View File
@@ -0,0 +1,132 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
170
],
"_distance": 360.0
},
{
"_paramType": 0,
"_values": [
2,
170
],
"_distance": 530.0
},
{
"_paramType": 0,
"_values": [
3,
210
],
"_distance": 1050.0
},
{
"_paramType": 0,
"_values": [
4,
145
],
"_distance": 1260.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 360.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1050.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1405.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1700.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1301.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1311.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1301.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1311.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1301.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1311.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1301.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1311.0
},
{
"_paramType": 11,
"_values": [
-10000,
320
],
"_distance": 285.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
210
],
"_distance": 310.0
},
{
"_paramType": 0,
"_values": [
4,
160
],
"_distance": 520.0
},
{
"_paramType": 0,
"_values": [
1,
170
],
"_distance": 1060.0
},
{
"_paramType": 0,
"_values": [
2,
170
],
"_distance": 1230.0
},
{
"_paramType": 0,
"_values": [
3,
210
],
"_distance": 1750.0
},
{
"_paramType": 0,
"_values": [
4,
145
],
"_distance": 1960.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 310.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 680.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1060.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1400.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1750.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2105.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2001.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2011.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2001.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2011.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
350
],
"_distance": 300.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 890.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 11,
"_values": [
-15000,
200
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 1025.0
}
]
}
+80
View File
@@ -0,0 +1,80 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
2,
450
],
"_distance": 50.0
},
{
"_paramType": 0,
"_values": [
3,
350
],
"_distance": 700.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 1050.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1290.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1100.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1110.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1100.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1110.0
},
{
"_paramType": 11,
"_values": [
-15000,
300
],
"_distance": 300.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 1425.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 175.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 425.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1000.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 1250.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 175.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 675.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1490.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 11,
"_values": [
20000,
35
],
"_distance": 1.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 125.0
},
{
"_paramType": 11,
"_values": [
-15000,
400
],
"_distance": 425.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 1625.0
}
]
}
+150
View File
@@ -0,0 +1,150 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 375.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 625.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1200.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 375.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 875.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1200.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1690.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 3,
"_values": [
7000
],
"_distance": 875.0
},
{
"_paramType": 3,
"_values": [
10000
],
"_distance": 1450.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1500.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1510.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1500.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1510.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 325.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 125.0
},
{
"_paramType": 11,
"_values": [
-15000,
400
],
"_distance": 625.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 1825.0
}
]
}
+120
View File
@@ -0,0 +1,120 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
247
],
"_distance": 403.0
},
{
"_paramType": 0,
"_values": [
2,
450
],
"_distance": 650.0
},
{
"_paramType": 0,
"_values": [
3,
350
],
"_distance": 1300.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 1650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 403.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1890.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1700.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1710.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 153.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 353.0
},
{
"_paramType": 11,
"_values": [
-15000,
300
],
"_distance": 900.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 2025.0
}
]
}
+152
View File
@@ -0,0 +1,152 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
146
],
"_distance": 100.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 246.0
},
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 875.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 1125.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1700.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 1950.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 496.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 875.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1375.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1700.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2190.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2500.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2010.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2010.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 621.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 825.0
},
{
"_paramType": 11,
"_values": [
-15000,
400
],
"_distance": 1125.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 2325.0
}
]
}
+224
View File
@@ -0,0 +1,224 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 290.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 540.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1115.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1365.0
},
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 1975.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 2225.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 2800.0
},
{
"_paramType": 0,
"_values": [
4,
240
],
"_distance": 3050.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 290.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 790.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1115.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1615.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1975.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 2475.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 2800.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 3290.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 3600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 3100.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 3110.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 3100.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 3110.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 40.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 240.0
},
{
"_paramType": 11,
"_values": [
-15000,
400
],
"_distance": 540.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 1740.0
},
{
"_paramType": 11,
"_values": [
15000,
200
],
"_distance": 1925.0
},
{
"_paramType": 11,
"_values": [
-15000,
400
],
"_distance": 2225.0
},
{
"_paramType": 11,
"_values": [
20000,
110
],
"_distance": 3425.0
}
]
}
+102
View File
@@ -0,0 +1,102 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 700.0
},
{
"_paramType": 1,
"_values": [
1
],
"_distance": 0.0
},
{
"_paramType": 1,
"_values": [
2
],
"_distance": 110.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 892.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 11,
"_values": [
-15000,
175
],
"_distance": 175.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 1000.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 350.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 550.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1100.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1100.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1492.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 100.0
},
{
"_paramType": 11,
"_values": [
10000,
175
],
"_distance": 350.0
},
{
"_paramType": 11,
"_values": [
-15000,
175
],
"_distance": 775.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 1600.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 200.0
},
{
"_paramType": 0,
"_values": [
4,
200
],
"_distance": 400.0
},
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 950.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 1150.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1700.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 1900.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 200.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 600.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1350.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1700.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2092.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1900.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1910.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1900.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1910.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 300.0
},
{
"_paramType": 0,
"_values": [
4,
200
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 1050.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 1250.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1800.0
},
{
"_paramType": 0,
"_values": [
4,
192
],
"_distance": 2000.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1050.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1800.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2192.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2500.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2010.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2000.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2010.0
}
]
}
+96
View File
@@ -0,0 +1,96 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 350.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 625.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 875.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 760.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 125.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 250.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 950.0
}
]
}
+96
View File
@@ -0,0 +1,96 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 550.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 825.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 550.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1075.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 900.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 910.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 950.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 960.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 450.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 325.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1150.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 75.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 750.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1025.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 325.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1275.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1100.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1110.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1126.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1136.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 525.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 650.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1350.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 200.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 950.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1225.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 400.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1475.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1300.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1310.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1340.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1350.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 725.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 850.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1550.0
}
]
}
+128
View File
@@ -0,0 +1,128 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 225.0
},
{
"_paramType": 0,
"_values": [
2,
325
],
"_distance": 475.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1250.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1525.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 225.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 800.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1250.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1775.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2300.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1600.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1610.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1640.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1650.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 1025.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 1150.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1850.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 325.0
},
{
"_paramType": 0,
"_values": [
2,
325
],
"_distance": 575.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1350.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1625.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 325.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 900.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1875.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1740.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1750.0
},
{
"_paramType": 11,
"_values": [
15000,
40
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 1125.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 1250.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1950.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 425.0
},
{
"_paramType": 0,
"_values": [
2,
325
],
"_distance": 675.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1450.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 1725.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 425.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1975.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2500.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1800.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1810.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1850.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1860.0
},
{
"_paramType": 11,
"_values": [
15000,
140
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 1225.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 1350.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 2050.0
}
]
}
+184
View File
@@ -0,0 +1,184 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 292.0
},
{
"_paramType": 0,
"_values": [
4,
275
],
"_distance": 567.0
},
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 1325.0
},
{
"_paramType": 0,
"_values": [
2,
325
],
"_distance": 1575.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 2350.0
},
{
"_paramType": 0,
"_values": [
4,
250
],
"_distance": 2625.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 292.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 842.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1325.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1900.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 2350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2875.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 3400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 2700.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 2710.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 2750.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 2760.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 67.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 192.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 892.0
},
{
"_paramType": 11,
"_values": [
20000,
75
],
"_distance": 2125.0
},
{
"_paramType": 11,
"_values": [
-15000,
250
],
"_distance": 2250.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 2950.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
225
],
"_distance": 350.0
},
{
"_paramType": 0,
"_values": [
4,
224
],
"_distance": 575.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 799.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1300.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 550.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 560.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 700.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 710.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 275.0
},
{
"_paramType": 11,
"_values": [
15000,
250
],
"_distance": 800.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
225
],
"_distance": 450.0
},
{
"_paramType": 0,
"_values": [
4,
224
],
"_distance": 675.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 899.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 650.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 660.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 810.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 375.0
},
{
"_paramType": 11,
"_values": [
15000,
250
],
"_distance": 900.0
}
]
}
+102
View File
@@ -0,0 +1,102 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
225
],
"_distance": 650.0
},
{
"_paramType": 0,
"_values": [
4,
224
],
"_distance": 875.0
},
{
"_paramType": 1,
"_values": [
1
],
"_distance": 0.0
},
{
"_paramType": 1,
"_values": [
2
],
"_distance": 120.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 650.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1099.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 900.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 910.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1000.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1010.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 575.0
},
{
"_paramType": 11,
"_values": [
15000,
250
],
"_distance": 1100.0
}
]
}
+120
View File
@@ -0,0 +1,120 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 200.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 450.0
},
{
"_paramType": 0,
"_values": [
3,
225
],
"_distance": 1150.0
},
{
"_paramType": 0,
"_values": [
4,
224
],
"_distance": 1375.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 200.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1150.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1599.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2100.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1400.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1410.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1500.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1510.0
},
{
"_paramType": 11,
"_values": [
-10000,
200
],
"_distance": 1075.0
},
{
"_paramType": 11,
"_values": [
15000,
250
],
"_distance": 1600.0
}
]
}
+112
View File
@@ -0,0 +1,112 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
2,
250
],
"_distance": 750.0
},
{
"_paramType": 0,
"_values": [
3,
225
],
"_distance": 1450.0
},
{
"_paramType": 0,
"_values": [
4,
225
],
"_distance": 1675.0
},
{
"_paramType": 0,
"_values": [
90,
500
],
"_distance": 2348.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1450.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1900.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1800.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1810.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1800.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1810.0
}
]
}
+169
View File
@@ -0,0 +1,169 @@
{
"courseParams": [
{
"_paramType": 1,
"_values": [
1
],
"_distance": 5.0
},
{
"_paramType": 0,
"_values": [
4,
276
],
"_distance": 205.0
},
{
"_paramType": 4,
"_values": [
40,
6000,
0
],
"_distance": 210.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 481.0
},
{
"_paramType": 0,
"_values": [
1,
250
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1000.0
},
{
"_paramType": 5,
"_values": [
10,
20000
],
"_distance": 1005.0
},
{
"_paramType": 4,
"_values": [
10,
20000,
0
],
"_distance": 1005.0
},
{
"_paramType": 0,
"_values": [
2,
300
],
"_distance": 1250.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 1550.0
},
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 1950.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1950.0
},
{
"_paramType": 5,
"_values": [
100,
0
],
"_distance": 1955.0
},
{
"_paramType": 0,
"_values": [
4,
275
],
"_distance": 2225.0
},
{
"_paramType": 4,
"_values": [
40,
6000,
0
],
"_distance": 2230.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 2500.0
},
{
"_paramType": 4,
"_values": [
50,
5000,
0
],
"_distance": 2600.0
},
{
"_paramType": 4,
"_values": [
70,
5000,
0
],
"_distance": 2800.0
},
{
"_paramType": 4,
"_values": [
90,
500,
0
],
"_distance": 2950.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 3000.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 300.0
},
{
"_paramType": 0,
"_values": [
4,
238
],
"_distance": 550.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 788.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 790.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 790.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 800.0
},
{
"_paramType": 11,
"_values": [
-10000,
775
],
"_distance": 100.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 875.0
}
]
}
+88
View File
@@ -0,0 +1,88 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
4,
238
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 988.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 860.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 870.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 850.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 860.0
},
{
"_paramType": 11,
"_values": [
-10000,
775
],
"_distance": 300.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 1075.0
}
]
}
+96
View File
@@ -0,0 +1,96 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
2,
150
],
"_distance": 150.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 700.0
},
{
"_paramType": 0,
"_values": [
4,
238
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 300.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1188.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1060.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1070.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1060.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1070.0
},
{
"_paramType": 11,
"_values": [
-10000,
775
],
"_distance": 500.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 1275.0
}
]
}
+128
View File
@@ -0,0 +1,128 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 300.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1100.0
},
{
"_paramType": 0,
"_values": [
4,
238
],
"_distance": 1350.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 300.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1100.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1588.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2000.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1460.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1470.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1460.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1470.0
},
{
"_paramType": 11,
"_values": [
20000,
50
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
-10000,
775
],
"_distance": 900.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 1675.0
}
]
}
+136
View File
@@ -0,0 +1,136 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
200
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
2,
200
],
"_distance": 700.0
},
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 1300.0
},
{
"_paramType": 0,
"_values": [
4,
238
],
"_distance": 1550.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 900.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1788.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 2200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1660.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1670.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1660.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1670.0
},
{
"_paramType": 11,
"_values": [
-10000,
150
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 150.0
},
{
"_paramType": 11,
"_values": [
-10000,
775
],
"_distance": 1100.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 1875.0
}
]
}
+72
View File
@@ -0,0 +1,72 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 400.0
},
{
"_paramType": 0,
"_values": [
4,
190
],
"_distance": 600.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 400.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 790.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 760.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 750.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 760.0
}
]
}
+122
View File
@@ -0,0 +1,122 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 600.0
},
{
"_paramType": 0,
"_values": [
4,
190
],
"_distance": 800.0
},
{
"_paramType": 1,
"_values": [
1
],
"_distance": 0.0
},
{
"_paramType": 1,
"_values": [
2
],
"_distance": 155.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 600.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 990.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 865.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 865.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 865.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 865.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 11,
"_values": [
-15000,
600
],
"_distance": 425.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1025.0
}
]
}
+148
View File
@@ -0,0 +1,148 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
165
],
"_distance": 270.0
},
{
"_paramType": 0,
"_values": [
2,
165
],
"_distance": 435.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1000.0
},
{
"_paramType": 0,
"_values": [
4,
190
],
"_distance": 1200.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 270.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 600.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1000.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1390.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1800.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1265.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1275.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1265.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1275.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1265.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1275.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1265.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1275.0
},
{
"_paramType": 11,
"_values": [
15000,
50
],
"_distance": 0.0
},
{
"_paramType": 11,
"_values": [
-15000,
600
],
"_distance": 825.0
},
{
"_paramType": 11,
"_values": [
15000,
150
],
"_distance": 1425.0
}
]
}
+104
View File
@@ -0,0 +1,104 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
1,
165
],
"_distance": 370.0
},
{
"_paramType": 0,
"_values": [
2,
165
],
"_distance": 535.0
},
{
"_paramType": 0,
"_values": [
3,
200
],
"_distance": 1100.0
},
{
"_paramType": 0,
"_values": [
4,
190
],
"_distance": 1300.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 370.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 1100.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1490.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1900.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1365.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1375.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1365.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1375.0
}
]
}
+108
View File
@@ -0,0 +1,108 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 320.0
},
{
"_paramType": 0,
"_values": [
4,
277
],
"_distance": 595.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 320.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 872.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1200.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 675.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 685.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 675.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 685.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 675.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 685.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 675.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 685.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 120.0
},
{
"_paramType": 11,
"_values": [
-15000,
150
],
"_distance": 420.0
}
]
}
+108
View File
@@ -0,0 +1,108 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 520.0
},
{
"_paramType": 0,
"_values": [
4,
277
],
"_distance": 795.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 520.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1072.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 885.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 885.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 885.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 875.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 885.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 320.0
},
{
"_paramType": 11,
"_values": [
-15000,
150
],
"_distance": 620.0
}
]
}
+116
View File
@@ -0,0 +1,116 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 500.0
},
{
"_paramType": 0,
"_values": [
4,
247
],
"_distance": 750.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 0.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 500.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 997.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1400.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 825.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 835.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 825.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 835.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 825.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 835.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 825.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 835.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 250.0
},
{
"_paramType": 11,
"_values": [
10000,
225
],
"_distance": 350.0
},
{
"_paramType": 11,
"_values": [
-20000,
150
],
"_distance": 575.0
}
]
}
+108
View File
@@ -0,0 +1,108 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
275
],
"_distance": 720.0
},
{
"_paramType": 0,
"_values": [
4,
277
],
"_distance": 995.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 200.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 720.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1272.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1075.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1085.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1075.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1085.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1075.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1085.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1075.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1085.0
},
{
"_paramType": 11,
"_values": [
15000,
175
],
"_distance": 520.0
},
{
"_paramType": 11,
"_values": [
-15000,
150
],
"_distance": 820.0
}
]
}
+116
View File
@@ -0,0 +1,116 @@
{
"courseParams": [
{
"_paramType": 0,
"_values": [
3,
250
],
"_distance": 700.0
},
{
"_paramType": 0,
"_values": [
4,
247
],
"_distance": 950.0
},
{
"_paramType": 2,
"_values": [
1,
2
],
"_distance": 200.0
},
{
"_paramType": 2,
"_values": [
2,
2
],
"_distance": 700.0
},
{
"_paramType": 2,
"_values": [
1,
1
],
"_distance": 1197.0
},
{
"_paramType": 2,
"_values": [
2,
1
],
"_distance": 1600.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1035.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1035.0
},
{
"_paramType": 4,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 5,
"_values": [],
"_distance": 1035.0
},
{
"_paramType": 8,
"_values": [],
"_distance": 1025.0
},
{
"_paramType": 9,
"_values": [],
"_distance": 1035.0
},
{
"_paramType": 11,
"_values": [
20000,
100
],
"_distance": 450.0
},
{
"_paramType": 11,
"_values": [
10000,
225
],
"_distance": 550.0
},
{
"_paramType": 11,
"_values": [
-20000,
150
],
"_distance": 775.0
}
]
}

Some files were not shown because too many files have changed in this diff Show More