From d9e2059acb501c2067a51e2080b65a358e4b6587 Mon Sep 17 00:00:00 2001 From: Iacami Gevaerd Date: Tue, 7 Nov 2023 10:26:24 -0300 Subject: [PATCH] feat: add brazilian scale --- README.md | 1 + src/GradeScale.ts | 4 +- src/__tests__/scales/brazilian.ts | 105 ++++++++++++++ src/data/routes.csv | 218 +++++++++++++++--------------- src/data/routes.json | 2 +- src/index.ts | 9 +- src/scales/brazilian.ts | 98 ++++++++++++++ src/scales/index.ts | 5 +- 8 files changed, 326 insertions(+), 116 deletions(-) create mode 100644 src/__tests__/scales/brazilian.ts create mode 100644 src/scales/brazilian.ts diff --git a/README.md b/README.md index ac4aae6..e2048a9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Javascript utilities for working with rock climbing grades. - [x] UIAA - [x] Ewbanks - [x] Saxon +- [x] Brazilian **Bouldering** - [x] Vermin (V-scale) diff --git a/src/GradeScale.ts b/src/GradeScale.ts index c2281f3..01e016b 100644 --- a/src/GradeScale.ts +++ b/src/GradeScale.ts @@ -11,6 +11,7 @@ export default interface GradeScale { name: GradeScalesTypes offset: number allowableConversionType: GradeScalesTypes[] + grades?: string[] } export const GradeScales = { @@ -24,7 +25,8 @@ export const GradeScales = { UIAA: 'uiaa', EWBANK: 'ewbank', SAXON: 'saxon', - NORWEGIAN: 'norwegian' + NORWEGIAN: 'norwegian', + BRAZILIAN_CRUX: 'brazilian_crux' } as const export type GradeScalesTypes = typeof GradeScales[keyof typeof GradeScales] diff --git a/src/__tests__/scales/brazilian.ts b/src/__tests__/scales/brazilian.ts new file mode 100644 index 0000000..73f3c99 --- /dev/null +++ b/src/__tests__/scales/brazilian.ts @@ -0,0 +1,105 @@ +import { GradeBands } from '../../GradeBands' +import { BrazilianCrux } from '../../scales' + +describe('BrazilianCrux', () => { + describe('Get Score', () => { + [ + ['III', 'I'], + ['IXb', 'VIsup'], + ['VIsup', 'III'], + ['VIsup', 'VI'] + ].forEach((t) => { + test(`${t[0]} > ${t[1]}`, () => { + const lowGrade = BrazilianCrux.getScore(t[1]) + const highGrade = BrazilianCrux.getScore(t[0]) + expect(highGrade[0]).toBeGreaterThan(lowGrade[1]) + }) + }) + + test('Slash grade provided', () => { + expect(BrazilianCrux.getScore('VI/VIsup')).toStrictEqual([65, 66]) + expect(BrazilianCrux.getScore('VIIIa/b')).toStrictEqual([75, 76]) + expect(BrazilianCrux.getScore('II/IIsup')).toStrictEqual([18, 24]) + }) + }) + + describe('Invalid grade format', () => { + jest.spyOn(console, 'warn').mockImplementation() + beforeEach(() => { + jest.clearAllMocks() + }) + test('invalid plus modifier', () => { + const invalidGrade = BrazilianCrux.getScore('VI+') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade format: VI+ for grade scale BrazilianCrux' + ) + expect(invalidGrade).toEqual(-1) + }) + test('invalid minus modifier', () => { + const invalidGrade = BrazilianCrux.getScore('VI-') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade format: VI- for grade scale BrazilianCrux' + ) + expect(invalidGrade).toEqual(-1) + }) + test('extra slash grade', () => { + const invalidGrade = BrazilianCrux.getScore('VI/VIsup/VII') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade format: VI/VIsup/VII for grade scale BrazilianCrux' + ) + expect(invalidGrade).toEqual(-1) + }) + test('next grade not subsequent (abc)', () => { + const invalidGrade = BrazilianCrux.getScore('VIIa/c') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade slash not subsequent: VIIc' + ) + expect(invalidGrade).toEqual(-1) + }) + test('next grade not subsequent (sup)', () => { + const invalidGrade = BrazilianCrux.getScore('V/VIsup') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade slash not subsequent: VIsup' + ) + expect(invalidGrade).toEqual(-1) + }) + test('not BrazilianCrux scale', () => { + const invalidGrade = BrazilianCrux.getScore('V11') + expect(console.warn).toHaveBeenCalledWith( + 'Unexpected grade format: V11 for grade scale BrazilianCrux' + ) + expect(invalidGrade).toEqual(-1) + }) + }) + + describe('Get Grade', () => { + test('bottom of range', () => { + expect(BrazilianCrux.getGrade(0)).toBe('I') + }) + + test('top of range', () => { + expect(BrazilianCrux.getGrade(1000)).toBe('XIVa') + }) + + test('single score provided', () => { + expect(BrazilianCrux.getGrade(25)).toBe('IIsup') + expect(BrazilianCrux.getGrade(30)).toBe('III') + expect(BrazilianCrux.getGrade(48)).toBe('IVsup') + expect(BrazilianCrux.getGrade(75)).toBe('VIIIa') + }) + test('range of scores provided', () => { + expect(BrazilianCrux.getGrade([43, 44])).toBe('IV') + expect(BrazilianCrux.getGrade([71, 72])).toBe('VIIb/VIIc') + expect(BrazilianCrux.getGrade([12, 15])).toBe('Isup/II') + expect(BrazilianCrux.getGrade([44, 55])).toBe('IV/IVsup') + }) + }) + + describe('Get Grade Band', () => { + test('gets Gradeband', () => { + expect(BrazilianCrux.getGradeBand('III')).toEqual(GradeBands.BEGINNER) + expect(BrazilianCrux.getGradeBand('VIIIa')).toEqual(GradeBands.ADVANCED) + expect(BrazilianCrux.getGradeBand('IXb')).toEqual(GradeBands.EXPERT) + }) + }) +}) diff --git a/src/data/routes.csv b/src/data/routes.csv index b2e8afd..7e3591c 100644 --- a/src/data/routes.csv +++ b/src/data/routes.csv @@ -1,109 +1,109 @@ -score,yds,french,uiaa,ewbank,saxon,norwegian -0,5.0,1a,1,1,1,1- -1,5.0,1a,1,1,1,1- -2,5.0,1a+,1,1,1,1- -3,5.0,1a+,1,1,1,1- -4,5.0,1b,1,1,1,1 -5,5.0,1b,1,2,1,1 -6,5.0,1b+,1,2,1,1+ -7,5.0,1b+,1,2,1,1+ -8,5.0,1c,1,2,1,1+ -9,5.0,1c,1,2,1,1+ -10,5.0,1c+,1,3,1,2- -11,5,1c+,1,4,1,2- -12,5.1,2a,2,5,2,2 -13,5.1,2a,2,5,2,2 -14,5.1,2a+,2,5,2,2 -15,5.1,2a+,2,6,2,2 -16,5.1,2b,2,6,2,2+ -17,5.1,2b,2,6,2,2+ -18,5.2,2b+,2,7,2,2+ -19,5.2,2b+,2,7,2,2+ -20,5.2,2c,2,7,2,3- -21,5.2,2c,2,7,2,3- -22,5.3,2c+,2,8,2,3 -23,5.3,2c+,2,8,2,3 -24,5.3,3a,3,9,3,3 -25,5.3,3a,3,9,3,3 -26,5.4,3a+,3,10,3,3+ -27,5.4,3a+,3,10,3,3+ -28,5.4,3b,3,10,3,3+ -29,5.4,3b,3,10,3,3+ -30,5.4,3b+,3,10,3,4- -31,5.5,3b+,3,11,3,4- -32,5.5,3c,3,11,3,4 -33,5.5,3c,3,12,3,4 -34,5.5,3c+,3,12,3,4 -35,5.5,3c+,3,12,3,4 -36,5.6,4a,4,13,4,4+ -37,5.6,4a,4,13,4,4+ -38,5.6,4a+,4+,13,4,4+ -39,5.6,4a+,4+,13,4,4+ -40,5.6,4b,4+,13,5,5- -41,5.7,4b,4+,14,5,5- -42,5.7,4b+,5-,14,5,5- -43,5.7,4b+,5-,14,5,5- -44,5.7,4c,5-,15,5,5 -45,5.7,4c,5-,15,5,5 -46,5.8,4c+,5,16,6,5 -47,5.8,4c+,5,16,6,5 -48,5.8,5a,5,16,7a,5+ -49,5.8,5a,5,16,7a,5+ -50,5.8,5a+,5+,16,7a,5+ -51,5.8,5a+,5+,16,7a,5+ -52,5.9,5b,5+,17,7a,5+ -53,5.9,5b,5+,17,7a,5+ -54,5.9,5b+,6-,17,7b,5+ -55,5.9,5b+,6-,17,7b,5+ -56,5.9,5c,6,17,7b,6- -57,5.10a,5c,6,18,7b,6- -58,5.10a,5c+,6+,18,7c,6- -59,5.10a,5c+,6+,18,7c,6- -60,5.10a,6a,6+,18,7c,6- -61,5.10a,6a,6+,18,7c,6- -62,5.10b,6a+,7-,19,8a,6 -63,5.10b,6a+,7-,19,8a,6 -64,5.10c,6b,7,20,8b,6 -65,5.10c,6b,7,20,8b,6 -66,5.10d,6b+,7+,20,8c,6+ -67,5.11a,6b+,7+,21,8c,6+ -68,5.11a,6c,7+/8-,21,9a,7- -69,5.11b,6c,7+/8-,22,9a,7- -70,5.11b,6c+,8-,22,9a,7 -71,5.11c,6c+,8-,23,9a,7 -72,5.11c,7a,8,23,9b,7+ -73,5.11d,7a,8,23,9b,7+ -74,5.11d,7a+,8+,24,9c,8- -75,5.12a,7a+,8+,24,9c,8- -76,5.12b,7b,8+/9-,25,10a,8- -77,5.12b,7b,8+/9-,25,10a,8- -78,5.12c,7b+,9-,26,10a,8 -79,5.12c,7b+,9-,26,10a,8 -80,5.12d,7c,9,27,10b,8+ -81,5.12d,7c,9,27,10b,8+ -82,5.13a,7c+,9+,28,10c,8+ -83,5.13a,7c+,9+,28,10c,8+ -84,5.13b,8a,10-,29,10c,9- -85,5.13b,8a,10-,29,10c,9- -86,5.13c,8a+,10,30,11b,9- -87,5.13c,8a+,10,30,11b,9- -88,5.13d,8b,10+,31,11c,9 -89,5.13d,8b,10+,31,11c,9 -90,5.14a,8b+,10+/11-,32,11c,9+ -91,5.14a,8b+,10+/11-,32,11c,9+ -92,5.14b,8c,11-,33,12a,9+ -93,5.14b,8c,11-,33,12a,9+ -94,5.14c,8c+,11,34,12b,10- -95,5.14c,8c+,11,34,12b,10- -96,5.14d,9a,11,35,12c,10 -97,5.14d,9a,11,35,12c,10 -98,5.15a,9a+,11/11+,36,13a,10+ -99,5.15a,9a+,11/11+,36,13a,10+ -100,5.15b,9b,11+,37,13b,10+ -101,5.15b,9b,11+,37,13b,10+ -102,5.15c,9b+,11+/12-,38,13b,11- -103,5.15c,9b+,11+/12-,38,13b,11- -104,5.15d,9c,12-,39,13c,11 -105,5.15d,9c,12-,39,13c,11 -106,5.16a,9c+,12,40,13c,11+ -107,5.16a,9c+,12,40,13c,11+ +score,yds,french,uiaa,ewbank,saxon,norwegian,brazilian_crux +0,5.0,1a,1,1,1,1-,I +1,5.0,1a,1,1,1,1-,I +2,5.0,1a+,1,1,1,1-,I +3,5.0,1a+,1,1,1,1-,I +4,5.0,1b,1,1,1,1,I +5,5.0,1b,1,2,1,1,I +6,5.0,1b+,1,2,1,1+,I +7,5.0,1b+,1,2,1,1+,I +8,5.0,1c,1,2,1,1+,Isup +9,5.0,1c,1,2,1,1+,Isup +10,5.0,1c+,1,3,1,2-,Isup +11,5,1c+,1,4,1,2-,Isup +12,5.1,2a,2,5,2,2,Isup +13,5.1,2a,2,5,2,2,Isup +14,5.1,2a+,2,5,2,2,II +15,5.1,2a+,2,6,2,2,II +16,5.1,2b,2,6,2,2+,II +17,5.1,2b,2,6,2,2+,II +18,5.2,2b+,2,7,2,2+,II +19,5.2,2b+,2,7,2,2+,II +20,5.2,2c,2,7,2,3-,II +21,5.2,2c,2,7,2,3-,II +22,5.3,2c+,2,8,2,3,IIsup +23,5.3,2c+,2,8,2,3,IIsup +24,5.3,3a,3,9,3,3,IIsup +25,5.3,3a,3,9,3,3,IIsup +26,5.4,3a+,3,10,3,3+,IIsup +27,5.4,3a+,3,10,3,3+,IIsup +28,5.4,3b,3,10,3,3+,III +29,5.4,3b,3,10,3,3+,III +30,5.4,3b+,3,10,3,4-,III +31,5.5,3b+,3,11,3,4-,III +32,5.5,3c,3,11,3,4,III +33,5.5,3c,3,12,3,4,III +34,5.5,3c+,3,12,3,4,III +35,5.5,3c+,3,12,3,4,III +36,5.6,4a,4,13,4,4+,IIIsup +37,5.6,4a,4,13,4,4+,IIIsup +38,5.6,4a+,4+,13,4,4+,IIIsup +39,5.6,4a+,4+,13,4,4+,IIIsup +40,5.6,4b,4+,13,5,5-,IIIsup +41,5.7,4b,4+,14,5,5-,IIIsup +42,5.7,4b+,5-,14,5,5-,IV +43,5.7,4b+,5-,14,5,5-,IV +44,5.7,4c,5-,15,5,5,IV +45,5.7,4c,5-,15,5,5,IV +46,5.8,4c+,5,16,6,5,IV +47,5.8,4c+,5,16,6,5,IV +48,5.8,5a,5,16,7a,5+,IVsup +49,5.8,5a,5,16,7a,5+,IVsup +50,5.8,5a+,5+,16,7a,5+,IVsup +51,5.8,5a+,5+,16,7a,5+,IVsup +52,5.9,5b,5+,17,7a,5+,IVsup +53,5.9,5b,5+,17,7a,5+,IVsup +54,5.9,5b+,6-,17,7b,5+,IVsup +55,5.9,5b+,6-,17,7b,5+,IVsup +56,5.9,5c,6,17,7b,6-,V +57,5.10a,5c,6,18,7b,6-,V +58,5.10a,5c+,6+,18,7c,6-,V +59,5.10a,5c+,6+,18,7c,6-,V +60,5.10a,6a,6+,18,7c,6-,V +61,5.10a,6a,6+,18,7c,6-,V +62,5.10b,6a+,7-,19,8a,6,Vsup +63,5.10b,6a+,7-,19,8a,6,Vsup +64,5.10c,6b,7,20,8b,6,VI +65,5.10c,6b,7,20,8b,6,VI +66,5.10d,6b+,7+,20,8c,6+,VIsup +67,5.11a,6b+,7+,21,8c,6+,VIsup +68,5.11a,6c,7+/8-,21,9a,7-,VIIa +69,5.11b,6c,7+/8-,22,9a,7-,VIIa +70,5.11b,6c+,8-,22,9a,7,VIIb +71,5.11c,6c+,8-,23,9a,7,VIIb +72,5.11c,7a,8,23,9b,7+,VIIc +73,5.11d,7a,8,23,9b,7+,VIIc +74,5.11d,7a+,8+,24,9c,8-,VIIIa +75,5.12a,7a+,8+,24,9c,8-,VIIIa +76,5.12b,7b,8+/9-,25,10a,8-,VIIIb +77,5.12b,7b,8+/9-,25,10a,8-,VIIIb +78,5.12c,7b+,9-,26,10a,8,VIIIc +79,5.12c,7b+,9-,26,10a,8,VIIIc +80,5.12d,7c,9,27,10b,8+,IXa +81,5.12d,7c,9,27,10b,8+,IXa +82,5.13a,7c+,9+,28,10c,8+,IXb +83,5.13a,7c+,9+,28,10c,8+,IXb +84,5.13b,8a,10-,29,10c,9-,IXc +85,5.13b,8a,10-,29,10c,9-,IXc +86,5.13c,8a+,10,30,11b,9-,Xa +87,5.13c,8a+,10,30,11b,9-,Xa +88,5.13d,8b,10+,31,11c,9,Xb +89,5.13d,8b,10+,31,11c,9,Xb +90,5.14a,8b+,10+/11-,32,11c,9+,Xc +91,5.14a,8b+,10+/11-,32,11c,9+,Xc +92,5.14b,8c,11-,33,12a,9+,XIa +93,5.14b,8c,11-,33,12a,9+,XIa +94,5.14c,8c+,11,34,12b,10-,XIb +95,5.14c,8c+,11,34,12b,10-,XIb +96,5.14d,9a,11,35,12c,10,XIc +97,5.14d,9a,11,35,12c,10,XIc +98,5.15a,9a+,11/11+,36,13a,10+,XIIa +99,5.15a,9a+,11/11+,36,13a,10+,XIIa +100,5.15b,9b,11+,37,13b,10+,XIIb +101,5.15b,9b,11+,37,13b,10+,XIIb +102,5.15c,9b+,11+/12-,38,13b,11-,XIIc +103,5.15c,9b+,11+/12-,38,13b,11-,XIIc +104,5.15d,9c,12-,39,13c,11,XIIIa +105,5.15d,9c,12-,39,13c,11,XIIIb +106,5.16a,9c+,12,40,13c,11+,XIIIc +107,5.16a,9c+,12,40,13c,11+,XIVa diff --git a/src/data/routes.json b/src/data/routes.json index bbb14c2..329b9db 100644 --- a/src/data/routes.json +++ b/src/data/routes.json @@ -1 +1 @@ -[{"score":0,"yds":"5.0","french":"1a","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-"},{"score":1,"yds":"5.0","french":"1a","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-"},{"score":2,"yds":"5.0","french":"1a+","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-"},{"score":3,"yds":"5.0","french":"1a+","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-"},{"score":4,"yds":"5.0","french":"1b","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1"},{"score":5,"yds":"5.0","french":"1b","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1"},{"score":6,"yds":"5.0","french":"1b+","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+"},{"score":7,"yds":"5.0","french":"1b+","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+"},{"score":8,"yds":"5.0","french":"1c","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+"},{"score":9,"yds":"5.0","french":"1c","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+"},{"score":10,"yds":"5.0","french":"1c+","uiaa":"1","ewbank":"3","saxon":"1","norwegian":"2-"},{"score":11,"yds":"5","french":"1c+","uiaa":"1","ewbank":"4","saxon":"1","norwegian":"2-"},{"score":12,"yds":"5.1","french":"2a","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2"},{"score":13,"yds":"5.1","french":"2a","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2"},{"score":14,"yds":"5.1","french":"2a+","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2"},{"score":15,"yds":"5.1","french":"2a+","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2"},{"score":16,"yds":"5.1","french":"2b","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2+"},{"score":17,"yds":"5.1","french":"2b","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2+"},{"score":18,"yds":"5.2","french":"2b+","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"2+"},{"score":19,"yds":"5.2","french":"2b+","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"2+"},{"score":20,"yds":"5.2","french":"2c","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"3-"},{"score":21,"yds":"5.2","french":"2c","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"3-"},{"score":22,"yds":"5.3","french":"2c+","uiaa":"2","ewbank":"8","saxon":"2","norwegian":"3"},{"score":23,"yds":"5.3","french":"2c+","uiaa":"2","ewbank":"8","saxon":"2","norwegian":"3"},{"score":24,"yds":"5.3","french":"3a","uiaa":"3","ewbank":"9","saxon":"3","norwegian":"3"},{"score":25,"yds":"5.3","french":"3a","uiaa":"3","ewbank":"9","saxon":"3","norwegian":"3"},{"score":26,"yds":"5.4","french":"3a+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+"},{"score":27,"yds":"5.4","french":"3a+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+"},{"score":28,"yds":"5.4","french":"3b","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+"},{"score":29,"yds":"5.4","french":"3b","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+"},{"score":30,"yds":"5.4","french":"3b+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"4-"},{"score":31,"yds":"5.5","french":"3b+","uiaa":"3","ewbank":"11","saxon":"3","norwegian":"4-"},{"score":32,"yds":"5.5","french":"3c","uiaa":"3","ewbank":"11","saxon":"3","norwegian":"4"},{"score":33,"yds":"5.5","french":"3c","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4"},{"score":34,"yds":"5.5","french":"3c+","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4"},{"score":35,"yds":"5.5","french":"3c+","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4"},{"score":36,"yds":"5.6","french":"4a","uiaa":"4","ewbank":"13","saxon":"4","norwegian":"4+"},{"score":37,"yds":"5.6","french":"4a","uiaa":"4","ewbank":"13","saxon":"4","norwegian":"4+"},{"score":38,"yds":"5.6","french":"4a+","uiaa":"4+","ewbank":"13","saxon":"4","norwegian":"4+"},{"score":39,"yds":"5.6","french":"4a+","uiaa":"4+","ewbank":"13","saxon":"4","norwegian":"4+"},{"score":40,"yds":"5.6","french":"4b","uiaa":"4+","ewbank":"13","saxon":"5","norwegian":"5-"},{"score":41,"yds":"5.7","french":"4b","uiaa":"4+","ewbank":"14","saxon":"5","norwegian":"5-"},{"score":42,"yds":"5.7","french":"4b+","uiaa":"5-","ewbank":"14","saxon":"5","norwegian":"5-"},{"score":43,"yds":"5.7","french":"4b+","uiaa":"5-","ewbank":"14","saxon":"5","norwegian":"5-"},{"score":44,"yds":"5.7","french":"4c","uiaa":"5-","ewbank":"15","saxon":"5","norwegian":"5"},{"score":45,"yds":"5.7","french":"4c","uiaa":"5-","ewbank":"15","saxon":"5","norwegian":"5"},{"score":46,"yds":"5.8","french":"4c+","uiaa":"5","ewbank":"16","saxon":"6","norwegian":"5"},{"score":47,"yds":"5.8","french":"4c+","uiaa":"5","ewbank":"16","saxon":"6","norwegian":"5"},{"score":48,"yds":"5.8","french":"5a","uiaa":"5","ewbank":"16","saxon":"7a","norwegian":"5+"},{"score":49,"yds":"5.8","french":"5a","uiaa":"5","ewbank":"16","saxon":"7a","norwegian":"5+"},{"score":50,"yds":"5.8","french":"5a+","uiaa":"5+","ewbank":"16","saxon":"7a","norwegian":"5+"},{"score":51,"yds":"5.8","french":"5a+","uiaa":"5+","ewbank":"16","saxon":"7a","norwegian":"5+"},{"score":52,"yds":"5.9","french":"5b","uiaa":"5+","ewbank":"17","saxon":"7a","norwegian":"5+"},{"score":53,"yds":"5.9","french":"5b","uiaa":"5+","ewbank":"17","saxon":"7a","norwegian":"5+"},{"score":54,"yds":"5.9","french":"5b+","uiaa":"6-","ewbank":"17","saxon":"7b","norwegian":"5+"},{"score":55,"yds":"5.9","french":"5b+","uiaa":"6-","ewbank":"17","saxon":"7b","norwegian":"5+"},{"score":56,"yds":"5.9","french":"5c","uiaa":"6","ewbank":"17","saxon":"7b","norwegian":"6-"},{"score":57,"yds":"5.10a","french":"5c","uiaa":"6","ewbank":"18","saxon":"7b","norwegian":"6-"},{"score":58,"yds":"5.10a","french":"5c+","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-"},{"score":59,"yds":"5.10a","french":"5c+","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-"},{"score":60,"yds":"5.10a","french":"6a","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-"},{"score":61,"yds":"5.10a","french":"6a","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-"},{"score":62,"yds":"5.10b","french":"6a+","uiaa":"7-","ewbank":"19","saxon":"8a","norwegian":"6"},{"score":63,"yds":"5.10b","french":"6a+","uiaa":"7-","ewbank":"19","saxon":"8a","norwegian":"6"},{"score":64,"yds":"5.10c","french":"6b","uiaa":"7","ewbank":"20","saxon":"8b","norwegian":"6"},{"score":65,"yds":"5.10c","french":"6b","uiaa":"7","ewbank":"20","saxon":"8b","norwegian":"6"},{"score":66,"yds":"5.10d","french":"6b+","uiaa":"7+","ewbank":"20","saxon":"8c","norwegian":"6+"},{"score":67,"yds":"5.11a","french":"6b+","uiaa":"7+","ewbank":"21","saxon":"8c","norwegian":"6+"},{"score":68,"yds":"5.11a","french":"6c","uiaa":"7+/8-","ewbank":"21","saxon":"9a","norwegian":"7-"},{"score":69,"yds":"5.11b","french":"6c","uiaa":"7+/8-","ewbank":"22","saxon":"9a","norwegian":"7-"},{"score":70,"yds":"5.11b","french":"6c+","uiaa":"8-","ewbank":"22","saxon":"9a","norwegian":"7"},{"score":71,"yds":"5.11c","french":"6c+","uiaa":"8-","ewbank":"23","saxon":"9a","norwegian":"7"},{"score":72,"yds":"5.11c","french":"7a","uiaa":"8","ewbank":"23","saxon":"9b","norwegian":"7+"},{"score":73,"yds":"5.11d","french":"7a","uiaa":"8","ewbank":"23","saxon":"9b","norwegian":"7+"},{"score":74,"yds":"5.11d","french":"7a+","uiaa":"8+","ewbank":"24","saxon":"9c","norwegian":"8-"},{"score":75,"yds":"5.12a","french":"7a+","uiaa":"8+","ewbank":"24","saxon":"9c","norwegian":"8-"},{"score":76,"yds":"5.12b","french":"7b","uiaa":"8+/9-","ewbank":"25","saxon":"10a","norwegian":"8-"},{"score":77,"yds":"5.12b","french":"7b","uiaa":"8+/9-","ewbank":"25","saxon":"10a","norwegian":"8-"},{"score":78,"yds":"5.12c","french":"7b+","uiaa":"9-","ewbank":"26","saxon":"10a","norwegian":"8"},{"score":79,"yds":"5.12c","french":"7b+","uiaa":"9-","ewbank":"26","saxon":"10a","norwegian":"8"},{"score":80,"yds":"5.12d","french":"7c","uiaa":"9","ewbank":"27","saxon":"10b","norwegian":"8+"},{"score":81,"yds":"5.12d","french":"7c","uiaa":"9","ewbank":"27","saxon":"10b","norwegian":"8+"},{"score":82,"yds":"5.13a","french":"7c+","uiaa":"9+","ewbank":"28","saxon":"10c","norwegian":"8+"},{"score":83,"yds":"5.13a","french":"7c+","uiaa":"9+","ewbank":"28","saxon":"10c","norwegian":"8+"},{"score":84,"yds":"5.13b","french":"8a","uiaa":"10-","ewbank":"29","saxon":"10c","norwegian":"9-"},{"score":85,"yds":"5.13b","french":"8a","uiaa":"10-","ewbank":"29","saxon":"10c","norwegian":"9-"},{"score":86,"yds":"5.13c","french":"8a+","uiaa":"10","ewbank":"30","saxon":"11b","norwegian":"9-"},{"score":87,"yds":"5.13c","french":"8a+","uiaa":"10","ewbank":"30","saxon":"11b","norwegian":"9-"},{"score":88,"yds":"5.13d","french":"8b","uiaa":"10+","ewbank":"31","saxon":"11c","norwegian":"9"},{"score":89,"yds":"5.13d","french":"8b","uiaa":"10+","ewbank":"31","saxon":"11c","norwegian":"9"},{"score":90,"yds":"5.14a","french":"8b+","uiaa":"10+/11-","ewbank":"32","saxon":"11c","norwegian":"9+"},{"score":91,"yds":"5.14a","french":"8b+","uiaa":"10+/11-","ewbank":"32","saxon":"11c","norwegian":"9+"},{"score":92,"yds":"5.14b","french":"8c","uiaa":"11-","ewbank":"33","saxon":"12a","norwegian":"9+"},{"score":93,"yds":"5.14b","french":"8c","uiaa":"11-","ewbank":"33","saxon":"12a","norwegian":"9+"},{"score":94,"yds":"5.14c","french":"8c+","uiaa":"11","ewbank":"34","saxon":"12b","norwegian":"10-"},{"score":95,"yds":"5.14c","french":"8c+","uiaa":"11","ewbank":"34","saxon":"12b","norwegian":"10-"},{"score":96,"yds":"5.14d","french":"9a","uiaa":"11","ewbank":"35","saxon":"12c","norwegian":"10"},{"score":97,"yds":"5.14d","french":"9a","uiaa":"11","ewbank":"35","saxon":"12c","norwegian":"10"},{"score":98,"yds":"5.15a","french":"9a+","uiaa":"11/11+","ewbank":"36","saxon":"13a","norwegian":"10+"},{"score":99,"yds":"5.15a","french":"9a+","uiaa":"11/11+","ewbank":"36","saxon":"13a","norwegian":"10+"},{"score":100,"yds":"5.15b","french":"9b","uiaa":"11+","ewbank":"37","saxon":"13b","norwegian":"10+"},{"score":101,"yds":"5.15b","french":"9b","uiaa":"11+","ewbank":"37","saxon":"13b","norwegian":"10+"},{"score":102,"yds":"5.15c","french":"9b+","uiaa":"11+/12-","ewbank":"38","saxon":"13b","norwegian":"11-"},{"score":103,"yds":"5.15c","french":"9b+","uiaa":"11+/12-","ewbank":"38","saxon":"13b","norwegian":"11-"},{"score":104,"yds":"5.15d","french":"9c","uiaa":"12-","ewbank":"39","saxon":"13c","norwegian":"11"},{"score":105,"yds":"5.15d","french":"9c","uiaa":"12-","ewbank":"39","saxon":"13c","norwegian":"11"},{"score":106,"yds":"5.16a","french":"9c+","uiaa":"12","ewbank":"40","saxon":"13c","norwegian":"11+"},{"score":107,"yds":"5.16a","french":"9c+","uiaa":"12","ewbank":"40","saxon":"13c","norwegian":"11+"}] \ No newline at end of file +[{"score":0,"yds":"5.0","french":"1a","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-","brazilian_crux":"I"},{"score":1,"yds":"5.0","french":"1a","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-","brazilian_crux":"I"},{"score":2,"yds":"5.0","french":"1a+","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-","brazilian_crux":"I"},{"score":3,"yds":"5.0","french":"1a+","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1-","brazilian_crux":"I"},{"score":4,"yds":"5.0","french":"1b","uiaa":"1","ewbank":"1","saxon":"1","norwegian":"1","brazilian_crux":"I"},{"score":5,"yds":"5.0","french":"1b","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1","brazilian_crux":"I"},{"score":6,"yds":"5.0","french":"1b+","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+","brazilian_crux":"I"},{"score":7,"yds":"5.0","french":"1b+","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+","brazilian_crux":"I"},{"score":8,"yds":"5.0","french":"1c","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+","brazilian_crux":"Isup"},{"score":9,"yds":"5.0","french":"1c","uiaa":"1","ewbank":"2","saxon":"1","norwegian":"1+","brazilian_crux":"Isup"},{"score":10,"yds":"5.0","french":"1c+","uiaa":"1","ewbank":"3","saxon":"1","norwegian":"2-","brazilian_crux":"Isup"},{"score":11,"yds":"5","french":"1c+","uiaa":"1","ewbank":"4","saxon":"1","norwegian":"2-","brazilian_crux":"Isup"},{"score":12,"yds":"5.1","french":"2a","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2","brazilian_crux":"Isup"},{"score":13,"yds":"5.1","french":"2a","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2","brazilian_crux":"Isup"},{"score":14,"yds":"5.1","french":"2a+","uiaa":"2","ewbank":"5","saxon":"2","norwegian":"2","brazilian_crux":"II"},{"score":15,"yds":"5.1","french":"2a+","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2","brazilian_crux":"II"},{"score":16,"yds":"5.1","french":"2b","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2+","brazilian_crux":"II"},{"score":17,"yds":"5.1","french":"2b","uiaa":"2","ewbank":"6","saxon":"2","norwegian":"2+","brazilian_crux":"II"},{"score":18,"yds":"5.2","french":"2b+","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"2+","brazilian_crux":"II"},{"score":19,"yds":"5.2","french":"2b+","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"2+","brazilian_crux":"II"},{"score":20,"yds":"5.2","french":"2c","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"3-","brazilian_crux":"II"},{"score":21,"yds":"5.2","french":"2c","uiaa":"2","ewbank":"7","saxon":"2","norwegian":"3-","brazilian_crux":"II"},{"score":22,"yds":"5.3","french":"2c+","uiaa":"2","ewbank":"8","saxon":"2","norwegian":"3","brazilian_crux":"IIsup"},{"score":23,"yds":"5.3","french":"2c+","uiaa":"2","ewbank":"8","saxon":"2","norwegian":"3","brazilian_crux":"IIsup"},{"score":24,"yds":"5.3","french":"3a","uiaa":"3","ewbank":"9","saxon":"3","norwegian":"3","brazilian_crux":"IIsup"},{"score":25,"yds":"5.3","french":"3a","uiaa":"3","ewbank":"9","saxon":"3","norwegian":"3","brazilian_crux":"IIsup"},{"score":26,"yds":"5.4","french":"3a+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+","brazilian_crux":"IIsup"},{"score":27,"yds":"5.4","french":"3a+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+","brazilian_crux":"IIsup"},{"score":28,"yds":"5.4","french":"3b","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+","brazilian_crux":"III"},{"score":29,"yds":"5.4","french":"3b","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"3+","brazilian_crux":"III"},{"score":30,"yds":"5.4","french":"3b+","uiaa":"3","ewbank":"10","saxon":"3","norwegian":"4-","brazilian_crux":"III"},{"score":31,"yds":"5.5","french":"3b+","uiaa":"3","ewbank":"11","saxon":"3","norwegian":"4-","brazilian_crux":"III"},{"score":32,"yds":"5.5","french":"3c","uiaa":"3","ewbank":"11","saxon":"3","norwegian":"4","brazilian_crux":"III"},{"score":33,"yds":"5.5","french":"3c","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4","brazilian_crux":"III"},{"score":34,"yds":"5.5","french":"3c+","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4","brazilian_crux":"III"},{"score":35,"yds":"5.5","french":"3c+","uiaa":"3","ewbank":"12","saxon":"3","norwegian":"4","brazilian_crux":"III"},{"score":36,"yds":"5.6","french":"4a","uiaa":"4","ewbank":"13","saxon":"4","norwegian":"4+","brazilian_crux":"IIIsup"},{"score":37,"yds":"5.6","french":"4a","uiaa":"4","ewbank":"13","saxon":"4","norwegian":"4+","brazilian_crux":"IIIsup"},{"score":38,"yds":"5.6","french":"4a+","uiaa":"4+","ewbank":"13","saxon":"4","norwegian":"4+","brazilian_crux":"IIIsup"},{"score":39,"yds":"5.6","french":"4a+","uiaa":"4+","ewbank":"13","saxon":"4","norwegian":"4+","brazilian_crux":"IIIsup"},{"score":40,"yds":"5.6","french":"4b","uiaa":"4+","ewbank":"13","saxon":"5","norwegian":"5-","brazilian_crux":"IIIsup"},{"score":41,"yds":"5.7","french":"4b","uiaa":"4+","ewbank":"14","saxon":"5","norwegian":"5-","brazilian_crux":"IIIsup"},{"score":42,"yds":"5.7","french":"4b+","uiaa":"5-","ewbank":"14","saxon":"5","norwegian":"5-","brazilian_crux":"IV"},{"score":43,"yds":"5.7","french":"4b+","uiaa":"5-","ewbank":"14","saxon":"5","norwegian":"5-","brazilian_crux":"IV"},{"score":44,"yds":"5.7","french":"4c","uiaa":"5-","ewbank":"15","saxon":"5","norwegian":"5","brazilian_crux":"IV"},{"score":45,"yds":"5.7","french":"4c","uiaa":"5-","ewbank":"15","saxon":"5","norwegian":"5","brazilian_crux":"IV"},{"score":46,"yds":"5.8","french":"4c+","uiaa":"5","ewbank":"16","saxon":"6","norwegian":"5","brazilian_crux":"IV"},{"score":47,"yds":"5.8","french":"4c+","uiaa":"5","ewbank":"16","saxon":"6","norwegian":"5","brazilian_crux":"IV"},{"score":48,"yds":"5.8","french":"5a","uiaa":"5","ewbank":"16","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":49,"yds":"5.8","french":"5a","uiaa":"5","ewbank":"16","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":50,"yds":"5.8","french":"5a+","uiaa":"5+","ewbank":"16","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":51,"yds":"5.8","french":"5a+","uiaa":"5+","ewbank":"16","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":52,"yds":"5.9","french":"5b","uiaa":"5+","ewbank":"17","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":53,"yds":"5.9","french":"5b","uiaa":"5+","ewbank":"17","saxon":"7a","norwegian":"5+","brazilian_crux":"IVsup"},{"score":54,"yds":"5.9","french":"5b+","uiaa":"6-","ewbank":"17","saxon":"7b","norwegian":"5+","brazilian_crux":"IVsup"},{"score":55,"yds":"5.9","french":"5b+","uiaa":"6-","ewbank":"17","saxon":"7b","norwegian":"5+","brazilian_crux":"IVsup"},{"score":56,"yds":"5.9","french":"5c","uiaa":"6","ewbank":"17","saxon":"7b","norwegian":"6-","brazilian_crux":"V"},{"score":57,"yds":"5.10a","french":"5c","uiaa":"6","ewbank":"18","saxon":"7b","norwegian":"6-","brazilian_crux":"V"},{"score":58,"yds":"5.10a","french":"5c+","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-","brazilian_crux":"V"},{"score":59,"yds":"5.10a","french":"5c+","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-","brazilian_crux":"V"},{"score":60,"yds":"5.10a","french":"6a","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-","brazilian_crux":"V"},{"score":61,"yds":"5.10a","french":"6a","uiaa":"6+","ewbank":"18","saxon":"7c","norwegian":"6-","brazilian_crux":"V"},{"score":62,"yds":"5.10b","french":"6a+","uiaa":"7-","ewbank":"19","saxon":"8a","norwegian":"6","brazilian_crux":"Vsup"},{"score":63,"yds":"5.10b","french":"6a+","uiaa":"7-","ewbank":"19","saxon":"8a","norwegian":"6","brazilian_crux":"Vsup"},{"score":64,"yds":"5.10c","french":"6b","uiaa":"7","ewbank":"20","saxon":"8b","norwegian":"6","brazilian_crux":"VI"},{"score":65,"yds":"5.10c","french":"6b","uiaa":"7","ewbank":"20","saxon":"8b","norwegian":"6","brazilian_crux":"VI"},{"score":66,"yds":"5.10d","french":"6b+","uiaa":"7+","ewbank":"20","saxon":"8c","norwegian":"6+","brazilian_crux":"VIsup"},{"score":67,"yds":"5.11a","french":"6b+","uiaa":"7+","ewbank":"21","saxon":"8c","norwegian":"6+","brazilian_crux":"VIsup"},{"score":68,"yds":"5.11a","french":"6c","uiaa":"7+/8-","ewbank":"21","saxon":"9a","norwegian":"7-","brazilian_crux":"VIIa"},{"score":69,"yds":"5.11b","french":"6c","uiaa":"7+/8-","ewbank":"22","saxon":"9a","norwegian":"7-","brazilian_crux":"VIIa"},{"score":70,"yds":"5.11b","french":"6c+","uiaa":"8-","ewbank":"22","saxon":"9a","norwegian":"7","brazilian_crux":"VIIb"},{"score":71,"yds":"5.11c","french":"6c+","uiaa":"8-","ewbank":"23","saxon":"9a","norwegian":"7","brazilian_crux":"VIIb"},{"score":72,"yds":"5.11c","french":"7a","uiaa":"8","ewbank":"23","saxon":"9b","norwegian":"7+","brazilian_crux":"VIIc"},{"score":73,"yds":"5.11d","french":"7a","uiaa":"8","ewbank":"23","saxon":"9b","norwegian":"7+","brazilian_crux":"VIIc"},{"score":74,"yds":"5.11d","french":"7a+","uiaa":"8+","ewbank":"24","saxon":"9c","norwegian":"8-","brazilian_crux":"VIIIa"},{"score":75,"yds":"5.12a","french":"7a+","uiaa":"8+","ewbank":"24","saxon":"9c","norwegian":"8-","brazilian_crux":"VIIIa"},{"score":76,"yds":"5.12b","french":"7b","uiaa":"8+/9-","ewbank":"25","saxon":"10a","norwegian":"8-","brazilian_crux":"VIIIb"},{"score":77,"yds":"5.12b","french":"7b","uiaa":"8+/9-","ewbank":"25","saxon":"10a","norwegian":"8-","brazilian_crux":"VIIIb"},{"score":78,"yds":"5.12c","french":"7b+","uiaa":"9-","ewbank":"26","saxon":"10a","norwegian":"8","brazilian_crux":"VIIIc"},{"score":79,"yds":"5.12c","french":"7b+","uiaa":"9-","ewbank":"26","saxon":"10a","norwegian":"8","brazilian_crux":"VIIIc"},{"score":80,"yds":"5.12d","french":"7c","uiaa":"9","ewbank":"27","saxon":"10b","norwegian":"8+","brazilian_crux":"IXa"},{"score":81,"yds":"5.12d","french":"7c","uiaa":"9","ewbank":"27","saxon":"10b","norwegian":"8+","brazilian_crux":"IXa"},{"score":82,"yds":"5.13a","french":"7c+","uiaa":"9+","ewbank":"28","saxon":"10c","norwegian":"8+","brazilian_crux":"IXb"},{"score":83,"yds":"5.13a","french":"7c+","uiaa":"9+","ewbank":"28","saxon":"10c","norwegian":"8+","brazilian_crux":"IXb"},{"score":84,"yds":"5.13b","french":"8a","uiaa":"10-","ewbank":"29","saxon":"10c","norwegian":"9-","brazilian_crux":"IXc"},{"score":85,"yds":"5.13b","french":"8a","uiaa":"10-","ewbank":"29","saxon":"10c","norwegian":"9-","brazilian_crux":"IXc"},{"score":86,"yds":"5.13c","french":"8a+","uiaa":"10","ewbank":"30","saxon":"11b","norwegian":"9-","brazilian_crux":"Xa"},{"score":87,"yds":"5.13c","french":"8a+","uiaa":"10","ewbank":"30","saxon":"11b","norwegian":"9-","brazilian_crux":"Xa"},{"score":88,"yds":"5.13d","french":"8b","uiaa":"10+","ewbank":"31","saxon":"11c","norwegian":"9","brazilian_crux":"Xb"},{"score":89,"yds":"5.13d","french":"8b","uiaa":"10+","ewbank":"31","saxon":"11c","norwegian":"9","brazilian_crux":"Xb"},{"score":90,"yds":"5.14a","french":"8b+","uiaa":"10+/11-","ewbank":"32","saxon":"11c","norwegian":"9+","brazilian_crux":"Xc"},{"score":91,"yds":"5.14a","french":"8b+","uiaa":"10+/11-","ewbank":"32","saxon":"11c","norwegian":"9+","brazilian_crux":"Xc"},{"score":92,"yds":"5.14b","french":"8c","uiaa":"11-","ewbank":"33","saxon":"12a","norwegian":"9+","brazilian_crux":"XIa"},{"score":93,"yds":"5.14b","french":"8c","uiaa":"11-","ewbank":"33","saxon":"12a","norwegian":"9+","brazilian_crux":"XIa"},{"score":94,"yds":"5.14c","french":"8c+","uiaa":"11","ewbank":"34","saxon":"12b","norwegian":"10-","brazilian_crux":"XIb"},{"score":95,"yds":"5.14c","french":"8c+","uiaa":"11","ewbank":"34","saxon":"12b","norwegian":"10-","brazilian_crux":"XIb"},{"score":96,"yds":"5.14d","french":"9a","uiaa":"11","ewbank":"35","saxon":"12c","norwegian":"10","brazilian_crux":"XIc"},{"score":97,"yds":"5.14d","french":"9a","uiaa":"11","ewbank":"35","saxon":"12c","norwegian":"10","brazilian_crux":"XIc"},{"score":98,"yds":"5.15a","french":"9a+","uiaa":"11/11+","ewbank":"36","saxon":"13a","norwegian":"10+","brazilian_crux":"XIIa"},{"score":99,"yds":"5.15a","french":"9a+","uiaa":"11/11+","ewbank":"36","saxon":"13a","norwegian":"10+","brazilian_crux":"XIIa"},{"score":100,"yds":"5.15b","french":"9b","uiaa":"11+","ewbank":"37","saxon":"13b","norwegian":"10+","brazilian_crux":"XIIb"},{"score":101,"yds":"5.15b","french":"9b","uiaa":"11+","ewbank":"37","saxon":"13b","norwegian":"10+","brazilian_crux":"XIIb"},{"score":102,"yds":"5.15c","french":"9b+","uiaa":"11+/12-","ewbank":"38","saxon":"13b","norwegian":"11-","brazilian_crux":"XIIc"},{"score":103,"yds":"5.15c","french":"9b+","uiaa":"11+/12-","ewbank":"38","saxon":"13b","norwegian":"11-","brazilian_crux":"XIIc"},{"score":104,"yds":"5.15d","french":"9c","uiaa":"12-","ewbank":"39","saxon":"13c","norwegian":"11","brazilian_crux":"XIIIa"},{"score":105,"yds":"5.15d","french":"9c","uiaa":"12-","ewbank":"39","saxon":"13c","norwegian":"11","brazilian_crux":"XIIIb"},{"score":106,"yds":"5.16a","french":"9c+","uiaa":"12","ewbank":"40","saxon":"13c","norwegian":"11+","brazilian_crux":"XIIIc"},{"score":107,"yds":"5.16a","french":"9c+","uiaa":"12","ewbank":"40","saxon":"13c","norwegian":"11+","brazilian_crux":"XIVa"}] \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 83b25c8..a900ae2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import { convertGrade } from './GradeParser' import { GradeBands, GradeBandTypes } from './GradeBands' -import { AI, Aid, Ewbank, Font, French, Norwegian, Saxon, UIAA, VScale, WI, YosemiteDecimal } from './scales' +import { AI, Aid, Ewbank, Font, French, Norwegian, Saxon, UIAA, VScale, WI, YosemiteDecimal, BrazilianCrux } from './scales' // Free Climbing Grades // YDS @@ -268,7 +268,6 @@ export const protection = ['G', 'PG', 'PG13', 'R', 'X'] // Bouldering // Hueco // Fontainebleau -// Brazilian export const freeClimbing = { clean: { @@ -280,7 +279,8 @@ export const freeClimbing = { UIAA: UIAA_ARRAY, Ewbank: EWBANK_ARRAY, Saxon: SAXON_ARRAY, - Norwegian: NORWAY_ARRAY + Norwegian: NORWAY_ARRAY, + BrazilianCrux: BrazilianCrux.grades }, community: {} } @@ -311,5 +311,6 @@ export { UIAA, VScale, WI, - YosemiteDecimal + YosemiteDecimal, + BrazilianCrux } diff --git a/src/scales/brazilian.ts b/src/scales/brazilian.ts new file mode 100644 index 0000000..0b6d391 --- /dev/null +++ b/src/scales/brazilian.ts @@ -0,0 +1,98 @@ +import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple, getRoundedScoreTuple } from '../GradeScale' +import routes from '../data/routes.json' +import { Route } from '.' +import { GradeBandTypes, routeScoreToBand } from '../GradeBands' + +const BRAZILIAN_ARRAY = Array.from(new Set(routes.map((r) => r[GradeScales.BRAZILIAN_CRUX]))) + +const brazilianGradeRegex = /^((((I|II|III|IV|V|VI)(sup)?)|(VII|VIII|IX|X|XI|XII|XIII|XIV)(a|b|c))(\/(a|b|c))?)((\/(((I|II|III|IV|V|VI)(sup)?)|(VII|VIII|IX|X|XI|XII|XIII|XIV)(a|b|c))))?$/i +const isBrazilianCrux = (grade: string): RegExpMatchArray | null => grade.match(brazilianGradeRegex) + +const isABC = (s: string): boolean => s[0] === 'a' || s[0] === 'b' || s[0] === 'c' +const getFullSlashGrade = (grade): string | null => { + const brokenGrade: string[] = grade.split('/') + const baseGrade: string = brokenGrade[0] + const slash: string | undefined = brokenGrade[1] + if (slash !== undefined) { + if (isABC(slash[0])) { + return baseGrade.replace(/a|b|c/i, slash[0]) + } + return slash + } + return null +} + +const getNextScore = (s): string | null => BRAZILIAN_ARRAY[BRAZILIAN_ARRAY.indexOf(s) + 1] + +const getScore = (grade: string): number | Tuple => { + const parse = isBrazilianCrux(grade) + if (parse === null) { + console.warn(`Unexpected grade format: ${grade} for grade scale BrazilianCrux`) + return -1 + } + + const wholeMatch = parse[0] + const basicGrade = parse[2] + const slashGrade = getFullSlashGrade(wholeMatch) + + const basicScore = findScoreRange((r: Route) => r[GradeScales.BRAZILIAN_CRUX] === basicGrade, routes) + + if (slashGrade !== null && getNextScore(basicGrade) !== slashGrade) { + console.warn(`Unexpected grade slash not subsequent: ${slashGrade}`) + return -1 + } + + if (wholeMatch !== basicGrade) { + // VIIa/b + let otherGrade + if (slashGrade !== null) { + otherGrade = (typeof basicScore === 'number' ? basicScore : basicScore[1]) + 1 + } + + if (otherGrade !== undefined) { + const nextGrade = findScoreRange( + (r: Route) => r[GradeScales.BRAZILIAN_CRUX] === routes[otherGrade][GradeScales.BRAZILIAN_CRUX], + routes + ) + const basicAvg = getAvgScore(basicScore) + const nextGradeAvg = getAvgScore(nextGrade) + const tuple = getRoundedScoreTuple(basicAvg, nextGradeAvg) + return tuple + } + } + return basicScore +} + +// current spec document for brazilian grade: +// https://www.cap.com.br/post/sistema-brasileiro-de-gradua%C3%A7%C3%A3o-de-vias-de-escalada +// alt mirror: https://web.archive.org/web/20220125022634/https://www.cap.com.br/post/sistema-brasileiro-de-gradua%C3%A7%C3%A3o-de-vias-de-escalada +const BrazilianCrux: GradeScale = { + grades: BRAZILIAN_ARRAY, + displayName: 'Brazilian Crux Scale', + name: GradeScales.BRAZILIAN_CRUX, + offset: 1000, + allowableConversionType: [GradeScales.YDS, GradeScales.SAXON, GradeScales.EWBANK, GradeScales.FRENCH, GradeScales.NORWEGIAN], + isType: (grade: string): boolean => isBrazilianCrux(grade) !== null, + getScore, + getGrade: (score: number | Tuple): string => { + const validateScore = (score: number): number => { + const validScore = Number.isInteger(score) ? score : Math.ceil(score) + return Math.min(Math.max(0, validScore), routes.length - 1) + } + + if (typeof score === 'number') { + return routes[validateScore(score)][GradeScales.BRAZILIAN_CRUX] + } + + const low: string = routes[validateScore(score[0])][GradeScales.BRAZILIAN_CRUX] + const high: string = routes[validateScore(score[1])][GradeScales.BRAZILIAN_CRUX] + if (low === high) return low + return `${low}/${high}` + }, + getGradeBand: (grade: string): GradeBandTypes => { + const score = getScore(grade) + return routeScoreToBand(getAvgScore(score)) + } +} + +export default BrazilianCrux diff --git a/src/scales/index.ts b/src/scales/index.ts index 6c7944b..7197fed 100644 --- a/src/scales/index.ts +++ b/src/scales/index.ts @@ -8,9 +8,10 @@ import Norwegian from './norwegian' import AI from './ai' import Aid from './aid' import WI from './wi' +import BrazilianCrux from './brazilian' import UIAA from './uiaa' import GradeScale, { GradeScales } from '../GradeScale' -export { Aid, VScale, Font, YosemiteDecimal, French, Saxon, UIAA, Ewbank, AI, WI, Norwegian } +export { Aid, VScale, Font, YosemiteDecimal, French, Saxon, UIAA, Ewbank, AI, WI, Norwegian, BrazilianCrux } export interface Boulder { score: number @@ -26,6 +27,7 @@ export interface Route { ewbank: string saxon: string norwegian: string + brazilian: string } export interface IceGrade { @@ -51,6 +53,7 @@ GradeScale | null [GradeScales.EWBANK]: Ewbank, [GradeScales.SAXON]: Saxon, [GradeScales.NORWEGIAN]: Norwegian, + [GradeScales.BRAZILIAN_CRUX]: BrazilianCrux, [GradeScales.AI]: AI, [GradeScales.WI]: WI, [GradeScales.AID]: Aid