@datagrok-libraries/statistics 1.0.0 → 1.0.1
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/package.json
CHANGED
|
@@ -1,59 +1,13 @@
|
|
|
1
|
-
declare type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
declare type FitResult = {
|
|
2
|
+
parameters: number[];
|
|
3
|
+
fittedCurve: (x: number) => number;
|
|
4
|
+
confidenceTop: (x: number) => number;
|
|
5
|
+
confidenceBottom: (x: number) => number;
|
|
5
6
|
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
params: number[];
|
|
12
|
-
cf(params: number[], args: TArg): number;
|
|
13
|
-
of(targetFunc: (params: number[], args: TArg) => number, data: {
|
|
14
|
-
observed: number[];
|
|
15
|
-
args: TArg[];
|
|
16
|
-
}, params: number[]): Likelihood;
|
|
17
|
-
}
|
|
18
|
-
export declare class CurveFitter<TArg> implements ICurveFitter<TArg> {
|
|
19
|
-
errorModel: string;
|
|
20
|
-
data: {
|
|
21
|
-
observed: number[];
|
|
22
|
-
args: TArg[];
|
|
23
|
-
};
|
|
24
|
-
params: number[];
|
|
25
|
-
cf: (params: number[], args: TArg) => number;
|
|
26
|
-
of: typeof objectiveNormalConstant;
|
|
27
|
-
optimizable: {
|
|
28
|
-
getValue: (parameters: number[]) => number;
|
|
29
|
-
getGradient: (parameters: number[], gradient: number[]) => number[];
|
|
30
|
-
};
|
|
31
|
-
fitHistory: {
|
|
32
|
-
iterations: number;
|
|
33
|
-
parameters: {
|
|
34
|
-
[iteration: number]: number[];
|
|
35
|
-
};
|
|
36
|
-
likelihood: {
|
|
37
|
-
[iteration: number]: number;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
constructor(curveFunction: (params: number[], args: TArg) => number, data: {
|
|
41
|
-
observed: number[];
|
|
42
|
-
args: TArg[];
|
|
43
|
-
}, params: number[], errorModel?: 'constant' | 'proportional');
|
|
44
|
-
performFit(): void;
|
|
45
|
-
get parameters(): number[];
|
|
46
|
-
get curveFunction(): Function;
|
|
47
|
-
get confidence(): {
|
|
48
|
-
top: Function;
|
|
49
|
-
bottom: Function;
|
|
50
|
-
};
|
|
51
|
-
private getDerivative;
|
|
52
|
-
}
|
|
7
|
+
export declare function fit(data: {
|
|
8
|
+
x: number[];
|
|
9
|
+
y: number[];
|
|
10
|
+
}, params: number[], curveFunction: (params: number[], x: number) => number, errorModel: string): FitResult;
|
|
53
11
|
export declare function sigmoid(params: number[], x: number): number;
|
|
54
|
-
declare function objectiveNormalConstant<TArg>(targetFunc: (params: number[], args: TArg) => number, data: {
|
|
55
|
-
observed: number[];
|
|
56
|
-
args: TArg[];
|
|
57
|
-
}, params: number[]): Likelihood;
|
|
58
12
|
export {};
|
|
59
13
|
//# sourceMappingURL=fit-curve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fit-curve.d.ts","sourceRoot":"","sources":["fit-curve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fit-curve.d.ts","sourceRoot":"","sources":["fit-curve.ts"],"names":[],"mappings":"AAQA,aAAK,SAAS,GAAG;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAC;IACjC,aAAa,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAC;IACnC,gBAAgB,EAAE,CAAC,CAAC,EAAC,MAAM,KAAI,MAAM,CAAA;CACtC,CAAC;AAEF,wBAAgB,GAAG,CAAE,IAAI,EAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAClD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CA2FzG;AA0JD,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3D"}
|
|
@@ -1,82 +1,18 @@
|
|
|
1
1
|
import { limitedMemoryBFGS } from "../../lbfgs/lbfgs";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
this.cf = curveFunction;
|
|
15
|
-
switch (errorModel) {
|
|
16
|
-
case 'constant':
|
|
17
|
-
this.of = objectiveNormalConstant;
|
|
18
|
-
case 'proportional':
|
|
19
|
-
this.of = objectiveNormalProportional;
|
|
20
|
-
// case 'combinational1':
|
|
21
|
-
// this.of = objectiveNormalAdditive;
|
|
22
|
-
// case 'combinational2':
|
|
23
|
-
// this.of = objectiveNormalAdditive;
|
|
24
|
-
default:
|
|
25
|
-
this.of = objectiveNormalConstant;
|
|
26
|
-
}
|
|
27
|
-
this.optimizable = {
|
|
28
|
-
getValue: (parameters) => {
|
|
29
|
-
return this.of(this.cf, this.data, parameters).value;
|
|
30
|
-
},
|
|
31
|
-
getGradient: (parameters, gradient) => {
|
|
32
|
-
const length = Object.keys(this.fitHistory.parameters).length;
|
|
33
|
-
this.fitHistory.iterations++;
|
|
34
|
-
this.fitHistory.parameters[length] = parameters.slice();
|
|
35
|
-
this.fitHistory.likelihood[length] = this.of(this.cf, this.data, parameters).value;
|
|
36
|
-
console.log(parameters.slice());
|
|
37
|
-
for (let i = 0; i < parameters.length; i++)
|
|
38
|
-
gradient[i] = this.getDerivative(parameters, i);
|
|
39
|
-
return gradient;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
performFit() {
|
|
44
|
-
limitedMemoryBFGS(this.optimizable, this.params);
|
|
45
|
-
limitedMemoryBFGS(this.optimizable, this.params);
|
|
46
|
-
}
|
|
47
|
-
get parameters() {
|
|
48
|
-
return this.params;
|
|
2
|
+
export function fit(data, params, curveFunction, errorModel) {
|
|
3
|
+
let of;
|
|
4
|
+
switch (errorModel) {
|
|
5
|
+
case 'constant':
|
|
6
|
+
of = objectiveNormalConstant;
|
|
7
|
+
break;
|
|
8
|
+
case 'proportional':
|
|
9
|
+
of = objectiveNormalProportional;
|
|
10
|
+
break;
|
|
11
|
+
default:
|
|
12
|
+
of = objectiveNormalConstant;
|
|
13
|
+
break;
|
|
49
14
|
}
|
|
50
|
-
|
|
51
|
-
let res = (arg) => {
|
|
52
|
-
let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
|
|
53
|
-
return this.cf(params, arg);
|
|
54
|
-
};
|
|
55
|
-
return res;
|
|
56
|
-
}
|
|
57
|
-
get confidence() {
|
|
58
|
-
let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
|
|
59
|
-
let error = this.errorModel == "constant" ?
|
|
60
|
-
this.of(this.cf, this.data, params).const :
|
|
61
|
-
this.of(this.cf, this.data, params).mult;
|
|
62
|
-
let top = (arg) => {
|
|
63
|
-
let value = this.cf(params, arg);
|
|
64
|
-
if (this.errorModel == "constant")
|
|
65
|
-
return value + 1.4 * error;
|
|
66
|
-
else
|
|
67
|
-
return value + 1.4 * (Math.abs(value) * error);
|
|
68
|
-
};
|
|
69
|
-
let bottom = (arg) => {
|
|
70
|
-
let value = this.cf(params, arg);
|
|
71
|
-
if (this.errorModel == "constant")
|
|
72
|
-
return value - 1.4 * error;
|
|
73
|
-
else
|
|
74
|
-
return value - 1.4 * (Math.abs(value) * error);
|
|
75
|
-
};
|
|
76
|
-
return { top: top, bottom: bottom };
|
|
77
|
-
}
|
|
78
|
-
//central difference
|
|
79
|
-
getDerivative(params, selectedParam) {
|
|
15
|
+
function getDerivative(params, selectedParam) {
|
|
80
16
|
let step = params[selectedParam] * 0.0001;
|
|
81
17
|
step = step == 0 ? 0.001 : step;
|
|
82
18
|
let paramsTop = [];
|
|
@@ -91,11 +27,178 @@ export class CurveFitter {
|
|
|
91
27
|
paramsBottom.push(params[i]);
|
|
92
28
|
}
|
|
93
29
|
}
|
|
94
|
-
const drvTop =
|
|
95
|
-
const drvBottom =
|
|
30
|
+
const drvTop = of(curveFunction, data, paramsTop).value;
|
|
31
|
+
const drvBottom = of(curveFunction, data, paramsBottom).value;
|
|
96
32
|
return (drvTop - drvBottom) / (2 * step);
|
|
97
33
|
}
|
|
34
|
+
let iterations = 0;
|
|
35
|
+
let optimizable = {
|
|
36
|
+
getValue: (parameters) => {
|
|
37
|
+
return of(curveFunction, data, parameters).value;
|
|
38
|
+
},
|
|
39
|
+
getGradient: (parameters, gradient) => {
|
|
40
|
+
const length = Object.keys(parameters).length;
|
|
41
|
+
iterations++;
|
|
42
|
+
console.log(parameters.slice());
|
|
43
|
+
for (let i = 0; i < parameters.length; i++)
|
|
44
|
+
gradient[i] = getDerivative(parameters, i);
|
|
45
|
+
return gradient;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
limitedMemoryBFGS(optimizable, params);
|
|
49
|
+
limitedMemoryBFGS(optimizable, params);
|
|
50
|
+
let fittedCurve = (x) => {
|
|
51
|
+
return curveFunction(params, x);
|
|
52
|
+
};
|
|
53
|
+
let top = (x) => {
|
|
54
|
+
let value = curveFunction(params, x);
|
|
55
|
+
if (errorModel == "constant")
|
|
56
|
+
return value + 1.4 * error;
|
|
57
|
+
else
|
|
58
|
+
return value + 1.4 * (Math.abs(value) * error);
|
|
59
|
+
};
|
|
60
|
+
let error = errorModel == "constant" ?
|
|
61
|
+
of(curveFunction, data, params).const :
|
|
62
|
+
of(curveFunction, data, params).mult;
|
|
63
|
+
let bottom = (x) => {
|
|
64
|
+
let value = curveFunction(params, x);
|
|
65
|
+
if (errorModel == "constant")
|
|
66
|
+
return value - 1.4 * error;
|
|
67
|
+
else
|
|
68
|
+
return value - 1.4 * (Math.abs(value) * error);
|
|
69
|
+
};
|
|
70
|
+
let fitRes = {
|
|
71
|
+
parameters: params,
|
|
72
|
+
fittedCurve: fittedCurve,
|
|
73
|
+
confidenceTop: top,
|
|
74
|
+
confidenceBottom: bottom
|
|
75
|
+
};
|
|
76
|
+
return fitRes;
|
|
98
77
|
}
|
|
78
|
+
// performFit(): FitResult {
|
|
79
|
+
// limitedMemoryBFGS(this.optimizable, this.params);
|
|
80
|
+
// limitedMemoryBFGS(this.optimizable, this.params);
|
|
81
|
+
// let fit: FitResult = {
|
|
82
|
+
// parameters = this.parameters;
|
|
83
|
+
// };
|
|
84
|
+
// return {parameters: , curveFunction: this.curveFunction, confidence: this.confidence};
|
|
85
|
+
// }
|
|
86
|
+
// interface ICurveFitter<TArg> {
|
|
87
|
+
// data: {observed: number[], args: TArg[]};
|
|
88
|
+
// params: number[];
|
|
89
|
+
// //curve function
|
|
90
|
+
// cf (params: number[], args: TArg): number
|
|
91
|
+
// //objective function
|
|
92
|
+
// of (targetFunc: (params: number[], args: TArg) => number,
|
|
93
|
+
// data: {observed: number[], args: TArg[]},
|
|
94
|
+
// params: number[]): Likelihood
|
|
95
|
+
// }
|
|
96
|
+
// export class CurveFitter<TArg = number> implements ICurveFitter<TArg> {
|
|
97
|
+
// errorModel: string;
|
|
98
|
+
// data: {observed: number[], args: TArg[]};
|
|
99
|
+
// params: number[];
|
|
100
|
+
// cf;
|
|
101
|
+
// of;
|
|
102
|
+
// optimizable;
|
|
103
|
+
// fitHistory: {iterations: number, parameters: {[iteration: number]: number[]},
|
|
104
|
+
// likelihood: {[iteration: number]: number}} = {
|
|
105
|
+
// iterations: 0,
|
|
106
|
+
// parameters: {},
|
|
107
|
+
// likelihood: {}
|
|
108
|
+
// };
|
|
109
|
+
// constructor(curveFunction: (params: number[], args: TArg) => number,
|
|
110
|
+
// data: {observed: number[], args: TArg[]},
|
|
111
|
+
// params: number[],
|
|
112
|
+
// errorModel: 'constant' | 'proportional' = 'constant'//implement as enum
|
|
113
|
+
// ) {
|
|
114
|
+
// if(data.observed.length == 0 || data.observed.length != data.args.length)
|
|
115
|
+
// throw new Error('invalid data');
|
|
116
|
+
// this.data = data;
|
|
117
|
+
// this.params = params;
|
|
118
|
+
// this.errorModel = errorModel;
|
|
119
|
+
// this.cf = curveFunction;
|
|
120
|
+
// switch(errorModel) {
|
|
121
|
+
// case 'constant':
|
|
122
|
+
// this.of = objectiveNormalConstant;
|
|
123
|
+
// break;
|
|
124
|
+
// case 'proportional':
|
|
125
|
+
// this.of = objectiveNormalProportional;
|
|
126
|
+
// break;
|
|
127
|
+
// default:
|
|
128
|
+
// this.of = objectiveNormalConstant;
|
|
129
|
+
// break;
|
|
130
|
+
// }
|
|
131
|
+
// this.optimizable = {
|
|
132
|
+
// getValue: (parameters: number[]) => {
|
|
133
|
+
// return this.of(this.cf, this.data, parameters).value;
|
|
134
|
+
// },
|
|
135
|
+
// getGradient: (parameters: number[], gradient: number[]) => {
|
|
136
|
+
// const length = Object.keys(this.fitHistory.parameters).length;
|
|
137
|
+
// this.fitHistory.iterations++;
|
|
138
|
+
// this.fitHistory.parameters[length] = parameters.slice();
|
|
139
|
+
// this.fitHistory.likelihood[length] = this.of(this.cf, this.data, parameters).value;
|
|
140
|
+
// console.log(parameters.slice());
|
|
141
|
+
// for (let i = 0; i < parameters.length; i++)
|
|
142
|
+
// gradient[i] = this.getDerivative(parameters, i);
|
|
143
|
+
// return gradient;
|
|
144
|
+
// }
|
|
145
|
+
// };
|
|
146
|
+
// }
|
|
147
|
+
// performFit(): void {
|
|
148
|
+
// limitedMemoryBFGS(this.optimizable, this.params);
|
|
149
|
+
// limitedMemoryBFGS(this.optimizable, this.params);
|
|
150
|
+
// }
|
|
151
|
+
// get parameters(): number[] {
|
|
152
|
+
// return this.params;
|
|
153
|
+
// }
|
|
154
|
+
// get curveFunction(): Function {
|
|
155
|
+
// let res = (arg: TArg) =>{
|
|
156
|
+
// let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
|
|
157
|
+
// return this.cf(params, arg);
|
|
158
|
+
// }
|
|
159
|
+
// return res;
|
|
160
|
+
// }
|
|
161
|
+
// get confidence(): {top:Function, bottom: Function} {
|
|
162
|
+
// let params = this.fitHistory.parameters[this.fitHistory.iterations - 1];
|
|
163
|
+
// let error = this.errorModel == "constant" ?
|
|
164
|
+
// this.of(this.cf, this.data, params).const :
|
|
165
|
+
// this.of(this.cf, this.data, params).mult;
|
|
166
|
+
// let top = (arg: TArg) =>{
|
|
167
|
+
// let value = this.cf(params, arg);
|
|
168
|
+
// if (this.errorModel == "constant")
|
|
169
|
+
// return value + 1.4*error;
|
|
170
|
+
// else
|
|
171
|
+
// return value + 1.4*(Math.abs(value)*error);
|
|
172
|
+
// }
|
|
173
|
+
// let bottom = (arg: TArg) =>{
|
|
174
|
+
// let value = this.cf(params, arg);
|
|
175
|
+
// if (this.errorModel == "constant")
|
|
176
|
+
// return value - 1.4*error;
|
|
177
|
+
// else
|
|
178
|
+
// return value - 1.4*(Math.abs(value)*error);
|
|
179
|
+
// }
|
|
180
|
+
// return {top: top, bottom: bottom};
|
|
181
|
+
// }
|
|
182
|
+
// //central difference
|
|
183
|
+
// private getDerivative(params: number[], selectedParam: number): number {
|
|
184
|
+
// let step = params[selectedParam]*0.0001;
|
|
185
|
+
// step = step == 0 ? 0.001 : step;
|
|
186
|
+
// let paramsTop: number[] = [];
|
|
187
|
+
// let paramsBottom: number[] = [];
|
|
188
|
+
// for (let i = 0; i < params.length; i++) {
|
|
189
|
+
// if(i == selectedParam) {
|
|
190
|
+
// paramsTop.push(params[i] + step);
|
|
191
|
+
// paramsBottom.push(params[i] - step);
|
|
192
|
+
// } else {
|
|
193
|
+
// paramsTop.push(params[i]);
|
|
194
|
+
// paramsBottom.push(params[i]);
|
|
195
|
+
// }
|
|
196
|
+
// }
|
|
197
|
+
// const drvTop = this.of(this.cf, this.data, paramsTop).value;
|
|
198
|
+
// const drvBottom = this.of(this.cf, this.data, paramsBottom).value;
|
|
199
|
+
// return (drvTop - drvBottom)/(2*step);
|
|
200
|
+
// }
|
|
201
|
+
// }
|
|
99
202
|
export function sigmoid(params, x) {
|
|
100
203
|
const A = params[0];
|
|
101
204
|
const B = params[1];
|
|
@@ -110,10 +213,10 @@ function objectiveNormalConstant(targetFunc, data, params) {
|
|
|
110
213
|
let sigma = 0;
|
|
111
214
|
let sigmaSq = 0;
|
|
112
215
|
let likelihood = 0;
|
|
113
|
-
let residuesSquares = new Float32Array(data.
|
|
114
|
-
for (let i = 0; i < data.
|
|
115
|
-
const obs = data.
|
|
116
|
-
const pred = targetFunc(params, data.
|
|
216
|
+
let residuesSquares = new Float32Array(data.x.length);
|
|
217
|
+
for (let i = 0; i < data.x.length; i++) {
|
|
218
|
+
const obs = data.y[i];
|
|
219
|
+
const pred = targetFunc(params, data.x[i]);
|
|
117
220
|
residuesSquares[i] = Math.pow(obs - pred, 2);
|
|
118
221
|
}
|
|
119
222
|
for (let i = 0; i < residuesSquares.length; i++)
|
|
@@ -130,10 +233,10 @@ function objectiveNormalProportional(targetFunc, data, params) {
|
|
|
130
233
|
let sigma = 0;
|
|
131
234
|
let sigmaSq = 0;
|
|
132
235
|
let likelihood = 0;
|
|
133
|
-
let residuesSquares = new Float32Array(data.
|
|
134
|
-
for (let i = 0; i < data.
|
|
135
|
-
const obs = data.
|
|
136
|
-
const pred = targetFunc(params, data.
|
|
236
|
+
let residuesSquares = new Float32Array(data.x.length);
|
|
237
|
+
for (let i = 0; i < data.x.length; i++) {
|
|
238
|
+
const obs = data.y[i];
|
|
239
|
+
const pred = targetFunc(params, data.x[i]);
|
|
137
240
|
residuesSquares[i] = Math.pow(obs - pred, 2);
|
|
138
241
|
}
|
|
139
242
|
for (let i = 0; i < residuesSquares.length; i++)
|
|
@@ -144,4 +247,52 @@ function objectiveNormalProportional(targetFunc, data, params) {
|
|
|
144
247
|
likelihood += residuesSquares[i] / sigmaSq + Math.log(2 * pi * sigmaSq);
|
|
145
248
|
return { value: -likelihood, const: sigma, mult: 0 };
|
|
146
249
|
}
|
|
147
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml0LWN1cnZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZml0LWN1cnZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBb0JuRCxNQUFNLE9BQU8sV0FBVztJQWN0QixZQUFZLGFBQXVELEVBQ3ZELElBQXdDLEVBQ3hDLE1BQWdCLEVBQ2hCLGFBQTBDLFVBQVU7UUFWaEUsZUFBVSxHQUNpRDtZQUN6RCxVQUFVLEVBQUUsQ0FBQztZQUNiLFVBQVUsRUFBRSxFQUFFO1lBQ2QsVUFBVSxFQUFFLEVBQUU7U0FDZixDQUFDO1FBUUEsSUFBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQ3RFLE1BQU0sSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxhQUFhLENBQUM7UUFFeEIsUUFBTyxVQUFVLEVBQUU7WUFDakIsS0FBSyxVQUFVO2dCQUNiLElBQUksQ0FBQyxFQUFFLEdBQUcsdUJBQXVCLENBQUM7WUFDcEMsS0FBSyxjQUFjO2dCQUNqQixJQUFJLENBQUMsRUFBRSxHQUFHLDJCQUEyQixDQUFDO1lBQ3hDLHlCQUF5QjtZQUN6Qix1Q0FBdUM7WUFDdkMseUJBQXlCO1lBQ3pCLHVDQUF1QztZQUN2QztnQkFDRSxJQUFJLENBQUMsRUFBRSxHQUFHLHVCQUF1QixDQUFDO1NBQ3JDO1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRztZQUNqQixRQUFRLEVBQUUsQ0FBQyxVQUFvQixFQUFFLEVBQUU7Z0JB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QUFDLENBQUM7SUFFM0IsS0FBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQzlDLFVBQVUsSUFBSSxlQUFlLENBQUMsQ0FBQyxDQUFDLEdBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFDLEVBQUUsR0FBQyxPQUFPLENBQUMsQ0FBQztJQUVsRSxPQUFPLEVBQUMsS0FBSyxFQUFFLENBQUMsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2xpbWl0ZWRNZW1vcnlCRkdTfSBmcm9tIFwiLi4vLi4vbGJmZ3MvbGJmZ3NcIlxuXG50eXBlIExpa2VsaWhvb2QgPSB7XG4gIHZhbHVlOiBudW1iZXIsIFxuICBjb25zdDogbnVtYmVyLCBcbiAgbXVsdDogbnVtYmVyXG59O1xuXG5pbnRlcmZhY2UgSUN1cnZlRml0dGVyPFRBcmc+IHtcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfTtcbiAgcGFyYW1zOiBudW1iZXJbXTtcblxuICAvL2N1cnZlIGZ1bmN0aW9uXG4gIGNmIChwYXJhbXM6IG51bWJlcltdLCBhcmdzOiBUQXJnKTogbnVtYmVyXG4gIC8vb2JqZWN0aXZlIGZ1bmN0aW9uXG4gIG9mICh0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogbnVtYmVyW10pOiBMaWtlbGlob29kXG59XG5cbmV4cG9ydCBjbGFzcyBDdXJ2ZUZpdHRlcjxUQXJnPiBpbXBsZW1lbnRzIElDdXJ2ZUZpdHRlcjxUQXJnPiB7XG4gIGVycm9yTW9kZWw6IHN0cmluZztcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfTtcbiAgcGFyYW1zOiBudW1iZXJbXTtcbiAgY2Y7XG4gIG9mO1xuICBvcHRpbWl6YWJsZTtcbiAgZml0SGlzdG9yeToge2l0ZXJhdGlvbnM6IG51bWJlciwgcGFyYW1ldGVyczoge1tpdGVyYXRpb246IG51bWJlcl06IG51bWJlcltdfSwgXG4gICAgICAgICAgICAgICAgbGlrZWxpaG9vZDoge1tpdGVyYXRpb246IG51bWJlcl06IG51bWJlcn19ID0ge1xuICAgIGl0ZXJhdGlvbnM6IDAsXG4gICAgcGFyYW1ldGVyczoge30sXG4gICAgbGlrZWxpaG9vZDoge31cbiAgfTtcblxuICBjb25zdHJ1Y3RvcihjdXJ2ZUZ1bmN0aW9uOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfSxcbiAgICAgICAgICAgICAgcGFyYW1zOiBudW1iZXJbXSxcbiAgICAgICAgICAgICAgZXJyb3JNb2RlbDogJ2NvbnN0YW50JyB8ICdwcm9wb3J0aW9uYWwnID0gJ2NvbnN0YW50J1xuICAgICAgICAgICAgICApIHtcblxuICAgIGlmKGRhdGEub2JzZXJ2ZWQubGVuZ3RoID09IDAgfHwgZGF0YS5vYnNlcnZlZC5sZW5ndGggIT0gZGF0YS5hcmdzLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBkYXRhJyk7XG4gICAgICBcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgIHRoaXMuZXJyb3JNb2RlbCA9IGVycm9yTW9kZWw7XG4gICAgdGhpcy5jZiA9IGN1cnZlRnVuY3Rpb247XG5cbiAgICBzd2l0Y2goZXJyb3JNb2RlbCkge1xuICAgICAgY2FzZSAnY29uc3RhbnQnOlxuICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQ29uc3RhbnQ7XG4gICAgICBjYXNlICdwcm9wb3J0aW9uYWwnOlxuICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsUHJvcG9ydGlvbmFsO1xuICAgICAgLy8gY2FzZSAnY29tYmluYXRpb25hbDEnOlxuICAgICAgLy8gICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQWRkaXRpdmU7XG4gICAgICAvLyBjYXNlICdjb21iaW5hdGlvbmFsMic6XG4gICAgICAvLyAgIHRoaXMub2YgPSBvYmplY3RpdmVOb3JtYWxBZGRpdGl2ZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMub2YgPSBvYmplY3RpdmVOb3JtYWxDb25zdGFudDtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGltaXphYmxlID0ge1xuICAgICAgZ2V0VmFsdWU6IChwYXJhbWV0ZXJzOiBudW1iZXJbXSkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtZXRlcnMpLnZhbHVlO1xuICAgICAgfSxcbiAgICAgIGdldEdyYWRpZW50OiAocGFyYW1ldGVyczogbnVtYmVyW10sIGdyYWRpZW50OiBudW1iZXJbXSkgPT4ge1xuICAgICAgICBjb25zdCBsZW5ndGggPSBPYmplY3Qua2V5cyh0aGlzLmZpdEhpc3RvcnkucGFyYW1ldGVycykubGVuZ3RoO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkuaXRlcmF0aW9ucysrO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkucGFyYW1ldGVyc1tsZW5ndGhdID0gcGFyYW1ldGVycy5zbGljZSgpO1xuICAgICAgICB0aGlzLmZpdEhpc3RvcnkubGlrZWxpaG9vZFtsZW5ndGhdID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtZXRlcnMpLnZhbHVlO1xuICAgICAgICBjb25zb2xlLmxvZyhwYXJhbWV0ZXJzLnNsaWNlKCkpO1xuICAgICAgICBcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgIGdyYWRpZW50W2ldID0gdGhpcy5nZXREZXJpdmF0aXZlKHBhcmFtZXRlcnMsIGkpO1xuXG4gICAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgcGVyZm9ybUZpdCgpOiB2b2lkIHtcbiAgICBsaW1pdGVkTWVtb3J5QkZHUyh0aGlzLm9wdGltaXphYmxlLCB0aGlzLnBhcmFtcyk7XG4gICAgbGltaXRlZE1lbW9yeUJGR1ModGhpcy5vcHRpbWl6YWJsZSwgdGhpcy5wYXJhbXMpO1xuICB9XG5cbiAgZ2V0IHBhcmFtZXRlcnMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLnBhcmFtcztcbiAgfVxuXG4gIGdldCBjdXJ2ZUZ1bmN0aW9uKCk6IEZ1bmN0aW9uIHtcbiAgICBsZXQgcmVzID0gKGFyZzogVEFyZykgPT57XG4gICAgICBsZXQgcGFyYW1zID0gdGhpcy5maXRIaXN0b3J5LnBhcmFtZXRlcnNbdGhpcy5maXRIaXN0b3J5Lml0ZXJhdGlvbnMgLSAxXTtcblxuICAgICAgcmV0dXJuIHRoaXMuY2YocGFyYW1zLCBhcmcpO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBnZXQgY29uZmlkZW5jZSgpOiB7dG9wOkZ1bmN0aW9uLCBib3R0b206IEZ1bmN0aW9ufSB7XG4gICAgbGV0IHBhcmFtcyA9IHRoaXMuZml0SGlzdG9yeS5wYXJhbWV0ZXJzW3RoaXMuZml0SGlzdG9yeS5pdGVyYXRpb25zIC0gMV07XG5cbiAgICBsZXQgZXJyb3IgPSB0aGlzLmVycm9yTW9kZWwgPT0gXCJjb25zdGFudFwiID9cbiAgICAgICAgICAgICAgICB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1zKS5jb25zdCA6XG4gICAgICAgICAgICAgICAgdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtcykubXVsdDtcblxuICAgIGxldCB0b3AgPSAoYXJnOiBUQXJnKSA9PntcbiAgICAgIGxldCB2YWx1ZSA9IHRoaXMuY2YocGFyYW1zLCBhcmcpO1xuICAgICAgaWYgKHRoaXMuZXJyb3JNb2RlbCA9PSBcImNvbnN0YW50XCIpXG4gICAgICAgIHJldHVybiAgdmFsdWUgKyAxLjQqZXJyb3I7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiAgdmFsdWUgKyAxLjQqKE1hdGguYWJzKHZhbHVlKSplcnJvcik7XG4gICAgfVxuXG4gICAgbGV0IGJvdHRvbSA9IChhcmc6IFRBcmcpID0+e1xuICAgICAgbGV0IHZhbHVlID0gdGhpcy5jZihwYXJhbXMsIGFyZyk7XG4gICAgICBpZiAodGhpcy5lcnJvck1vZGVsID09IFwiY29uc3RhbnRcIilcbiAgICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCplcnJvcjtcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge3RvcDogdG9wLCBib3R0b206IGJvdHRvbX07XG4gIH1cblxuICAvL2NlbnRyYWwgZGlmZmVyZW5jZVxuICBwcml2YXRlIGdldERlcml2YXRpdmUocGFyYW1zOiBudW1iZXJbXSwgc2VsZWN0ZWRQYXJhbTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc3RlcCA9IHBhcmFtc1tzZWxlY3RlZFBhcmFtXSowLjAwMDE7XG4gICAgc3RlcCA9IHN0ZXAgPT0gMCA/IDAuMDAxIDogc3RlcDsgXG4gICAgbGV0IHBhcmFtc1RvcDogbnVtYmVyW10gPSBbXTtcbiAgICBsZXQgcGFyYW1zQm90dG9tOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZihpID09IHNlbGVjdGVkUGFyYW0pIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldICsgc3RlcCk7XG4gICAgICAgIHBhcmFtc0JvdHRvbS5wdXNoKHBhcmFtc1tpXSAtIHN0ZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgICAgcGFyYW1zQm90dG9tLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZHJ2VG9wID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtc1RvcCkudmFsdWU7XG4gICAgY29uc3QgZHJ2Qm90dG9tID0gdGhpcy5vZih0aGlzLmNmLCB0aGlzLmRhdGEsIHBhcmFtc0JvdHRvbSkudmFsdWU7XG5cbiAgICByZXR1cm4gKGRydlRvcCAtIGRydkJvdHRvbSkvKDIqc3RlcCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNpZ21vaWQocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgQSA9IHBhcmFtc1swXTtcbiAgY29uc3QgQiA9IHBhcmFtc1sxXTtcbiAgY29uc3QgQyA9IHBhcmFtc1syXTtcbiAgY29uc3QgRCA9IHBhcmFtc1szXTtcbiAgY29uc3QgcmVzID0gRCArIChBIC0gRCkvKDEgKyBNYXRoLnBvdygxMCwgKHggLSBDKSpCKSk7XG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIG9iamVjdGl2ZU5vcm1hbENvbnN0YW50PFRBcmc+IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogbnVtYmVyW11cbik6IExpa2VsaWhvb2Qge1xuICAvL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuICBjb25zdCBwaSA9IE1hdGguUEk7XG4gIGxldCBzaWdtYSA9IDA7XG4gIGxldCBzaWdtYVNxID0gMDtcbiAgbGV0IGxpa2VsaWhvb2QgPSAwO1xuXG4gIGxldCByZXNpZHVlc1NxdWFyZXMgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYXJncy5sZW5ndGgpO1xuICBmb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb2JzID0gZGF0YS5vYnNlcnZlZFtpXTtcbiAgICBjb25zdCBwcmVkID0gdGFyZ2V0RnVuYyhwYXJhbXMsIGRhdGEuYXJnc1tpXSk7XG4gICAgcmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG4gIH1cbiAgXG4gIGZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG4gICAgc2lnbWFTcSArPSByZXNpZHVlc1NxdWFyZXNbaV07XG4gIHNpZ21hU3EgLz0gcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDtcbiAgc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbiAgZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbiAgICBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMiAqIHBpICogc2lnbWFTcSk7XG5cbiAgcmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufVxuXG5mdW5jdGlvbiBvYmplY3RpdmVOb3JtYWxQcm9wb3J0aW9uYWw8VEFyZz4gKFxuICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbiAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfSxcbiAgcGFyYW1zOiBudW1iZXJbXVxuKTogTGlrZWxpaG9vZCB7XG4vL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuY29uc3QgcGkgPSBNYXRoLlBJO1xubGV0IHNpZ21hID0gMDtcbmxldCBzaWdtYVNxID0gMDtcbmxldCBsaWtlbGlob29kID0gMDtcblxubGV0IHJlc2lkdWVzU3F1YXJlcyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5hcmdzLmxlbmd0aCk7XG5mb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG5jb25zdCBvYnMgPSBkYXRhLm9ic2VydmVkW2ldO1xuY29uc3QgcHJlZCA9IHRhcmdldEZ1bmMocGFyYW1zLCBkYXRhLmFyZ3NbaV0pXG5yZXNpZHVlc1NxdWFyZXNbaV0gPSBNYXRoLnBvdyhvYnMgLSBwcmVkLCAyKTtcbn1cblxuZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbnNpZ21hU3EgKz0gcmVzaWR1ZXNTcXVhcmVzW2ldO1xuc2lnbWFTcSAvPSByZXNpZHVlc1NxdWFyZXMubGVuZ3RoO1xuc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbmZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG5saWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMipwaSpzaWdtYVNxKTtcblxucmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxufSJdfQ==
|
|
250
|
+
// function objectiveNormalConstant<TArg> (
|
|
251
|
+
// targetFunc: (params: number[], args: TArg) => number,
|
|
252
|
+
// data: {observed: number[], args: TArg[]},
|
|
253
|
+
// params: number[]
|
|
254
|
+
// ): Likelihood {
|
|
255
|
+
// //assure observed and args same length
|
|
256
|
+
// const pi = Math.PI;
|
|
257
|
+
// let sigma = 0;
|
|
258
|
+
// let sigmaSq = 0;
|
|
259
|
+
// let likelihood = 0;
|
|
260
|
+
// let residuesSquares = new Float32Array(data.args.length);
|
|
261
|
+
// for(let i = 0; i < data.args.length; i++) {
|
|
262
|
+
// const obs = data.observed[i];
|
|
263
|
+
// const pred = targetFunc(params, data.args[i]);
|
|
264
|
+
// residuesSquares[i] = Math.pow(obs - pred, 2);
|
|
265
|
+
// }
|
|
266
|
+
// for(let i = 0; i < residuesSquares.length; i++)
|
|
267
|
+
// sigmaSq += residuesSquares[i];
|
|
268
|
+
// sigmaSq /= residuesSquares.length;
|
|
269
|
+
// sigma = Math.sqrt(sigmaSq);
|
|
270
|
+
// for(let i = 0; i < residuesSquares.length; i++)
|
|
271
|
+
// likelihood += residuesSquares[i]/sigmaSq + Math.log(2 * pi * sigmaSq);
|
|
272
|
+
// return {value: -likelihood, const: sigma, mult: 0};
|
|
273
|
+
// }
|
|
274
|
+
// function objectiveNormalProportional<TArg> (
|
|
275
|
+
// targetFunc: (params: number[], args: TArg) => number,
|
|
276
|
+
// data: {observed: number[], args: TArg[]},
|
|
277
|
+
// params: number[]
|
|
278
|
+
// ): Likelihood {
|
|
279
|
+
// //assure observed and args same length
|
|
280
|
+
// const pi = Math.PI;
|
|
281
|
+
// let sigma = 0;
|
|
282
|
+
// let sigmaSq = 0;
|
|
283
|
+
// let likelihood = 0;
|
|
284
|
+
// let residuesSquares = new Float32Array(data.args.length);
|
|
285
|
+
// for(let i = 0; i < data.args.length; i++) {
|
|
286
|
+
// const obs = data.observed[i];
|
|
287
|
+
// const pred = targetFunc(params, data.args[i])
|
|
288
|
+
// residuesSquares[i] = Math.pow(obs - pred, 2);
|
|
289
|
+
// }
|
|
290
|
+
// for(let i = 0; i < residuesSquares.length; i++)
|
|
291
|
+
// sigmaSq += residuesSquares[i];
|
|
292
|
+
// sigmaSq /= residuesSquares.length;
|
|
293
|
+
// sigma = Math.sqrt(sigmaSq);
|
|
294
|
+
// for(let i = 0; i < residuesSquares.length; i++)
|
|
295
|
+
// likelihood += residuesSquares[i]/sigmaSq + Math.log(2*pi*sigmaSq);
|
|
296
|
+
// return {value: -likelihood, const: sigma, mult: 0};
|
|
297
|
+
// }
|
|
298
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml0LWN1cnZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZml0LWN1cnZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBZW5ELE1BQU0sVUFBVSxHQUFHLENBQUUsSUFBK0IsRUFBRSxNQUFnQixFQUNsRCxhQUFzRCxFQUFFLFVBQWtCO0lBRTVGLElBQUksRUFFMkIsQ0FBQztJQUNoQyxRQUFPLFVBQVUsRUFBRTtRQUNqQixLQUFLLFVBQVU7WUFDYixFQUFFLEdBQUcsdUJBQXVCLENBQUM7WUFDN0IsTUFBTTtRQUNSLEtBQUssY0FBYztZQUNqQixFQUFFLEdBQUcsMkJBQTJCLENBQUM7WUFDakMsTUFBTTtRQUNSO1lBQ0UsRUFBRSxHQUFHLHVCQUF1QixDQUFDO1lBQzdCLE1BQU07S0FDVDtJQUVELFNBQVMsYUFBYSxDQUFDLE1BQWdCLEVBQUUsYUFBcUI7UUFDNUQsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFDLE1BQU0sQ0FBQztRQUN4QyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDaEMsSUFBSSxTQUFTLEdBQWEsRUFBRSxDQUFDO1FBQzdCLElBQUksWUFBWSxHQUFhLEVBQUUsQ0FBQztRQUNoQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN0QyxJQUFHLENBQUMsSUFBSSxhQUFhLEVBQUU7Z0JBQ3JCLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO2dCQUNqQyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQzthQUNyQztpQkFBTTtn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O0FBQ3BELDZFQUE2RTtBQUU3RSxzR0FBc0c7QUFDdEcsSUFBSTtBQUVKLCtDQUErQztBQUMvQywyREFBMkQ7QUFDM0QsOENBQThDO0FBQzlDLHFCQUFxQjtBQUNyQixrQkFBa0I7QUFDbEIseUNBQXlDO0FBQ3pDLHNCQUFzQjtBQUN0QixpQkFBaUI7QUFDakIsbUJBQW1CO0FBQ25CLHNCQUFzQjtBQUV0Qiw0REFBNEQ7QUFDNUQsOENBQThDO0FBQzlDLGdDQUFnQztBQUNoQyxnREFBZ0Q7QUFDaEQsZ0RBQWdEO0FBQ2hELElBQUk7QUFFSixrREFBa0Q7QUFDbEQsaUNBQWlDO0FBQ2pDLHFDQUFxQztBQUNyQyw4QkFBOEI7QUFFOUIsa0RBQWtEO0FBQ2xELHFFQUFxRTtBQUVyRSxvR0FBb0c7QUFDcEcsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7bGltaXRlZE1lbW9yeUJGR1N9IGZyb20gXCIuLi8uLi9sYmZncy9sYmZnc1wiXG5cbnR5cGUgTGlrZWxpaG9vZCA9IHtcbiAgdmFsdWU6IG51bWJlciwgXG4gIGNvbnN0OiBudW1iZXIsIFxuICBtdWx0OiBudW1iZXJcbn07XG5cbnR5cGUgRml0UmVzdWx0ID0ge1xuICBwYXJhbWV0ZXJzOiBudW1iZXJbXSxcbiAgZml0dGVkQ3VydmU6ICh4Om51bWJlcik9PiBudW1iZXIsXG4gIGNvbmZpZGVuY2VUb3A6ICh4Om51bWJlcik9PiBudW1iZXIsXG4gIGNvbmZpZGVuY2VCb3R0b206ICh4Om51bWJlcik9PiBudW1iZXJcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBmaXQgKGRhdGE6e3g6IG51bWJlcltdLCB5OiBudW1iZXJbXX0sIHBhcmFtczogbnVtYmVyW10sXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlRnVuY3Rpb246IChwYXJhbXM6IG51bWJlcltdLCB4OiBudW1iZXIpID0+IG51bWJlciwgZXJyb3JNb2RlbDogc3RyaW5nKTogRml0UmVzdWx0IHtcblxuICBsZXQgb2Y6ICh0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKSA9PiBudW1iZXIsIFxuICBkYXRhOiB7eTogbnVtYmVyW10sIHg6IG51bWJlcltdfSxcbiAgcGFyYW1zOiBudW1iZXJbXSkgPT4gTGlrZWxpaG9vZDtcbiAgc3dpdGNoKGVycm9yTW9kZWwpIHtcbiAgICBjYXNlICdjb25zdGFudCc6XG4gICAgICBvZiA9IG9iamVjdGl2ZU5vcm1hbENvbnN0YW50O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncHJvcG9ydGlvbmFsJzpcbiAgICAgIG9mID0gb2JqZWN0aXZlTm9ybWFsUHJvcG9ydGlvbmFsO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIG9mID0gb2JqZWN0aXZlTm9ybWFsQ29uc3RhbnQ7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERlcml2YXRpdmUocGFyYW1zOiBudW1iZXJbXSwgc2VsZWN0ZWRQYXJhbTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc3RlcCA9IHBhcmFtc1tzZWxlY3RlZFBhcmFtXSowLjAwMDE7XG4gICAgc3RlcCA9IHN0ZXAgPT0gMCA/IDAuMDAxIDogc3RlcDsgXG4gICAgbGV0IHBhcmFtc1RvcDogbnVtYmVyW10gPSBbXTtcbiAgICBsZXQgcGFyYW1zQm90dG9tOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZihpID09IHNlbGVjdGVkUGFyYW0pIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldICsgc3RlcCk7XG4gICAgICAgIHBhcmFtc0JvdHRvbS5wdXNoKHBhcmFtc1tpXSAtIHN0ZXApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyYW1zVG9wLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgICAgcGFyYW1zQm90dG9tLnB1c2gocGFyYW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZHJ2VG9wID0gb2YoY3VydmVGdW5jdGlvbiwgZGF0YSwgcGFyYW1zVG9wKS52YWx1ZTtcbiAgICBjb25zdCBkcnZCb3R0b20gPSBvZihjdXJ2ZUZ1bmN0aW9uLCBkYXRhLCBwYXJhbXNCb3R0b20pLnZhbHVlO1xuXG4gICAgcmV0dXJuIChkcnZUb3AgLSBkcnZCb3R0b20pLygyKnN0ZXApO1xuICB9XG5cblxuICBsZXQgaXRlcmF0aW9ucyA9IDA7XG5cbiAgbGV0IG9wdGltaXphYmxlID0ge1xuICAgIGdldFZhbHVlOiAocGFyYW1ldGVyczogbnVtYmVyW10pID0+IHtcbiAgICAgIHJldHVybiBvZihjdXJ2ZUZ1bmN0aW9uLCBkYXRhLCBwYXJhbWV0ZXJzKS52YWx1ZTtcbiAgICB9LFxuICAgIGdldEdyYWRpZW50OiAocGFyYW1ldGVyczogbnVtYmVyW10sIGdyYWRpZW50OiBudW1iZXJbXSkgPT4ge1xuICAgICAgY29uc3QgbGVuZ3RoID0gT2JqZWN0LmtleXMocGFyYW1ldGVycykubGVuZ3RoO1xuICAgICAgaXRlcmF0aW9ucysrO1xuICAgICAgY29uc29sZS5sb2cocGFyYW1ldGVycy5zbGljZSgpKTtcbiAgICAgIFxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKVxuICAgICAgICBncmFkaWVudFtpXSA9IGdldERlcml2YXRpdmUocGFyYW1ldGVycywgaSk7XG5cbiAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICB9XG4gIH07XG5cbiAgbGltaXRlZE1lbW9yeUJGR1Mob3B0aW1pemFibGUsIHBhcmFtcyk7XG4gIGxpbWl0ZWRNZW1vcnlCRkdTKG9wdGltaXphYmxlLCBwYXJhbXMpO1xuXG4gIGxldCBmaXR0ZWRDdXJ2ZSA9ICh4OiBudW1iZXIpID0+e1xuICAgIHJldHVybiBjdXJ2ZUZ1bmN0aW9uKHBhcmFtcywgeCk7XG4gIH1cblxuICBsZXQgdG9wID0gKHg6IG51bWJlcikgPT57XG4gICAgbGV0IHZhbHVlID0gY3VydmVGdW5jdGlvbihwYXJhbXMsIHgpO1xuICAgIGlmIChlcnJvck1vZGVsID09IFwiY29uc3RhbnRcIilcbiAgICAgIHJldHVybiAgdmFsdWUgKyAxLjQqZXJyb3I7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuICB2YWx1ZSArIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbiAgfVxuXG4gIGxldCBlcnJvciA9IGVycm9yTW9kZWwgPT0gXCJjb25zdGFudFwiID9cbiAgb2YoY3VydmVGdW5jdGlvbiwgZGF0YSwgcGFyYW1zKS5jb25zdCA6XG4gIG9mKGN1cnZlRnVuY3Rpb24sIGRhdGEsIHBhcmFtcykubXVsdDtcblxuICBsZXQgYm90dG9tID0gKHg6IG51bWJlcikgPT57XG4gICAgbGV0IHZhbHVlID0gY3VydmVGdW5jdGlvbihwYXJhbXMsIHgpO1xuICAgIGlmIChlcnJvck1vZGVsID09IFwiY29uc3RhbnRcIilcbiAgICAgIHJldHVybiAgdmFsdWUgLSAxLjQqZXJyb3I7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuICB2YWx1ZSAtIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbiAgfVxuXG4gIGxldCBmaXRSZXM6IEZpdFJlc3VsdCA9IHtcbiAgICBwYXJhbWV0ZXJzOiBwYXJhbXMsXG4gICAgZml0dGVkQ3VydmU6IGZpdHRlZEN1cnZlLFxuICAgIGNvbmZpZGVuY2VUb3A6IHRvcCxcbiAgICBjb25maWRlbmNlQm90dG9tOiBib3R0b21cbiAgfTtcblxuICByZXR1cm4gZml0UmVzO1xufVxuXG5cblxuLy8gcGVyZm9ybUZpdCgpOiBGaXRSZXN1bHQge1xuLy8gICBsaW1pdGVkTWVtb3J5QkZHUyh0aGlzLm9wdGltaXphYmxlLCB0aGlzLnBhcmFtcyk7XG4vLyAgIGxpbWl0ZWRNZW1vcnlCRkdTKHRoaXMub3B0aW1pemFibGUsIHRoaXMucGFyYW1zKTtcblxuLy8gICBsZXQgZml0OiBGaXRSZXN1bHQgPSB7XG4vLyAgICAgcGFyYW1ldGVycyA9IHRoaXMucGFyYW1ldGVycztcbi8vICAgfTtcblxuLy8gICByZXR1cm4ge3BhcmFtZXRlcnM6ICwgY3VydmVGdW5jdGlvbjogdGhpcy5jdXJ2ZUZ1bmN0aW9uLCBjb25maWRlbmNlOiB0aGlzLmNvbmZpZGVuY2V9O1xuLy8gfVxuXG5cbi8vIGludGVyZmFjZSBJQ3VydmVGaXR0ZXI8VEFyZz4ge1xuLy8gICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119O1xuLy8gICBwYXJhbXM6IG51bWJlcltdO1xuXG4vLyAgIC8vY3VydmUgZnVuY3Rpb25cbi8vICAgY2YgKHBhcmFtczogbnVtYmVyW10sIGFyZ3M6IFRBcmcpOiBudW1iZXJcbi8vICAgLy9vYmplY3RpdmUgZnVuY3Rpb25cbi8vICAgb2YgKHRhcmdldEZ1bmM6IChwYXJhbXM6IG51bWJlcltdLCBhcmdzOiBUQXJnKSA9PiBudW1iZXIsIFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHtvYnNlcnZlZDogbnVtYmVyW10sIGFyZ3M6IFRBcmdbXX0sXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiBudW1iZXJbXSk6IExpa2VsaWhvb2Rcbi8vIH1cblxuLy8gZXhwb3J0IGNsYXNzIEN1cnZlRml0dGVyPFRBcmcgPSBudW1iZXI+IGltcGxlbWVudHMgSUN1cnZlRml0dGVyPFRBcmc+IHtcbi8vICAgZXJyb3JNb2RlbDogc3RyaW5nO1xuLy8gICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119O1xuLy8gICBwYXJhbXM6IG51bWJlcltdO1xuLy8gICBjZjtcbi8vICAgb2Y7XG4vLyAgIG9wdGltaXphYmxlO1xuLy8gICBmaXRIaXN0b3J5OiB7aXRlcmF0aW9uczogbnVtYmVyLCBwYXJhbWV0ZXJzOiB7W2l0ZXJhdGlvbjogbnVtYmVyXTogbnVtYmVyW119LCBcbi8vICAgICAgICAgICAgICAgICBsaWtlbGlob29kOiB7W2l0ZXJhdGlvbjogbnVtYmVyXTogbnVtYmVyfX0gPSB7XG4vLyAgICAgaXRlcmF0aW9uczogMCxcbi8vICAgICBwYXJhbWV0ZXJzOiB7fSxcbi8vICAgICBsaWtlbGlob29kOiB7fVxuLy8gICB9O1xuXG4vLyAgIGNvbnN0cnVjdG9yKGN1cnZlRnVuY3Rpb246IChwYXJhbXM6IG51bWJlcltdLCBhcmdzOiBUQXJnKSA9PiBudW1iZXIsIFxuLy8gICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuLy8gICAgICAgICAgICAgICBwYXJhbXM6IG51bWJlcltdLFxuLy8gICAgICAgICAgICAgICBlcnJvck1vZGVsOiAnY29uc3RhbnQnIHwgJ3Byb3BvcnRpb25hbCcgPSAnY29uc3RhbnQnLy9pbXBsZW1lbnQgYXMgZW51bVxuLy8gICAgICAgICAgICAgICApIHtcblxuLy8gICAgIGlmKGRhdGEub2JzZXJ2ZWQubGVuZ3RoID09IDAgfHwgZGF0YS5vYnNlcnZlZC5sZW5ndGggIT0gZGF0YS5hcmdzLmxlbmd0aClcbi8vICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBkYXRhJyk7XG4gICAgICBcbi8vICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuLy8gICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuLy8gICAgIHRoaXMuZXJyb3JNb2RlbCA9IGVycm9yTW9kZWw7XG4vLyAgICAgdGhpcy5jZiA9IGN1cnZlRnVuY3Rpb247XG5cbi8vICAgICBzd2l0Y2goZXJyb3JNb2RlbCkge1xuLy8gICAgICAgY2FzZSAnY29uc3RhbnQnOlxuLy8gICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQ29uc3RhbnQ7XG4vLyAgICAgICAgIGJyZWFrO1xuLy8gICAgICAgY2FzZSAncHJvcG9ydGlvbmFsJzpcbi8vICAgICAgICAgdGhpcy5vZiA9IG9iamVjdGl2ZU5vcm1hbFByb3BvcnRpb25hbDtcbi8vICAgICAgICAgYnJlYWs7XG4vLyAgICAgICBkZWZhdWx0OlxuLy8gICAgICAgICB0aGlzLm9mID0gb2JqZWN0aXZlTm9ybWFsQ29uc3RhbnQ7XG4vLyAgICAgICAgIGJyZWFrO1xuLy8gICAgIH1cblxuLy8gICAgIHRoaXMub3B0aW1pemFibGUgPSB7XG4vLyAgICAgICBnZXRWYWx1ZTogKHBhcmFtZXRlcnM6IG51bWJlcltdKSA9PiB7XG4vLyAgICAgICAgIHJldHVybiB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1ldGVycykudmFsdWU7XG4vLyAgICAgICB9LFxuLy8gICAgICAgZ2V0R3JhZGllbnQ6IChwYXJhbWV0ZXJzOiBudW1iZXJbXSwgZ3JhZGllbnQ6IG51bWJlcltdKSA9PiB7XG4vLyAgICAgICAgIGNvbnN0IGxlbmd0aCA9IE9iamVjdC5rZXlzKHRoaXMuZml0SGlzdG9yeS5wYXJhbWV0ZXJzKS5sZW5ndGg7XG4vLyAgICAgICAgIHRoaXMuZml0SGlzdG9yeS5pdGVyYXRpb25zKys7XG4vLyAgICAgICAgIHRoaXMuZml0SGlzdG9yeS5wYXJhbWV0ZXJzW2xlbmd0aF0gPSBwYXJhbWV0ZXJzLnNsaWNlKCk7XG4vLyAgICAgICAgIHRoaXMuZml0SGlzdG9yeS5saWtlbGlob29kW2xlbmd0aF0gPSB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1ldGVycykudmFsdWU7XG4vLyAgICAgICAgIGNvbnNvbGUubG9nKHBhcmFtZXRlcnMuc2xpY2UoKSk7XG4gICAgICAgIFxuLy8gICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlcnMubGVuZ3RoOyBpKyspXG4vLyAgICAgICAgICAgZ3JhZGllbnRbaV0gPSB0aGlzLmdldERlcml2YXRpdmUocGFyYW1ldGVycywgaSk7XG5cbi8vICAgICAgICAgcmV0dXJuIGdyYWRpZW50O1xuLy8gICAgICAgfVxuLy8gICAgIH07XG4vLyAgIH1cblxuLy8gICBwZXJmb3JtRml0KCk6IHZvaWQge1xuLy8gICAgIGxpbWl0ZWRNZW1vcnlCRkdTKHRoaXMub3B0aW1pemFibGUsIHRoaXMucGFyYW1zKTtcbi8vICAgICBsaW1pdGVkTWVtb3J5QkZHUyh0aGlzLm9wdGltaXphYmxlLCB0aGlzLnBhcmFtcyk7XG4vLyAgIH1cblxuLy8gICBnZXQgcGFyYW1ldGVycygpOiBudW1iZXJbXSB7XG4vLyAgICAgcmV0dXJuIHRoaXMucGFyYW1zO1xuLy8gICB9XG5cbi8vICAgZ2V0IGN1cnZlRnVuY3Rpb24oKTogRnVuY3Rpb24ge1xuLy8gICAgIGxldCByZXMgPSAoYXJnOiBUQXJnKSA9Pntcbi8vICAgICAgIGxldCBwYXJhbXMgPSB0aGlzLmZpdEhpc3RvcnkucGFyYW1ldGVyc1t0aGlzLmZpdEhpc3RvcnkuaXRlcmF0aW9ucyAtIDFdO1xuXG4vLyAgICAgICByZXR1cm4gdGhpcy5jZihwYXJhbXMsIGFyZyk7XG4vLyAgICAgfVxuXG4vLyAgICAgcmV0dXJuIHJlcztcbi8vICAgfVxuXG4vLyAgIGdldCBjb25maWRlbmNlKCk6IHt0b3A6RnVuY3Rpb24sIGJvdHRvbTogRnVuY3Rpb259IHtcbi8vICAgICBsZXQgcGFyYW1zID0gdGhpcy5maXRIaXN0b3J5LnBhcmFtZXRlcnNbdGhpcy5maXRIaXN0b3J5Lml0ZXJhdGlvbnMgLSAxXTtcblxuLy8gICAgIGxldCBlcnJvciA9IHRoaXMuZXJyb3JNb2RlbCA9PSBcImNvbnN0YW50XCIgP1xuLy8gICAgICAgICAgICAgICAgIHRoaXMub2YodGhpcy5jZiwgdGhpcy5kYXRhLCBwYXJhbXMpLmNvbnN0IDpcbi8vICAgICAgICAgICAgICAgICB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1zKS5tdWx0O1xuXG4vLyAgICAgbGV0IHRvcCA9IChhcmc6IFRBcmcpID0+e1xuLy8gICAgICAgbGV0IHZhbHVlID0gdGhpcy5jZihwYXJhbXMsIGFyZyk7XG4vLyAgICAgICBpZiAodGhpcy5lcnJvck1vZGVsID09IFwiY29uc3RhbnRcIilcbi8vICAgICAgICAgcmV0dXJuICB2YWx1ZSArIDEuNCplcnJvcjtcbi8vICAgICAgIGVsc2Vcbi8vICAgICAgICAgcmV0dXJuICB2YWx1ZSArIDEuNCooTWF0aC5hYnModmFsdWUpKmVycm9yKTtcbi8vICAgICB9XG5cbi8vICAgICBsZXQgYm90dG9tID0gKGFyZzogVEFyZykgPT57XG4vLyAgICAgICBsZXQgdmFsdWUgPSB0aGlzLmNmKHBhcmFtcywgYXJnKTtcbi8vICAgICAgIGlmICh0aGlzLmVycm9yTW9kZWwgPT0gXCJjb25zdGFudFwiKVxuLy8gICAgICAgICByZXR1cm4gIHZhbHVlIC0gMS40KmVycm9yO1xuLy8gICAgICAgZWxzZVxuLy8gICAgICAgICByZXR1cm4gIHZhbHVlIC0gMS40KihNYXRoLmFicyh2YWx1ZSkqZXJyb3IpO1xuLy8gICAgIH1cblxuLy8gICAgIHJldHVybiB7dG9wOiB0b3AsIGJvdHRvbTogYm90dG9tfTtcbi8vICAgfVxuXG4vLyAgIC8vY2VudHJhbCBkaWZmZXJlbmNlXG4vLyAgIHByaXZhdGUgZ2V0RGVyaXZhdGl2ZShwYXJhbXM6IG51bWJlcltdLCBzZWxlY3RlZFBhcmFtOiBudW1iZXIpOiBudW1iZXIge1xuLy8gICAgIGxldCBzdGVwID0gcGFyYW1zW3NlbGVjdGVkUGFyYW1dKjAuMDAwMTtcbi8vICAgICBzdGVwID0gc3RlcCA9PSAwID8gMC4wMDEgOiBzdGVwOyBcbi8vICAgICBsZXQgcGFyYW1zVG9wOiBudW1iZXJbXSA9IFtdO1xuLy8gICAgIGxldCBwYXJhbXNCb3R0b206IG51bWJlcltdID0gW107XG4vLyAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJhbXMubGVuZ3RoOyBpKyspIHtcbi8vICAgICAgIGlmKGkgPT0gc2VsZWN0ZWRQYXJhbSkge1xuLy8gICAgICAgICBwYXJhbXNUb3AucHVzaChwYXJhbXNbaV0gKyBzdGVwKTtcbi8vICAgICAgICAgcGFyYW1zQm90dG9tLnB1c2gocGFyYW1zW2ldIC0gc3RlcCk7XG4vLyAgICAgICB9IGVsc2Uge1xuLy8gICAgICAgICBwYXJhbXNUb3AucHVzaChwYXJhbXNbaV0pO1xuLy8gICAgICAgICBwYXJhbXNCb3R0b20ucHVzaChwYXJhbXNbaV0pO1xuLy8gICAgICAgfVxuLy8gICAgIH1cbi8vICAgICBjb25zdCBkcnZUb3AgPSB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1zVG9wKS52YWx1ZTtcbi8vICAgICBjb25zdCBkcnZCb3R0b20gPSB0aGlzLm9mKHRoaXMuY2YsIHRoaXMuZGF0YSwgcGFyYW1zQm90dG9tKS52YWx1ZTtcblxuLy8gICAgIHJldHVybiAoZHJ2VG9wIC0gZHJ2Qm90dG9tKS8oMipzdGVwKTtcbi8vICAgfVxuLy8gfVxuXG5leHBvcnQgZnVuY3Rpb24gc2lnbW9pZChwYXJhbXM6IG51bWJlcltdLCB4OiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBBID0gcGFyYW1zWzBdO1xuICBjb25zdCBCID0gcGFyYW1zWzFdO1xuICBjb25zdCBDID0gcGFyYW1zWzJdO1xuICBjb25zdCBEID0gcGFyYW1zWzNdO1xuICBjb25zdCByZXMgPSBEICsgKEEgLSBEKS8oMSArIE1hdGgucG93KDEwLCAoeCAtIEMpKkIpKTtcbiAgcmV0dXJuIHJlcztcbn1cblxuXG5cbmZ1bmN0aW9uIG9iamVjdGl2ZU5vcm1hbENvbnN0YW50IChcbiAgdGFyZ2V0RnVuYzogKHBhcmFtczogbnVtYmVyW10sIHg6IG51bWJlcikgPT4gbnVtYmVyLCBcbiAgZGF0YToge3k6IG51bWJlcltdLCB4OiBudW1iZXJbXX0sXG4gIHBhcmFtczogbnVtYmVyW11cbik6IExpa2VsaWhvb2Qge1xuLy9hc3N1cmUgb2JzZXJ2ZWQgYW5kIGFyZ3Mgc2FtZSBsZW5ndGhcbmNvbnN0IHBpID0gTWF0aC5QSTtcbmxldCBzaWdtYSA9IDA7XG5sZXQgc2lnbWFTcSA9IDA7XG5sZXQgbGlrZWxpaG9vZCA9IDA7XG5cbmxldCByZXNpZHVlc1NxdWFyZXMgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEueC5sZW5ndGgpO1xuZm9yKGxldCBpID0gMDsgaSA8IGRhdGEueC5sZW5ndGg7IGkrKykge1xuY29uc3Qgb2JzID0gZGF0YS55W2ldO1xuY29uc3QgcHJlZCA9IHRhcmdldEZ1bmMocGFyYW1zLCBkYXRhLnhbaV0pO1xucmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG59XG5cbmZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG5zaWdtYVNxICs9IHJlc2lkdWVzU3F1YXJlc1tpXTtcbnNpZ21hU3EgLz0gcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDtcbnNpZ21hID0gTWF0aC5zcXJ0KHNpZ21hU3EpO1xuXG5mb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxubGlrZWxpaG9vZCArPSByZXNpZHVlc1NxdWFyZXNbaV0vc2lnbWFTcSArIE1hdGgubG9nKDIgKiBwaSAqIHNpZ21hU3EpO1xuXG5yZXR1cm4ge3ZhbHVlOiAtbGlrZWxpaG9vZCwgY29uc3Q6IHNpZ21hLCBtdWx0OiAwfTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG59XG5cbmZ1bmN0aW9uIG9iamVjdGl2ZU5vcm1hbFByb3BvcnRpb25hbCAoXG50YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgeDogbnVtYmVyKSA9PiBudW1iZXIsIFxuZGF0YToge3k6IG51bWJlcltdLCB4OiBudW1iZXJbXX0sXG5wYXJhbXM6IG51bWJlcltdXG4pOiBMaWtlbGlob29kIHtcbi8vYXNzdXJlIG9ic2VydmVkIGFuZCBhcmdzIHNhbWUgbGVuZ3RoXG5jb25zdCBwaSA9IE1hdGguUEk7XG5sZXQgc2lnbWEgPSAwO1xubGV0IHNpZ21hU3EgPSAwO1xubGV0IGxpa2VsaWhvb2QgPSAwO1xuXG5sZXQgcmVzaWR1ZXNTcXVhcmVzID0gbmV3IEZsb2F0MzJBcnJheShkYXRhLngubGVuZ3RoKTtcbmZvcihsZXQgaSA9IDA7IGkgPCBkYXRhLngubGVuZ3RoOyBpKyspIHtcbmNvbnN0IG9icyA9IGRhdGEueVtpXTtcbmNvbnN0IHByZWQgPSB0YXJnZXRGdW5jKHBhcmFtcywgZGF0YS54W2ldKVxucmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG59XG5cbmZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG5zaWdtYVNxICs9IHJlc2lkdWVzU3F1YXJlc1tpXTtcbnNpZ21hU3EgLz0gcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDtcbnNpZ21hID0gTWF0aC5zcXJ0KHNpZ21hU3EpO1xuXG5mb3IobGV0IGkgPSAwOyBpIDwgcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDsgaSsrKVxubGlrZWxpaG9vZCArPSByZXNpZHVlc1NxdWFyZXNbaV0vc2lnbWFTcSArIE1hdGgubG9nKDIqcGkqc2lnbWFTcSk7XG5cbnJldHVybiB7dmFsdWU6IC1saWtlbGlob29kLCBjb25zdDogc2lnbWEsIG11bHQ6IDB9OyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbn1cblxuXG5cbi8vIGZ1bmN0aW9uIG9iamVjdGl2ZU5vcm1hbENvbnN0YW50PFRBcmc+IChcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7b2JzZXJ2ZWQ6IG51bWJlcltdLCBhcmdzOiBUQXJnW119LFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogbnVtYmVyW11cbi8vICk6IExpa2VsaWhvb2Qge1xuLy8gICAvL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuLy8gICBjb25zdCBwaSA9IE1hdGguUEk7XG4vLyAgIGxldCBzaWdtYSA9IDA7XG4vLyAgIGxldCBzaWdtYVNxID0gMDtcbi8vICAgbGV0IGxpa2VsaWhvb2QgPSAwO1xuXG4vLyAgIGxldCByZXNpZHVlc1NxdWFyZXMgPSBuZXcgRmxvYXQzMkFycmF5KGRhdGEuYXJncy5sZW5ndGgpO1xuLy8gICBmb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG4vLyAgICAgY29uc3Qgb2JzID0gZGF0YS5vYnNlcnZlZFtpXTtcbi8vICAgICBjb25zdCBwcmVkID0gdGFyZ2V0RnVuYyhwYXJhbXMsIGRhdGEuYXJnc1tpXSk7XG4vLyAgICAgcmVzaWR1ZXNTcXVhcmVzW2ldID0gTWF0aC5wb3cob2JzIC0gcHJlZCwgMik7XG4vLyAgIH1cbiAgXG4vLyAgIGZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG4vLyAgICAgc2lnbWFTcSArPSByZXNpZHVlc1NxdWFyZXNbaV07XG4vLyAgIHNpZ21hU3EgLz0gcmVzaWR1ZXNTcXVhcmVzLmxlbmd0aDtcbi8vICAgc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbi8vICAgZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbi8vICAgICBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMiAqIHBpICogc2lnbWFTcSk7XG5cbi8vICAgcmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuLy8gfVxuXG4vLyBmdW5jdGlvbiBvYmplY3RpdmVOb3JtYWxQcm9wb3J0aW9uYWw8VEFyZz4gKFxuLy8gICB0YXJnZXRGdW5jOiAocGFyYW1zOiBudW1iZXJbXSwgYXJnczogVEFyZykgPT4gbnVtYmVyLCBcbi8vICAgZGF0YToge29ic2VydmVkOiBudW1iZXJbXSwgYXJnczogVEFyZ1tdfSxcbi8vICAgcGFyYW1zOiBudW1iZXJbXVxuLy8gKTogTGlrZWxpaG9vZCB7XG4vLyAvL2Fzc3VyZSBvYnNlcnZlZCBhbmQgYXJncyBzYW1lIGxlbmd0aFxuLy8gY29uc3QgcGkgPSBNYXRoLlBJO1xuLy8gbGV0IHNpZ21hID0gMDtcbi8vIGxldCBzaWdtYVNxID0gMDtcbi8vIGxldCBsaWtlbGlob29kID0gMDtcblxuLy8gbGV0IHJlc2lkdWVzU3F1YXJlcyA9IG5ldyBGbG9hdDMyQXJyYXkoZGF0YS5hcmdzLmxlbmd0aCk7XG4vLyBmb3IobGV0IGkgPSAwOyBpIDwgZGF0YS5hcmdzLmxlbmd0aDsgaSsrKSB7XG4vLyBjb25zdCBvYnMgPSBkYXRhLm9ic2VydmVkW2ldO1xuLy8gY29uc3QgcHJlZCA9IHRhcmdldEZ1bmMocGFyYW1zLCBkYXRhLmFyZ3NbaV0pXG4vLyByZXNpZHVlc1NxdWFyZXNbaV0gPSBNYXRoLnBvdyhvYnMgLSBwcmVkLCAyKTtcbi8vIH1cblxuLy8gZm9yKGxldCBpID0gMDsgaSA8IHJlc2lkdWVzU3F1YXJlcy5sZW5ndGg7IGkrKylcbi8vIHNpZ21hU3EgKz0gcmVzaWR1ZXNTcXVhcmVzW2ldO1xuLy8gc2lnbWFTcSAvPSByZXNpZHVlc1NxdWFyZXMubGVuZ3RoO1xuLy8gc2lnbWEgPSBNYXRoLnNxcnQoc2lnbWFTcSk7XG5cbi8vIGZvcihsZXQgaSA9IDA7IGkgPCByZXNpZHVlc1NxdWFyZXMubGVuZ3RoOyBpKyspXG4vLyBsaWtlbGlob29kICs9IHJlc2lkdWVzU3F1YXJlc1tpXS9zaWdtYVNxICsgTWF0aC5sb2coMipwaSpzaWdtYVNxKTtcblxuLy8gcmV0dXJuIHt2YWx1ZTogLWxpa2VsaWhvb2QsIGNvbnN0OiBzaWdtYSwgbXVsdDogMH07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuLy8gfVxuIl19
|