<head>
<link rel="icon" href="data:,">
<script type="module">
- try {
- let NanoPow, stats
try {
- ({ NanoPow, stats } = await import('../dist/main.min.js'))
- } catch (err) {
- console.warn(err)
+ let NanoPow, stats
try {
- ({ NanoPow, stats } = await import('https://unpkg.com/nano-pow@5.1/dist/main.min.js'))
+ ({ NanoPow, stats } = await import('../dist/main.min.js'))
} catch (err) {
console.warn(err)
try {
- ({ NanoPow, stats } = await import('https://cdn.jsdelivr.net/npm/nano-pow@5.1/dist/main.min.js'))
+ ({ NanoPow, stats } = await import('https://unpkg.com/nano-pow@5.1/dist/main.min.js'))
} catch (err) {
- throw new Error(`Failed to load NanoPow ${err}`)
+ console.warn(err)
+ try {
+ ({ NanoPow, stats } = await import('https://cdn.jsdelivr.net/npm/nano-pow@5.1/dist/main.min.js'))
+ } catch (err) {
+ throw new Error(`Failed to load NanoPow ${err}`)
+ }
}
}
- }
- const glSize = (canvas => {
- const gl = canvas.getContext('webgl2')
- const MAX_VIEWPORT_DIMS = gl.getParameter(gl.MAX_VIEWPORT_DIMS)
- canvas.height = MAX_VIEWPORT_DIMS?.[0] ?? 0x1000
- canvas.width = MAX_VIEWPORT_DIMS?.[1] ?? 0x1000
- return Math.min(gl.drawingBufferHeight, gl.drawingBufferWidth)
- })(new OffscreenCanvas(0, 0))
+ let isContextLost = 0
+ const glSize = (canvas => {
+ canvas.addEventListener('webglcontextlost', ev => {
+ // Set up 10s timeout to prevent long-running restoration
+ isContextLost = window.setTimeout(() => {
+ throw new Error('NanoPow could not restore WebGL context.')
+ }, 10_000)
+ ev.preventDefault()
+ console.log('NanoPow test page glSize', 'WebGL context lost.')
+ })
+ canvas.addEventListener('webglcontextrestored', ev => {
+ window.clearTimeout(isContextLost)
+ isContextLost = 0
+ console.log('NanoPow test page glSize', 'WebGL context restored.')
+ })
+ const gl = canvas.getContext('webgl2')
+ const MAX_VIEWPORT_DIMS = gl.getParameter(gl.MAX_VIEWPORT_DIMS)
+ canvas.height = MAX_VIEWPORT_DIMS?.[0] ?? 0x1000
+ canvas.width = MAX_VIEWPORT_DIMS?.[1] ?? 0x1000
+ return Math.min(gl.drawingBufferHeight, gl.drawingBufferWidth)
+ })(document.createElement('canvas'))
- function random (size = 64) {
- let hex = ''
- while (hex.length < size) {
- hex += crypto.randomUUID().replace(/-.*-/g, '')
+ function random(size = 64) {
+ let hex = ''
+ while (hex.length < size) {
+ hex += crypto.randomUUID().replace(/-.*-/g, '')
+ }
+ return hex.slice(0, size)
}
- return hex.slice(0, size)
- }
- function average (times, type, effort) {
- const averages = stats(times)
- const title = type === 'WebGPU'
- ? `NanoPow (${type}) | Effort: ${effort} | Dispatch: ${(0x100 * effort) ** 2} | Threads: ${64 * (0x100 * effort) ** 2}`
- : type === 'WebGL'
- ? `NanoPow (${type}) | Effort: ${effort} | Work per frame: ${Math.min(0x100 * effort, glSize) ** 2}`
- : `NanoPow (${type}) | Effort: ${effort}`
- return {
- [title]: averages
+ function average(times, type, effort) {
+ const averages = stats(times)
+ const title = type === 'WebGPU'
+ ? `NanoPow (${type}) | Effort: ${effort} | Dispatch: ${(0x100 * effort) ** 2} | Threads: ${64 * (0x100 * effort) ** 2}`
+ : type === 'WebGL'
+ ? `NanoPow (${type}) | Effort: ${effort} | Work per frame: ${Math.min(0x100 * effort, glSize) ** 2}`
+ : `NanoPow (${type}) | Effort: ${effort}`
+ return {
+ [title]: averages
+ }
}
- }
- async function run (size, difficulty, effort, api, isOutputShown, isDebug, isSelfCheck) {
- // Generate once on load to compile shaders and initialize buffers
- await NanoPow.work_generate(random(), { api, difficulty: 0 })
- const type = api
- api = type.toLowerCase()
- if (isSelfCheck) {
- document.getElementById('status').innerHTML = `RUNNING SELF-CHECK`
- console.log(`%cNanoPow`, 'color:green', 'Checking validation against known values')
+ async function run(size, difficulty, effort, api, isOutputShown, isDebug, isSelfCheck) {
+ // Generate once on load to compile shaders and initialize buffers
+ await NanoPow.work_generate(random(), { api, difficulty: 0 })
+ const type = api
+ api = type.toLowerCase()
+ if (isSelfCheck) {
+ document.getElementById('status').innerHTML = `RUNNING SELF-CHECK`
+ console.log(`%cNanoPow`, 'color:green', 'Checking validation against known values')
- const expect = []
- let result
+ const expect = []
+ let result
- // PASS
- result = await NanoPow.work_validate('47c83266398728cf', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '1'
- console.log(`work_validate() output for good nonce 1 is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ // PASS
+ result = await NanoPow.work_validate('47c83266398728cf', '92BA74A7D6DC7557F3EDA95ADC6341D51AC777A0A6FF0688A5C492AB2B2CB40D', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '1'
+ console.log(`work_validate() output for good nonce 1 is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('4a8fb104eebbd336', '8797585D56B8AEA3A62899C31FC088F9BE849BA8298A88E94F6E3112D4E55D01', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '1'
- console.log(`work_validate() output for good nonce 2 is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('4a8fb104eebbd336', '8797585D56B8AEA3A62899C31FC088F9BE849BA8298A88E94F6E3112D4E55D01', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '1'
+ console.log(`work_validate() output for good nonce 2 is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('c5d5d6f7c5d6ccd1', '281E89AC73B1082B464B9C3C1168384F846D39F6DF25105F8B4A22915E999117', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '1'
- console.log(`work_validate() output for colliding nonce is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('c5d5d6f7c5d6ccd1', '281E89AC73B1082B464B9C3C1168384F846D39F6DF25105F8B4A22915E999117', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '1'
+ console.log(`work_validate() output for colliding nonce is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('6866c1ac3831a891', '7069D9CD1E85D6204301D254B0927F06ACC794C9EA5DF70EA5578458FB597090', { api, difficulty: 0xfffffe0000000000n, debug: isDebug })
- console.log(result)
- result = result.valid === '1' && result.valid_all === '0' && result.valid_receive === '1'
- console.log(`work_validate() output for good receive difficulty nonce is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('6866c1ac3831a891', '7069D9CD1E85D6204301D254B0927F06ACC794C9EA5DF70EA5578458FB597090', { api, difficulty: 0xfffffe0000000000n, debug: isDebug })
+ console.log(result)
+ result = result.valid === '1' && result.valid_all === '0' && result.valid_receive === '1'
+ console.log(`work_validate() output for good receive difficulty nonce is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- // XFAIL
- result = await NanoPow.work_validate('0000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '0'
- console.log(`work_validate() output for bad nonce 1 is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ // XFAIL
+ result = await NanoPow.work_validate('0000000000000000', '0000000000000000000000000000000000000000000000000000000000000000', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '0'
+ console.log(`work_validate() output for bad nonce 1 is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('c5d5d6f7c5d6ccd1', 'BA1E946BA3D778C2F30A83D44D2132CC6EEF010D8D06FF10A8ABD0100D8FB47E', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '0'
- console.log(`work_validate() output for bad nonce 2 is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('c5d5d6f7c5d6ccd1', 'BA1E946BA3D778C2F30A83D44D2132CC6EEF010D8D06FF10A8ABD0100D8FB47E', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '0'
+ console.log(`work_validate() output for bad nonce 2 is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('ae238556213c3624', 'BF41D87DA3057FDC6050D2B00C06531F89F4AA6195D7C6C2EAAF15B6E703F8F6', { api, difficulty: 0xfffffff800000001n, debug: isDebug })
- console.log(result)
- result = result.error === 'Invalid difficulty fffffff800000001'
- console.log(`work_validate() output for bad difficulty beyond max is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('ae238556213c3624', 'BF41D87DA3057FDC6050D2B00C06531F89F4AA6195D7C6C2EAAF15B6E703F8F6', { api, difficulty: 0xfffffff800000001n, debug: isDebug })
+ console.log(result)
+ result = result.error === 'Invalid difficulty fffffff800000001'
+ console.log(`work_validate() output for bad difficulty beyond max is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('29a9ae0236990e2e', '32721F4BD2AFB6F6A08D41CD0DF3C0D9C0B5294F68D0D12422F52B28F0800B5F', { api, debug: isDebug })
- console.log(result)
- result = result.valid_all === '0'
- console.log(`work_validate() output for slightly wrong nonce is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('29a9ae0236990e2e', '32721F4BD2AFB6F6A08D41CD0DF3C0D9C0B5294F68D0D12422F52B28F0800B5F', { api, debug: isDebug })
+ console.log(result)
+ result = result.valid_all === '0'
+ console.log(`work_validate() output for slightly wrong nonce is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
- result = await NanoPow.work_validate('7d903b18d03f9820', '39C57C28F904DFE4012288FFF64CE80C0F42601023A9C82108E8F7B2D186C150', { api, difficulty: 0xfffffe0000000000n, debug: isDebug })
- console.log(result)
- result = result.valid === '0' && result.valid_all === '0' && result.valid_receive === '0'
- console.log(`work_validate() output for bad receive difficulty nonce is ${result === true ? 'correct' : 'incorrect'}`)
- expect.push(result)
+ result = await NanoPow.work_validate('7d903b18d03f9820', '39C57C28F904DFE4012288FFF64CE80C0F42601023A9C82108E8F7B2D186C150', { api, difficulty: 0xfffffe0000000000n, debug: isDebug })
+ console.log(result)
+ result = result.valid === '0' && result.valid_all === '0' && result.valid_receive === '0'
+ console.log(`work_validate() output for bad receive difficulty nonce is ${result === true ? 'correct' : 'incorrect'}`)
+ expect.push(result)
+
+ const prefixes = [
+ '0B1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
+ '0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
+ '0O17777777777777777777777777777777777777777777777777777777777777777777777777777777777777',
+ '0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777777',
+ '0Xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
+ '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
+ ' 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn ',
+ ' ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn ',
+ ]
+ for (let i = 0; i < prefixes.length; i++) {
+ const hash = prefixes[i]
+ let result = null
+ const start = performance.now()
+ try {
+ result = await NanoPow.work_generate(hash, { api, difficulty, effort, debug: isDebug })
+ console.log(result)
+ } catch (err) {
+ document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
+ console.error(err)
+ return
+ }
+ const end = performance.now()
+ const check = await NanoPow.work_validate(result.work, result.hash, { difficulty, debug: isDebug })
+ const isValid = (check.valid === '1' && BigInt(`0x${result.hash}`) === BigInt(hash.replace('n', '').replace(' f', '0xf')))
+ console.log(`work_generate() output for max value block hash is ${isValid === true ? 'correct' : 'incorrect'}`)
+ expect.push(isValid)
+ }
- const prefixes = [
- '0B1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
- '0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
- '0O17777777777777777777777777777777777777777777777777777777777777777777777777777777777777',
- '0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777777',
- '0Xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
- '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
- ' 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn ',
- ' ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn ',
- ]
- for (let i = 0; i < prefixes.length; i++) {
- const hash = prefixes[i]
- let result = null
- const start = performance.now()
try {
- result = await NanoPow.work_generate(hash, { api, difficulty, effort, debug: isDebug })
- console.log(result)
+ if (!expect.every(result => result)) throw new Error(`Validation is not working`)
} catch (err) {
+ document.getElementById('status').innerHTML = `FAILED TO VALIDATE KNOWN VALUES`
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
console.error(err)
return
}
- const end = performance.now()
- const check = await NanoPow.work_validate(result.work, result.hash, { difficulty, debug: isDebug })
- const isValid = (check.valid === '1' && BigInt(`0x${result.hash}`) === BigInt(hash.replace('n', '').replace(' f', '0xf')))
- console.log(`work_generate() output for max value block hash is ${isValid === true ? 'correct' : 'incorrect'}`)
- expect.push(isValid)
}
- try {
- if (!expect.every(result => result)) throw new Error(`Validation is not working`)
- } catch (err) {
- document.getElementById('status').innerHTML = `FAILED TO VALIDATE KNOWN VALUES`
- document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
- console.error(err)
- return
- }
- }
-
- document.getElementById('status').innerHTML = `TESTING IN PROGRESS 0/${size}`
- console.log(`%cNanoPow (${type})`, 'color:green', `Calculate proof-of-work for ${size} unique send block hashes`)
- const times = []
- for (let i = 0; i < size; i++) {
- document.getElementById('status').innerHTML = `TESTING IN PROGRESS ${i}/${size}<br/>`
- const hash = random()
- let result = null
- const start = performance.now()
- try {
- result = await NanoPow.work_generate(hash, { api, difficulty, effort, debug: isDebug })
- } catch (err) {
- document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
- console.error(err)
- return
- }
- const end = performance.now()
- const check = await NanoPow.work_validate(result.work, result.hash, { difficulty, debug: isDebug })
- const isValid = (result.hash === hash && check.valid === '1') ? 'VALID' : 'INVALID'
- times.push(end - start)
- const msg = `${isValid} (${end - start} ms)\n${JSON.stringify(result, ' ', 2)}`
- if (isOutputShown) document.getElementById('output').innerHTML += `${msg}<br/>`
- }
- document.getElementById('output').innerHTML += `<hr/>`
- document.getElementById('summary').innerHTML += `${JSON.stringify(average(times, type, effort), null, '\t')}<br/>`
- document.getElementById('status').innerHTML = `TESTING COMPLETE<br/>`
- console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
- }
-
- async function score (runs, size, difficulty, effort, api) {
- console.log(`%cNanoPow ${api}`, 'color:green', `Calculate truncated harmonic mean of the truncated arithmetic rate across ${runs} runs of ${size} samples.`)
- const rates = []
- for (let i = 0; i < runs; i++) {
+ document.getElementById('status').innerHTML = `TESTING IN PROGRESS 0/${size}`
+ console.log(`%cNanoPow (${type})`, 'color:green', `Calculate proof-of-work for ${size} unique send block hashes`)
const times = []
- for (let j = 0; j < size; j++) {
- document.getElementById('status').innerHTML = `SCORING IN PROGRESS. THIS WILL TAKE A LONG TIME. ${i}/${size} ${j}/${runs}<br/>`
+ for (let i = 0; i < size; i++) {
+ document.getElementById('status').innerHTML = `TESTING IN PROGRESS ${i}/${size}<br/>`
const hash = random()
let result = null
const start = performance.now()
try {
- result = await NanoPow.work_generate(hash, { difficulty, effort, api })
+ result = await NanoPow.work_generate(hash, { api, difficulty, effort, debug: isDebug })
} catch (err) {
document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
console.error(err)
return
}
- times.push(performance.now() - start)
+ const end = performance.now()
+ const check = await NanoPow.work_validate(result.work, result.hash, { difficulty, debug: isDebug })
+ const isValid = (result.hash === hash && check.valid === '1') ? 'VALID' : 'INVALID'
+ times.push(end - start)
+ const msg = `${isValid} (${end - start} ms)\n${JSON.stringify(result, ' ', 2)}`
+ if (isOutputShown) document.getElementById('output').innerHTML += `${msg}<br/>`
}
- const results = Object.values(average(times))[0]
- const { truncatedRate } = results
- rates.push(truncatedRate)
- document.getElementById('output').innerHTML += `Benchmark ${i + 1} score: ${truncatedRate} wps<br/>`
+ document.getElementById('output').innerHTML += `<hr/>`
+ document.getElementById('summary').innerHTML += `${JSON.stringify(average(times, type, effort), null, '\t')}<br/>`
+ document.getElementById('status').innerHTML = `TESTING COMPLETE<br/>`
+ console.log('%cTESTING COMPLETE', 'color:orange;font-weight:bold')
}
- const results = Object.values(average(rates))[0]
- console.log(rates)
- console.log(results)
- const { truncatedHarmonic } = results
- document.getElementById('output').innerHTML += `<hr/>`
- document.getElementById('summary').innerHTML += `work-per-second: ${truncatedHarmonic}<br/>`
- document.getElementById('status').innerHTML = `SCORING COMPLETE<br/>`
- console.log('%cSCORING COMPLETE', 'color:orange;font-weight:bold')
- }
- function startValidation (event) {
- const difficulty = document.getElementById('difficulty')?.value
- const work = document.getElementById('work')?.value
- const hash = document.getElementById('hash')?.value
- const validation = document.getElementById('validation')
- const api = document.getElementById('api')?.value
- const apiContainer = document.getElementById('api')?.parentElement
- if (api === 'CPU') {
- apiContainer.classList.add('warning')
- apiContainer.title = 'Use only for testing with very low difficulty.'
- } else {
- apiContainer.classList.remove('warning')
- apiContainer.title = ''
+ async function score(runs, size, difficulty, effort, api) {
+ console.log(`%cNanoPow ${api}`, 'color:green', `Calculate truncated harmonic mean of the truncated arithmetic rate across ${runs} runs of ${size} samples.`)
+ const rates = []
+ for (let i = 0; i < runs; i++) {
+ const times = []
+ for (let j = 0; j < size; j++) {
+ document.getElementById('status').innerHTML = `SCORING IN PROGRESS. THIS WILL TAKE A LONG TIME. ${i}/${size} ${j}/${runs}<br/>`
+ const hash = random()
+ let result = null
+ const start = performance.now()
+ try {
+ result = await NanoPow.work_generate(hash, { difficulty, effort, api })
+ } catch (err) {
+ document.getElementById('output').innerHTML += `Error: ${err.message}<br/>`
+ console.error(err)
+ return
+ }
+ times.push(performance.now() - start)
+ }
+ const results = Object.values(average(times))[0]
+ const { truncatedRate } = results
+ rates.push(truncatedRate)
+ document.getElementById('output').innerHTML += `Benchmark ${i + 1} score: ${truncatedRate} wps<br/>`
+ }
+ const results = Object.values(average(rates))[0]
+ console.log(rates)
+ console.log(results)
+ const { truncatedHarmonic } = results
+ document.getElementById('output').innerHTML += `<hr/>`
+ document.getElementById('summary').innerHTML += `work-per-second: ${truncatedHarmonic}<br/>`
+ document.getElementById('status').innerHTML = `SCORING COMPLETE<br/>`
+ console.log('%cSCORING COMPLETE', 'color:orange;font-weight:bold')
}
- validation.innerText = '⏳'
- if (work.length === 16 && hash.length === 64) {
- NanoPow.work_validate(work, hash, { difficulty })
- .then(result => {
- validation.innerText = result
- ? '✔️'
- : '❌'
- })
- .catch(err => {
- validation.innerText = '⏳'
+
+ function startValidation(event) {
+ const difficulty = document.getElementById('difficulty')?.value
+ const work = document.getElementById('work')?.value
+ const hash = document.getElementById('hash')?.value
+ const validation = document.getElementById('validation')
+ const api = document.getElementById('api')?.value
+ const apiContainer = document.getElementById('api')?.parentElement
+ if (api === 'CPU') {
+ apiContainer.classList.add('warning')
+ apiContainer.title = 'Use only for testing with very low difficulty.'
+ } else {
+ apiContainer.classList.remove('warning')
+ apiContainer.title = ''
+ }
+ validation.innerText = '⏳'
+ if (work.length === 16 && hash.length === 64) {
+ NanoPow.work_validate(work, hash, { difficulty })
+ .then(result => {
+ validation.innerText = result
+ ? '✔️'
+ : '❌'
+ })
+ .catch(err => {
+ validation.innerText = '⏳'
+ })
+ }
+ }
+ document.getElementById('difficulty').addEventListener('input', startValidation)
+ document.getElementById('work').addEventListener('input', startValidation)
+ document.getElementById('hash').addEventListener('input', startValidation)
+ document.getElementById('api').addEventListener('input', startValidation)
+
+ function startTest(event) {
+ event.target.disabled = true
+ const size = document.getElementById('size')
+ const difficulty = document.getElementById('difficulty')
+ const effort = document.getElementById('effort')
+ const api = document.getElementById('api')
+ const isOutputShown = document.getElementById('isOutputShown')
+ const isDebug = document.getElementById('isDebug')
+ const isSelfCheck = document.getElementById('isSelfCheck')
+ run(+size.value, difficulty.value, +effort.value, api.value, isOutputShown.checked, isDebug.checked, isSelfCheck.checked)
+ .then(() => {
+ event.target.disabled = false
+ isSelfCheck.checked = false
})
}
- }
- document.getElementById('difficulty').addEventListener('input', startValidation)
- document.getElementById('work').addEventListener('input', startValidation)
- document.getElementById('hash').addEventListener('input', startValidation)
- document.getElementById('api').addEventListener('input', startValidation)
- function startTest (event) {
- event.target.disabled = true
- const size = document.getElementById('size')
- const difficulty = document.getElementById('difficulty')
- const effort = document.getElementById('effort')
- const api = document.getElementById('api')
- const isOutputShown = document.getElementById('isOutputShown')
- const isDebug = document.getElementById('isDebug')
- const isSelfCheck = document.getElementById('isSelfCheck')
- run(+size.value, difficulty.value, +effort.value, api.value, isOutputShown.checked, isDebug.checked, isSelfCheck.checked)
- .then(() => {
- event.target.disabled = false
- isSelfCheck.checked = false
- })
- }
+ function startScore(event) {
+ event.target.disabled = true
+ const runs = document.getElementById('runs')
+ const size = document.getElementById('size')
+ const difficulty = document.getElementById('difficulty')
+ const effort = document.getElementById('effort')
+ const api = document.getElementById('api')
+ const isOutputShown = document.getElementById('isOutputShown')
+ score(+runs.value, +size.value, difficulty.value, +effort.value, api.value)
+ .then(() => event.target.disabled = false)
+ }
- function startScore (event) {
- event.target.disabled = true
- const runs = document.getElementById('runs')
- const size = document.getElementById('size')
- const difficulty = document.getElementById('difficulty')
- const effort = document.getElementById('effort')
- const api = document.getElementById('api')
- const isOutputShown = document.getElementById('isOutputShown')
- score(+runs.value, +size.value, difficulty.value, +effort.value, api.value)
- .then(() => event.target.disabled = false)
+ document.getElementById('api_webgpu').disabled = navigator?.gpu == null
+ document.getElementById('api_webgl').selected = navigator?.gpu == null
+ document.getElementById('btnStartTest').addEventListener('click', startTest)
+ document.getElementById('btnStartScore').addEventListener('click', startScore)
+ document.getElementById('effort').value = Math.max(1, Math.floor(navigator.hardwareConcurrency) / 2)
+ } catch (err) {
+ console.error(err)
}
-
- document.getElementById('api_webgpu').disabled = navigator?.gpu == null
- document.getElementById('api_webgl').selected = navigator?.gpu == null
- document.getElementById('btnStartTest').addEventListener('click', startTest)
- document.getElementById('btnStartScore').addEventListener('click', startScore)
- document.getElementById('effort').value = Math.max(1, Math.floor(navigator.hardwareConcurrency) / 2)
- } catch (err) {
- console.error(err)
- }
</script>
<style>
body{background:black;color:white;}a{color:darkcyan;}input[type=number]{width:5em;}input[type=checkbox]{margin-right:2em;}