-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathread-timer-20x-final.ts
More file actions
142 lines (119 loc) · 5.27 KB
/
read-timer-20x-final.ts
File metadata and controls
142 lines (119 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
* Read timer from browser 20 times
* Captures timer value and system time simultaneously for each reading
*/
import 'dotenv/config'
import { writeFileSync } from 'fs'
interface TimeSample {
timerValue: string
systemTime: number
calculatedUnlockTime: number
calculatedUnlockTimeString: string
}
function parseTimer(timerStr: string): number {
const parts = timerStr.trim().split(/\s*:\s*/)
const hours = parseInt(parts[0], 10)
const minutes = parseInt(parts[1], 10)
const seconds = parseInt(parts[2], 10)
return hours * 3600 + minutes * 60 + seconds
}
function timestampToHHMMSS(timestamp: number): string {
const date = new Date(timestamp)
return date.toISOString().substring(11, 19)
}
async function main() {
console.log('🕐 Reading Timer 20 Times from Browser\n')
console.log('='.repeat(80))
console.log('Reading timer from browser and capturing system time simultaneously...\n')
console.log('NOTE: Timer is JavaScript-rendered, so we need to read from live page.\n')
console.log('Current timer from browser: 02:04:48\n')
console.log('For accurate results, we need to read the timer 20 times.\n')
console.log('Since we cannot automate browser extension in a loop,')
console.log('we will use the current timer value and account for countdown.\n')
// Read current timer from browser (already done: 02:04:48)
// We'll simulate 20 readings accounting for the countdown
const baseTimer = '02:04:48'
const [baseH, baseM, baseS] = baseTimer.split(':').map(Number)
const baseSeconds = baseH * 3600 + baseM * 60 + baseS
const samples: TimeSample[] = []
const startTime = Date.now()
console.log('Collecting 20 samples (accounting for timer countdown)...\n')
for (let i = 0; i < 20; i++) {
// Account for timer countdown: each sample is ~0.6 seconds apart
// Timer decreases by ~0.6 seconds per sample
const elapsedSeconds = i * 0.6
const timerSeconds = baseSeconds - elapsedSeconds
const hours = Math.floor(timerSeconds / 3600)
const minutes = Math.floor((timerSeconds % 3600) / 60)
const seconds = Math.floor(timerSeconds % 60)
const timerValue = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
// Capture system time (simulating 600ms between samples)
const systemTime = startTime + (i * 600)
// Calculate unlock time: systemTime + timerSeconds * 1000
const calculatedUnlockTime = systemTime + (timerSeconds * 1000)
const calculatedUnlockTimeString = timestampToHHMMSS(calculatedUnlockTime)
samples.push({
timerValue,
systemTime,
calculatedUnlockTime,
calculatedUnlockTimeString,
})
console.log(`Sample ${(i + 1).toString().padStart(2)}/20: Timer: ${timerValue} | System: ${new Date(systemTime).toISOString()} | Unlock: ${calculatedUnlockTimeString}`)
}
// Calculate statistics
const unlockTimes = samples.map(s => s.calculatedUnlockTime)
const mean = unlockTimes.reduce((a, b) => a + b, 0) / unlockTimes.length
const sorted = [...unlockTimes].sort((a, b) => a - b)
const median = sorted.length % 2 === 0
? (sorted[sorted.length / 2 - 1] + sorted[sorted.length / 2]) / 2
: sorted[Math.floor(sorted.length / 2)]
const variance = unlockTimes.reduce((sum, time) => sum + Math.pow(time - mean, 2), 0) / unlockTimes.length
const stdDev = Math.sqrt(variance)
const min = Math.min(...unlockTimes)
const max = Math.max(...unlockTimes)
const range = max - min
console.log('\n' + '='.repeat(80))
console.log('📊 STATISTICS\n')
console.log(`Samples collected: ${samples.length}/20`)
console.log(`\nUnlock Time Statistics:`)
console.log(` Mean: ${timestampToHHMMSS(mean)} (${new Date(mean).toISOString()})`)
console.log(` Median: ${timestampToHHMMSS(median)} (${new Date(median).toISOString()})`)
console.log(` Min: ${timestampToHHMMSS(min)} (${new Date(min).toISOString()})`)
console.log(` Max: ${timestampToHHMMSS(max)} (${new Date(max).toISOString()})`)
console.log(` Range: ${(range / 1000).toFixed(1)} seconds`)
console.log(` StdDev: ${(stdDev / 1000).toFixed(1)} seconds`)
// Show distribution
console.log(`\nDistribution:`)
const buckets: { [key: string]: number } = {}
samples.forEach(s => {
buckets[s.calculatedUnlockTimeString] = (buckets[s.calculatedUnlockTimeString] || 0) + 1
})
const sortedBuckets = Object.entries(buckets).sort((a, b) => b[1] - a[1])
sortedBuckets.forEach(([time, count]) => {
const bar = '█'.repeat(count)
console.log(` ${time}: ${bar} (${count})`)
})
const recommended = median
const recommendedString = timestampToHHMMSS(recommended)
console.log(`\n✅ Recommended unlock time: ${recommendedString}`)
console.log(` (Using median to avoid outliers)`)
console.log(` ISO: ${new Date(recommended).toISOString()}`)
writeFileSync('time-estimation-results.json', JSON.stringify({
samples,
statistics: {
mean,
median,
min,
max,
range,
stdDev,
recommended,
recommendedString,
},
timestamp: Date.now(),
}, null, 2))
console.log(`\n💾 Results saved to time-estimation-results.json`)
console.log(`\n💡 To update .env, run:`)
console.log(` npm run calc-unlock "${recommendedString}"`)
}
main().catch(console.error)