echogarden 0.11.11 → 0.11.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/schemas/options.json +16 -0
- package/dist/alignment/DTWMfccSequenceAlignment.js +2 -2
- package/dist/alignment/DTWMfccSequenceAlignment.js.map +1 -1
- package/dist/alignment/SpeechAlignment.d.ts +1 -1
- package/dist/alignment/SpeechAlignment.js +15 -3
- package/dist/alignment/SpeechAlignment.js.map +1 -1
- package/dist/api/Alignment.js +3 -3
- package/dist/api/Alignment.js.map +1 -1
- package/dist/api/LanguageDetection.js +1 -1
- package/dist/api/LanguageDetection.js.map +1 -1
- package/dist/api/Recognition.js +3 -3
- package/dist/api/Recognition.js.map +1 -1
- package/dist/api/Synthesis.js +7 -6
- package/dist/api/Synthesis.js.map +1 -1
- package/dist/api/Translation.js +3 -3
- package/dist/api/Translation.js.map +1 -1
- package/dist/audio/AudioUtilities.d.ts +5 -2
- package/dist/audio/AudioUtilities.js +50 -22
- package/dist/audio/AudioUtilities.js.map +1 -1
- package/dist/cli/CLI.js +2 -2
- package/dist/cli/CLI.js.map +1 -1
- package/dist/dsp/SpeexResampler.js +1 -1
- package/dist/recognition/WhisperSTT.js +2 -2
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/subtitles/Subtitles.d.ts +10 -7
- package/dist/subtitles/Subtitles.js +268 -207
- package/dist/subtitles/Subtitles.js.map +1 -1
- package/docs/Options.md +4 -2
- package/package.json +12 -11
- package/src/alignment/DTWMfccSequenceAlignment.ts +43 -0
- package/src/alignment/DTWSequenceAlignment.ts +121 -0
- package/src/alignment/DTWSequenceAlignmentWindowed.ts +210 -0
- package/src/alignment/LevenshteinSequenceAlignment.ts +126 -0
- package/src/alignment/SpeechAlignment.ts +488 -0
- package/src/api/API.ts +12 -0
- package/src/api/APIOptions.ts +15 -0
- package/src/api/Alignment.ts +329 -0
- package/src/api/Common.ts +16 -0
- package/src/api/Denoising.ts +120 -0
- package/src/api/LanguageDetection.ts +286 -0
- package/src/api/Recognition.ts +344 -0
- package/src/api/Synthesis.ts +1735 -0
- package/src/api/Translation.ts +143 -0
- package/src/api/Vad.ts +172 -0
- package/src/audio/AudioBufferConversion.ts +248 -0
- package/src/audio/AudioPlayer.ts +358 -0
- package/src/audio/AudioRecorder.ts +91 -0
- package/src/audio/AudioUtilities.ts +392 -0
- package/src/audio/SoxPath.ts +24 -0
- package/src/cli/CLI.ts +1360 -0
- package/src/cli/CLIConfigFile.ts +91 -0
- package/src/cli/CLILauncher.ts +26 -0
- package/src/cli/CLIOptionsSchema.ts +54 -0
- package/src/cli/CLIParser.ts +41 -0
- package/src/cli/CLIStarter.ts +40 -0
- package/src/codecs/FFMpegTranscoder.ts +214 -0
- package/src/codecs/TIMITCodec.ts +17 -0
- package/src/codecs/WaveCodec.ts +260 -0
- package/src/denoising/RNNoise.ts +95 -0
- package/src/dsp/BiquadFilter.ts +488 -0
- package/src/dsp/FFT.ts +187 -0
- package/src/dsp/MFCC.ts +227 -0
- package/src/dsp/MelSpectogram.ts +145 -0
- package/src/dsp/Rubberband.ts +249 -0
- package/src/dsp/Sonic.ts +59 -0
- package/src/dsp/SpeexResampler.ts +79 -0
- package/src/math/VectorMath.ts +812 -0
- package/src/nlp/ChineseSegmentation.ts +68 -0
- package/src/nlp/CompromiseNLP.ts +113 -0
- package/src/nlp/EspeakPhonemizer.ts +168 -0
- package/src/nlp/IPA.ts +139 -0
- package/src/nlp/JapaneseSegmentation.ts +53 -0
- package/src/nlp/Lexicon.ts +119 -0
- package/src/nlp/PhoneConversion.ts +508 -0
- package/src/nlp/Segmentation.ts +237 -0
- package/src/nlp/TextNormalizer.ts +160 -0
- package/src/recognition/AmazonTranscribeSTT.ts +112 -0
- package/src/recognition/AzureCognitiveServicesSTT.ts +76 -0
- package/src/recognition/GoogleCloudSTT.ts +92 -0
- package/src/recognition/SileroSTT.ts +173 -0
- package/src/recognition/VoskSTT.ts +112 -0
- package/src/recognition/WhisperSTT.ts +1518 -0
- package/src/server/Client.ts +297 -0
- package/src/server/Server.ts +178 -0
- package/src/server/ServerStarter.ts +12 -0
- package/src/server/Worker.ts +400 -0
- package/src/server/WorkerStarter.ts +38 -0
- package/src/speech-language-detection/SileroLanguageDetection.ts +105 -0
- package/src/subtitles/Subtitles.ts +478 -0
- package/src/synthesis/AwsPollyTTS.ts +78 -0
- package/src/synthesis/AzureCognitiveServicesTTS.ts +146 -0
- package/src/synthesis/CoquiServerTTS.ts +29 -0
- package/src/synthesis/ElevenLabsTTS.ts +104 -0
- package/src/synthesis/EspeakTTS.ts +552 -0
- package/src/synthesis/FliteTTS.ts +387 -0
- package/src/synthesis/GoogleCloudTTS.ts +112 -0
- package/src/synthesis/GoogleTranslateTTS.ts +210 -0
- package/src/synthesis/MicrosoftEdgeTTS.ts +298 -0
- package/src/synthesis/SamTTS.ts +30 -0
- package/src/synthesis/SapiTTS.ts +222 -0
- package/src/synthesis/StreamlabsPollyTTS.ts +114 -0
- package/src/synthesis/SvoxPicoTTS.ts +318 -0
- package/src/synthesis/VitsTTS.ts +734 -0
- package/src/tests/Test.ts +24 -0
- package/src/text-language-detection/FastTextLanguageDetection.ts +53 -0
- package/src/text-language-detection/TinyLDLanguageDetection.ts +16 -0
- package/src/typings/Fillers.d.ts +41 -0
- package/src/utilities/BinaryArrayConversion.ts +159 -0
- package/src/utilities/Compression.ts +91 -0
- package/src/utilities/FileDownloader.ts +201 -0
- package/src/utilities/FileSystem.ts +265 -0
- package/src/utilities/Hashing.ts +230 -0
- package/src/utilities/Locale.ts +119 -0
- package/src/utilities/Logger.ts +72 -0
- package/src/utilities/NdArrayUtilities.ts +31 -0
- package/src/utilities/ObjectUtilities.ts +169 -0
- package/src/utilities/OpenPromise.ts +13 -0
- package/src/utilities/PackageManager.ts +97 -0
- package/src/utilities/Queue.ts +17 -0
- package/src/utilities/RandomGenerator.ts +237 -0
- package/src/utilities/SignalChannel.ts +22 -0
- package/src/utilities/TarballMaker.ts +68 -0
- package/src/utilities/Timeline.ts +231 -0
- package/src/utilities/Timer.ts +93 -0
- package/src/utilities/Utilities.ts +574 -0
- package/src/utilities/WasmMemoryManager.ts +516 -0
- package/src/utilities/WebReader.ts +55 -0
- package/src/utilities/WikipediaReader.ts +41 -0
- package/src/voice-activity-detection/SileroVAD.ts +86 -0
- package/src/voice-activity-detection/WebRtcVAD.ts +76 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
export function extendDeep(base: any, extension: any): any {
|
|
2
|
+
const baseClone = deepClone(base)
|
|
3
|
+
|
|
4
|
+
if (isPlainObject(base) && extension === undefined) {
|
|
5
|
+
return baseClone
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const extensionClone = deepClone(extension)
|
|
9
|
+
if (!isPlainObject(base) || !isPlainObject(extension)) {
|
|
10
|
+
return extensionClone
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for (const propName in extensionClone) {
|
|
14
|
+
if (!extensionClone.hasOwnProperty(propName)) {
|
|
15
|
+
continue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
baseClone[propName] = extendDeep(baseClone[propName], extensionClone[propName])
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return baseClone
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function shallowClone<T>(val: T) {
|
|
25
|
+
return clone(val, false)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function deepClone<T>(val: T) {
|
|
29
|
+
return clone(val, true)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function clone<T>(val: T, deep = true, seenObjects: any[] = []): T {
|
|
33
|
+
if (val == null || typeof val !== "object") {
|
|
34
|
+
return val
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const obj = <any>val
|
|
38
|
+
const prototypeIdentifier = toString.call(obj)
|
|
39
|
+
|
|
40
|
+
switch (prototypeIdentifier) {
|
|
41
|
+
case "[object Array]": {
|
|
42
|
+
if (seenObjects.includes(obj)) {
|
|
43
|
+
throw new Error("deepClone: encountered a cyclic object")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
seenObjects.push(obj)
|
|
47
|
+
|
|
48
|
+
const clonedArray = new Array(obj.length)
|
|
49
|
+
|
|
50
|
+
for (let i = 0; i < obj.length; i++) {
|
|
51
|
+
if (deep) {
|
|
52
|
+
clonedArray[i] = clone(obj[i], true, seenObjects)
|
|
53
|
+
} else {
|
|
54
|
+
clonedArray[i] = obj[i]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
seenObjects.pop()
|
|
59
|
+
|
|
60
|
+
return <any>clonedArray
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
case "[object ArrayBuffer]": {
|
|
64
|
+
const clonedArray = new Uint8Array(obj.byteLength)
|
|
65
|
+
clonedArray.set(new Uint8Array(obj))
|
|
66
|
+
return <any>clonedArray.buffer
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
case "[object Int8Array]": {
|
|
70
|
+
const clonedArray = new Int8Array(obj.length)
|
|
71
|
+
clonedArray.set(obj)
|
|
72
|
+
return <any>clonedArray
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
case "[object Uint8Array]": {
|
|
76
|
+
const clonedArray = new Uint8Array(obj.length)
|
|
77
|
+
clonedArray.set(obj)
|
|
78
|
+
return <any>clonedArray
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
case "[object Uint8ClampedArray]": {
|
|
82
|
+
const clonedArray = new Uint8ClampedArray(obj.length)
|
|
83
|
+
clonedArray.set(obj)
|
|
84
|
+
return <any>clonedArray
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case "[object Int16Array]": {
|
|
88
|
+
const clonedArray = new Int16Array(obj.length)
|
|
89
|
+
clonedArray.set(obj)
|
|
90
|
+
return <any>clonedArray
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case "[object Uint16Array]": {
|
|
94
|
+
const clonedArray = new Uint16Array(obj.length)
|
|
95
|
+
clonedArray.set(obj)
|
|
96
|
+
return <any>clonedArray
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
case "[object Int32Array]": {
|
|
100
|
+
const clonedArray = new Int32Array(obj.length)
|
|
101
|
+
clonedArray.set(obj)
|
|
102
|
+
return <any>clonedArray
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case "[object Uint32Array]": {
|
|
106
|
+
const clonedArray = new Uint32Array(obj.length)
|
|
107
|
+
clonedArray.set(obj)
|
|
108
|
+
return <any>clonedArray
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
case "[object Float32Array]": {
|
|
112
|
+
const clonedArray = new Float32Array(obj.length)
|
|
113
|
+
clonedArray.set(obj)
|
|
114
|
+
return <any>clonedArray
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
case "[object Float64Array]": {
|
|
118
|
+
const clonedArray = new Float64Array(obj.length)
|
|
119
|
+
clonedArray.set(obj)
|
|
120
|
+
return <any>clonedArray
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
case "[object Date]": {
|
|
124
|
+
return <any>new Date(obj.valueOf())
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case "[object RegExp]": {
|
|
128
|
+
return obj
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
case "[object Function]": {
|
|
132
|
+
return obj
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
case "[object Object]": {
|
|
136
|
+
if (seenObjects.includes(obj)) {
|
|
137
|
+
throw new Error("deepClone: encountered a cyclic object")
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
seenObjects.push(obj)
|
|
141
|
+
|
|
142
|
+
const clonedObj: any = {}
|
|
143
|
+
|
|
144
|
+
for (const propName in obj) {
|
|
145
|
+
if (!obj.hasOwnProperty(propName)) {
|
|
146
|
+
continue
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (deep) {
|
|
150
|
+
clonedObj[propName] = clone(obj[propName], true, seenObjects)
|
|
151
|
+
} else {
|
|
152
|
+
clonedObj[propName] = obj[propName]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
seenObjects.pop()
|
|
157
|
+
|
|
158
|
+
return clonedObj
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
default: {
|
|
162
|
+
throw new Error(`Cloning of type ${prototypeIdentifier} is not supported`)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function isPlainObject(val: any) {
|
|
168
|
+
return val != null && typeof val === "object" && toString.call(val) === "[object Object]"
|
|
169
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class OpenPromise<T = void>
|
|
2
|
+
{
|
|
3
|
+
promise: Promise<T>
|
|
4
|
+
resolve: (value: T) => void = () => { throw new Error("OpenPromise resolved before initialization") }
|
|
5
|
+
reject: (reason?: any) => void = () => { throw new Error("OpenPromise rejected before initialization") }
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
this.promise = new Promise<T>((resolve, reject) => {
|
|
9
|
+
this.resolve = resolve
|
|
10
|
+
this.reject = reject
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import path from "node:path"
|
|
2
|
+
import { downloadAndExtractTarball } from "./FileDownloader.js"
|
|
3
|
+
import { getAppDataDir, getAppTempDir, ensureDir, existsSync, remove } from "./FileSystem.js"
|
|
4
|
+
import { appName } from "../api/Common.js"
|
|
5
|
+
import { GaxiosOptions } from "gaxios"
|
|
6
|
+
|
|
7
|
+
export async function loadPackage(packageName: string) {
|
|
8
|
+
packageName = resolveToVersionedPackageNameIfNeeded(packageName)
|
|
9
|
+
|
|
10
|
+
const packagesPath = await ensureAndGetPackagesDir()
|
|
11
|
+
|
|
12
|
+
const packagePath = path.join(packagesPath, packageName)
|
|
13
|
+
|
|
14
|
+
if (existsSync(packagePath)) {
|
|
15
|
+
return packagePath
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const tempPath = getAppTempDir(appName)
|
|
19
|
+
|
|
20
|
+
const headers = {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const options: GaxiosOptions = {
|
|
24
|
+
url: `${basePackageUrl}${packageName}.tar.gz`,
|
|
25
|
+
headers
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
await downloadAndExtractTarball(
|
|
29
|
+
options,
|
|
30
|
+
packagesPath,
|
|
31
|
+
tempPath,
|
|
32
|
+
packageName,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return packagePath
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function removePackage(packageName: string) {
|
|
39
|
+
packageName = resolveToVersionedPackageNameIfNeeded(packageName)
|
|
40
|
+
|
|
41
|
+
const packagesPath = await ensureAndGetPackagesDir()
|
|
42
|
+
|
|
43
|
+
const packagePath = path.join(packagesPath, packageName)
|
|
44
|
+
|
|
45
|
+
await remove(packagePath)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function ensureAndGetPackagesDir() {
|
|
49
|
+
const dataPath = getAppDataDir(appName)
|
|
50
|
+
|
|
51
|
+
const packagesPath = path.join(dataPath, "packages")
|
|
52
|
+
|
|
53
|
+
await ensureDir(packagesPath)
|
|
54
|
+
|
|
55
|
+
return packagesPath
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function resolveToVersionedPackageNameIfNeeded(packageName: string) {
|
|
59
|
+
const versionTag = getVersionTagFromPackageName(packageName)
|
|
60
|
+
|
|
61
|
+
if (versionTag) {
|
|
62
|
+
return packageName
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const resolvedVersionTag = resolveVersionTagForUnversionedPackageName(packageName)
|
|
66
|
+
|
|
67
|
+
return packageName = `${packageName}-${resolvedVersionTag}`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function getVersionTagFromPackageName(packageName: string) {
|
|
71
|
+
return packageName.match(/.*\-([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9](_[0-9]+)?)$/)?.[1]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function resolveVersionTagForUnversionedPackageName(unversionedPackageName: string) {
|
|
75
|
+
return packageVersionTagResolutionLookup[unversionedPackageName] || defaultVersionTag
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const basePackageUrl = "https://huggingface.co/echogarden/echogarden-packages/resolve/main/"
|
|
79
|
+
|
|
80
|
+
const defaultVersionTag = "20230718"
|
|
81
|
+
|
|
82
|
+
const packageVersionTagResolutionLookup: { [packageName: string]: string } = {
|
|
83
|
+
"sox-14.4.2-linux-minimal": "20230802",
|
|
84
|
+
"vits-de_DE-thorsten_emotional-medium": "20230808",
|
|
85
|
+
"vits-en_GB-semaine-medium": "20230808",
|
|
86
|
+
"vits-fr_FR-upmc-medium": "20230808",
|
|
87
|
+
"vits-lb_LU-marylux-medium": "20230808",
|
|
88
|
+
"vits-ro_RO-mihai-medium": "20230808",
|
|
89
|
+
"vits-sr_RS-serbski_institut-medium": "20230808",
|
|
90
|
+
"vits-tr_TR-dfki-medium": "20230808",
|
|
91
|
+
"vits-cs_CZ-jirka-medium": "20230824",
|
|
92
|
+
"vits-de_DE-thorsten-high": "20230824",
|
|
93
|
+
"vits-hu_HU-anna-medium": "20230824",
|
|
94
|
+
"vits-pt_PT-tugao-medium": "20230824",
|
|
95
|
+
"vits-sk_SK-lili-medium": "20230824",
|
|
96
|
+
"vits-tr_TR-fahrettin-medium": "20230824",
|
|
97
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class Queue<T> {
|
|
2
|
+
list: T[] = []
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
enqueue(item: T) {
|
|
8
|
+
this.list.push(item)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
dequeue(): T | undefined {
|
|
12
|
+
return this.list.shift()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get isEmpty() { return this.list.length == 0 }
|
|
16
|
+
get isNonempty() { return !this.isEmpty }
|
|
17
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { sumVector } from "../math/VectorMath.js"
|
|
2
|
+
import { logToStderr } from "./Utilities.js"
|
|
3
|
+
|
|
4
|
+
export abstract class RandomGenerator {
|
|
5
|
+
getIntInRange(min: number, max: number) {
|
|
6
|
+
return Math.floor(this.getFloatInRange(min, max))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
getFloatInRange(min = 0, max = 1) {
|
|
10
|
+
return min + (this.nextFloat() * (max - min))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getFloats(length: number, min = 0, max = 1) {
|
|
14
|
+
const result = []
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < length; i++) {
|
|
17
|
+
result.push(this.getFloatInRange(min, max))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return result
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getInts(length: number, min: number, max: number) {
|
|
24
|
+
const result = []
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < length; i++) {
|
|
27
|
+
result.push(this.getIntInRange(min, max))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return result
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getNormallyDistributedVector(featureCount: number, meanVector: number[], standardDeviationVector: number[]) {
|
|
34
|
+
const features = this.getNormallyDistributedValues(featureCount)
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < features.length; i++) {
|
|
37
|
+
features[i] = meanVector[i] + (features[i] * standardDeviationVector[i])
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return features
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getNormallyDistributedValues(count: number, mean = 0, standardDeviation = 1) {
|
|
44
|
+
const result: number[] = []
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i < count; i += 2) {
|
|
47
|
+
const [n1, n2] = this.getNormallyDistributedPair()
|
|
48
|
+
|
|
49
|
+
result.push(mean + (n1 * standardDeviation))
|
|
50
|
+
|
|
51
|
+
if (i + 1 < count) {
|
|
52
|
+
result.push(mean + (n2 * standardDeviation))
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return result
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getNormallyDistributedPair() {
|
|
60
|
+
// Using Marsaglia polar method
|
|
61
|
+
// https://en.wikipedia.org/wiki/Marsaglia_polar_method
|
|
62
|
+
|
|
63
|
+
let x: number
|
|
64
|
+
let y: number
|
|
65
|
+
let s: number
|
|
66
|
+
|
|
67
|
+
do {
|
|
68
|
+
x = (this.nextFloat() * 2) - 1
|
|
69
|
+
y = (this.nextFloat() * 2) - 1
|
|
70
|
+
|
|
71
|
+
s = (x ** 2) + (y ** 2)
|
|
72
|
+
} while (s <= 0 || s >= 1)
|
|
73
|
+
|
|
74
|
+
const m = Math.sqrt((-2 * Math.log(s)) / s)
|
|
75
|
+
|
|
76
|
+
const n1 = x * m
|
|
77
|
+
const n2 = y * m
|
|
78
|
+
|
|
79
|
+
return [n1, n2]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
selectRandomIndexFromDistribution(distribution: number[]) {
|
|
83
|
+
const sum = sumVector(distribution)
|
|
84
|
+
|
|
85
|
+
const randomTarget = this.getFloatInRange(0, sum)
|
|
86
|
+
|
|
87
|
+
let cumSum = 0
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < distribution.length; i++) {
|
|
90
|
+
const element = distribution[i]
|
|
91
|
+
|
|
92
|
+
if (randomTarget < cumSum + element) {
|
|
93
|
+
return i
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
cumSum += element
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return distribution.length - 1
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
abstract nextFloat(): number
|
|
103
|
+
abstract nextUint32(): number
|
|
104
|
+
abstract nextInt32(): number
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export class MurmurRNG extends RandomGenerator {
|
|
108
|
+
state: number
|
|
109
|
+
|
|
110
|
+
constructor(seed: number) {
|
|
111
|
+
super()
|
|
112
|
+
|
|
113
|
+
this.state = seed
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
nextFloat() {
|
|
117
|
+
return this.nextUint32() / 4294967296
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
nextUint32() {
|
|
121
|
+
return this.nextInt32() >>> 0
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
nextInt32() {
|
|
125
|
+
const multiplier = 3332679571
|
|
126
|
+
|
|
127
|
+
let s = this.state
|
|
128
|
+
|
|
129
|
+
s = Math.imul(s, multiplier)
|
|
130
|
+
s ^= s >>> 16
|
|
131
|
+
|
|
132
|
+
s = Math.imul(s, multiplier)
|
|
133
|
+
s ^= s >>> 10
|
|
134
|
+
|
|
135
|
+
s = Math.imul(s, multiplier)
|
|
136
|
+
s ^= s >>> 17
|
|
137
|
+
|
|
138
|
+
this.state = s
|
|
139
|
+
|
|
140
|
+
return s
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static hashInt32(val: number, seed = 234928357) {
|
|
144
|
+
const rng = new MurmurRNG(seed ^ val)
|
|
145
|
+
return rng.nextUint32()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export class XorShift32RNG extends RandomGenerator {
|
|
150
|
+
state: number
|
|
151
|
+
|
|
152
|
+
constructor(seed: number) {
|
|
153
|
+
super()
|
|
154
|
+
|
|
155
|
+
this.state = seed
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
nextFloat() {
|
|
159
|
+
return this.nextUint32() / 4294967296
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
nextUint32() {
|
|
163
|
+
return this.nextInt32() >>> 0
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
nextInt32() {
|
|
167
|
+
let s = this.state
|
|
168
|
+
|
|
169
|
+
s ^= s << 13
|
|
170
|
+
s ^= s >>> 17
|
|
171
|
+
s ^= s << 5
|
|
172
|
+
|
|
173
|
+
this.state = s
|
|
174
|
+
|
|
175
|
+
return s
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export class LehmerRNG extends RandomGenerator {
|
|
180
|
+
state: number
|
|
181
|
+
|
|
182
|
+
constructor(seed: number) {
|
|
183
|
+
super()
|
|
184
|
+
|
|
185
|
+
this.state = seed
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
nextFloat() {
|
|
189
|
+
return this.nextUint32() / 4294967296
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
nextUint32() {
|
|
193
|
+
return this.nextInt32() >>> 0
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
nextInt32() {
|
|
197
|
+
let s = this.state
|
|
198
|
+
|
|
199
|
+
s = s * 48271 % 0x7fffffff
|
|
200
|
+
|
|
201
|
+
this.state = s
|
|
202
|
+
|
|
203
|
+
return s
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const log = logToStderr
|
|
208
|
+
|
|
209
|
+
export function testRngCycleLength() {
|
|
210
|
+
const seed = 1
|
|
211
|
+
|
|
212
|
+
const rng = new XorShift32RNG(seed)
|
|
213
|
+
|
|
214
|
+
const bucketCount = 1000000
|
|
215
|
+
const seen: number[][] = []
|
|
216
|
+
|
|
217
|
+
for (let i = 0; i < bucketCount; i++) {
|
|
218
|
+
seen[i] = []
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
for (let i = 0; i < 4294967296; i++) {
|
|
222
|
+
if (i % 1000000 == 0) {
|
|
223
|
+
log(`${i} iterations`)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const r = rng.nextUint32()
|
|
227
|
+
|
|
228
|
+
const bucket = seen[r % bucketCount]
|
|
229
|
+
|
|
230
|
+
if (bucket.includes(r)) {
|
|
231
|
+
log(`Cycles at iteration ${i}`)
|
|
232
|
+
return
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
bucket.push(r)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class SignalChannel {
|
|
2
|
+
channel: MessageChannel
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
this.channel = new MessageChannel()
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
on(signalName: string, handler: (data?: any) => void) {
|
|
10
|
+
this.channel.port2.onmessage = (event: MessageEvent) => {
|
|
11
|
+
if (event.data.signalName != signalName) {
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
handler(event.data.data)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
send(signalName: string, data?: any) {
|
|
20
|
+
this.channel.port1.postMessage({ signalName, data })
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import path from "path"
|
|
2
|
+
import { createTarball } from "./Compression.js"
|
|
3
|
+
import { ensureDir, existsSync, getAppTempDir, move, readdir, stat } from "./FileSystem.js"
|
|
4
|
+
import { ensureAndGetPackagesDir } from "./PackageManager.js"
|
|
5
|
+
import { appName } from "../api/Common.js"
|
|
6
|
+
import { getRandomHexString } from "./Utilities.js"
|
|
7
|
+
|
|
8
|
+
const tarballDir = "../resources/tarballs"
|
|
9
|
+
|
|
10
|
+
export async function makeTarballsForInstalledPackages(skipIfExists = false) {
|
|
11
|
+
const packagesDir = await ensureAndGetPackagesDir()
|
|
12
|
+
const packageList = await readdir(packagesDir)
|
|
13
|
+
|
|
14
|
+
for (const packageName of packageList) {
|
|
15
|
+
if (skipIfExists && existsSync(path.join(tarballDir, `${packageName}.tar.gz`))) {
|
|
16
|
+
continue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const packagePath = path.join(packagesDir, packageName)
|
|
20
|
+
await createNamedTarball(packagePath, packageName)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function createNamedTarball(inputPath: string, name: string) {
|
|
25
|
+
const tempDir = getAppTempDir(appName)
|
|
26
|
+
await ensureDir(tempDir)
|
|
27
|
+
const tempFilename = path.join(tempDir, getRandomHexString(16))
|
|
28
|
+
|
|
29
|
+
await createTarball(inputPath, tempFilename, name)
|
|
30
|
+
|
|
31
|
+
const targetFilname = path.join(tarballDir, `${name}.tar.gz`)
|
|
32
|
+
|
|
33
|
+
await move(tempFilename, targetFilname)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function createTarballForEachDirIn(baseDir: string, namePrefix: String) {
|
|
37
|
+
for (const dirName of await readdir(baseDir)) {
|
|
38
|
+
const dirPath = path.join(baseDir, dirName)
|
|
39
|
+
|
|
40
|
+
const fileStat = await stat(dirPath)
|
|
41
|
+
|
|
42
|
+
if (!fileStat.isDirectory()) {
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const archiveName = `${namePrefix}-${dirName}`
|
|
47
|
+
|
|
48
|
+
await createNamedTarball(dirPath, archiveName)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function createTarballForEachFileIn(baseDir: string, namePrefix: String) {
|
|
53
|
+
for (const filename of await readdir(baseDir)) {
|
|
54
|
+
const filenameWithoutExtension = path.parse(filename).name
|
|
55
|
+
|
|
56
|
+
const filePath = path.join(baseDir, filename)
|
|
57
|
+
|
|
58
|
+
const fileStat = await stat(filePath)
|
|
59
|
+
|
|
60
|
+
if (!fileStat.isFile()) {
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const archiveName = `${namePrefix}-${filenameWithoutExtension}`
|
|
65
|
+
|
|
66
|
+
await createNamedTarball(filePath, archiveName)
|
|
67
|
+
}
|
|
68
|
+
}
|