gx
chenyc
2025-02-12 ea42ff3ebee1eeb3fb29423aa848a249441db81c
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
/**
 * @license
 * Copyright 2018 Google LLC. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =============================================================================
 */
import * as tf from '../index';
import { BROWSER_ENVS, describeWithFlags } from '../jasmine_util';
import { BrowserIndexedDB, browserIndexedDB } from './indexed_db';
import { BrowserLocalStorage, browserLocalStorage } from './local_storage';
import { IORouterRegistry } from './router_registry';
describeWithFlags('IORouterRegistry', BROWSER_ENVS, () => {
    const localStorageRouter = (url) => {
        const scheme = 'localstorage://';
        if (url.startsWith(scheme)) {
            return browserLocalStorage(url.slice(scheme.length));
        }
        else {
            return null;
        }
    };
    const indexedDBRouter = (url) => {
        const scheme = 'indexeddb://';
        if (url.startsWith(scheme)) {
            return browserIndexedDB(url.slice(scheme.length));
        }
        else {
            return null;
        }
    };
    class FakeIOHandler {
        constructor(url1, url2) { }
    }
    const fakeMultiStringRouter = (url) => {
        const scheme = 'foo://';
        if (Array.isArray(url) && url.length === 2) {
            if (url[0].startsWith(scheme) && url[1].startsWith(scheme)) {
                return new FakeIOHandler(url[0], url[1]);
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    };
    let tempRegistryInstance = null;
    beforeEach(() => {
        // Force reset registry for testing.
        // tslint:disable:no-any
        tempRegistryInstance = IORouterRegistry.instance;
        IORouterRegistry.instance = null;
        // tslint:enable:no-any
    });
    afterEach(() => {
        // tslint:disable-next-line:no-any
        IORouterRegistry.instance = tempRegistryInstance;
    });
    it('getSaveHandler succeeds', () => {
        IORouterRegistry.registerSaveRouter(localStorageRouter);
        IORouterRegistry.registerSaveRouter(indexedDBRouter);
        const out1 = tf.io.getSaveHandlers('localstorage://foo-model');
        expect(out1.length).toEqual(1);
        expect(out1[0] instanceof BrowserLocalStorage).toEqual(true);
        const out2 = tf.io.getSaveHandlers('indexeddb://foo-model');
        expect(out2.length).toEqual(1);
        expect(out2[0] instanceof BrowserIndexedDB).toEqual(true);
    });
    it('getLoadHandler succeeds', () => {
        IORouterRegistry.registerLoadRouter(localStorageRouter);
        IORouterRegistry.registerLoadRouter(indexedDBRouter);
        const out1 = tf.io.getLoadHandlers('localstorage://foo-model');
        expect(out1.length).toEqual(1);
        expect(out1[0] instanceof BrowserLocalStorage).toEqual(true);
        const out2 = tf.io.getLoadHandlers('indexeddb://foo-model');
        expect(out2.length).toEqual(1);
        expect(out2[0] instanceof BrowserIndexedDB).toEqual(true);
    });
    it('getLoadHandler with string array argument succeeds', () => {
        IORouterRegistry.registerLoadRouter(fakeMultiStringRouter);
        const loadHandler = IORouterRegistry.getLoadHandlers(['foo:///123', 'foo:///456']);
        expect(loadHandler[0] instanceof FakeIOHandler).toEqual(true);
        expect(IORouterRegistry.getLoadHandlers([
            'foo:///123', 'bar:///456'
        ])).toEqual([]);
        expect(IORouterRegistry.getLoadHandlers(['foo:///123'])).toEqual([]);
        expect(IORouterRegistry.getLoadHandlers('foo:///123')).toEqual([]);
    });
    it('getSaveHandler fails', () => {
        IORouterRegistry.registerSaveRouter(localStorageRouter);
        expect(tf.io.getSaveHandlers('invalidscheme://foo-model')).toEqual([]);
        // Check there is no crosstalk between save and load handlers.
        expect(tf.io.getLoadHandlers('localstorage://foo-model')).toEqual([]);
    });
    const fakeLoadOptionsRouter = (url, loadOptions) => {
        return new FakeLoadOptionsHandler(url, loadOptions);
    };
    class FakeLoadOptionsHandler {
        constructor(url, loadOptions) {
            this.loadOptions = loadOptions;
        }
        get loadOptionsData() {
            return this.loadOptions;
        }
    }
    it('getLoadHandler loadOptions', () => {
        IORouterRegistry.registerLoadRouter(fakeLoadOptionsRouter);
        const loadOptions = {
            onProgress: (fraction) => { },
            fetchFunc: (() => { }),
        };
        const loadHandler = tf.io.getLoadHandlers('foo:///123', loadOptions);
        expect(loadHandler.length).toEqual(1);
        expect(loadHandler[0] instanceof FakeLoadOptionsHandler).toEqual(true);
        // Check callback function passed to IOHandler
        expect(loadHandler[0].loadOptionsData)
            .toBe(loadOptions);
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyX3JlZ2lzdHJ5X3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL2lvL3JvdXRlcl9yZWdpc3RyeV90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxZQUFZLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUVoRSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDaEUsT0FBTyxFQUFDLG1CQUFtQixFQUFFLG1CQUFtQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekUsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFHbkQsaUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLEdBQUcsRUFBRTtJQUN2RCxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUU7UUFDekMsTUFBTSxNQUFNLEdBQUcsaUJBQWlCLENBQUM7UUFDakMsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzFCLE9BQU8sbUJBQW1CLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztTQUN0RDthQUFNO1lBQ0wsT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sZUFBZSxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUU7UUFDdEMsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDO1FBQzlCLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUMxQixPQUFPLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0s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LENBQUMsQ0FBQyxDQUE0QixDQUFDLGVBQWUsQ0FBQzthQUM3RCxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDekIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtCUk9XU0VSX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzfSBmcm9tICcuLi9qYXNtaW5lX3V0aWwnO1xuXG5pbXBvcnQge0Jyb3dzZXJJbmRleGVkREIsIGJyb3dzZXJJbmRleGVkREJ9IGZyb20gJy4vaW5kZXhlZF9kYic7XG5pbXBvcnQge0Jyb3dzZXJMb2NhbFN0b3JhZ2UsIGJyb3dzZXJMb2NhbFN0b3JhZ2V9IGZyb20gJy4vbG9jYWxfc3RvcmFnZSc7XG5pbXBvcnQge0lPUm91dGVyUmVnaXN0cnl9IGZyb20gJy4vcm91dGVyX3JlZ2lzdHJ5JztcbmltcG9ydCB7SU9IYW5kbGVyLCBMb2FkSGFuZGxlciwgTG9hZE9wdGlvbnMsIFNhdmVIYW5kbGVyfSBmcm9tICcuL3R5cGVzJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ0lPUm91dGVyUmVnaXN0cnknLCBCUk9XU0VSX0VOVlMsICgpID0+IHtcbiAgY29uc3QgbG9jYWxTdG9yYWdlUm91dGVyID0gKHVybDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1lID0gJ2xvY2Fsc3RvcmFnZTovLyc7XG4gICAgaWYgKHVybC5zdGFydHNXaXRoKHNjaGVtZSkpIHtcbiAgICAgIHJldHVybiBicm93c2VyTG9jYWxTdG9yYWdlKHVybC5zbGljZShzY2hlbWUubGVuZ3RoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBpbmRleGVkREJSb3V0ZXIgPSAodXJsOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBzY2hlbWUgPSAnaW5kZXhlZGRiOi8vJztcbiAgICBpZiAodXJsLnN0YXJ0c1dpdGgoc2NoZW1lKSkge1xuICAgICAgcmV0dXJuIGJyb3dzZXJJbmRleGVkREIodXJsLnNsaWNlKHNjaGVtZS5sZW5ndGgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuXG4gIGNsYXNzIEZha2VJT0hhbmRsZXIgaW1wbGVtZW50cyBJT0hhbmRsZXIge1xuICAgIGNvbnN0cnVjdG9yKHVybDE6IHN0cmluZywgdXJsMjogc3RyaW5nKSB7fVxuICB9XG5cbiAgY29uc3QgZmFrZU11bHRpU3RyaW5nUm91dGVyID0gKHVybDogc3RyaW5nfHN0cmluZ1tdKSA9PiB7XG4gICAgY29uc3Qgc2NoZW1lID0gJ2ZvbzovLyc7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodXJsKSAmJiB1cmwubGVuZ3RoID09PSAyKSB7XG4gICAgICBpZiAodXJsWzBdLnN0YXJ0c1dpdGgoc2NoZW1lKSAmJiB1cmxbMV0uc3RhcnRzV2l0aChzY2hlbWUpKSB7XG4gICAgICAgIHJldHVybiBuZXcgRmFrZUlPSGFuZGxlcih1cmxbMF0sIHVybFsxXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9O1xuXG4gIGxldCB0ZW1wUmVnaXN0cnlJbnN0YW5jZTogSU9Sb3V0ZXJSZWdpc3RyeSA9IG51bGw7XG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIC8vIEZvcmNlIHJlc2V0IHJlZ2lzdHJ5IGZvciB0ZXN0aW5nLlxuICAgIC8vIHRzbGludDpkaXNhYmxlOm5vLWFueVxuICAgIHRlbXBSZWdpc3RyeUluc3RhbmNlID0gKElPUm91dGVyUmVnaXN0cnkgYXMgYW55KS5pbnN0YW5jZTtcbiAgICAoSU9Sb3V0ZXJSZWdpc3RyeSBhcyBhbnkpLmluc3RhbmNlID0gbnVsbDtcbiAgICAvLyB0c2xpbnQ6ZW5hYmxlOm5vLWFueVxuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAoSU9Sb3V0ZXJSZWdpc3RyeSBhcyBhbnkpLmluc3RhbmNlID0gdGVtcFJlZ2lzdHJ5SW5zdGFuY2U7XG4gIH0pO1xuXG4gIGl0KCdnZXRTYXZlSGFuZGxlciBzdWNjZWVkcycsICgpID0+IHtcbiAgICBJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyU2F2ZVJvdXRlcihsb2NhbFN0b3JhZ2VSb3V0ZXIpO1xuICAgIElPUm91dGVyUmVnaXN0cnkucmVnaXN0ZXJTYXZlUm91dGVyKGluZGV4ZWREQlJvdXRlcik7XG5cbiAgICBjb25zdCBvdXQxID0gdGYuaW8uZ2V0U2F2ZUhhbmRsZXJzKCdsb2NhbHN0b3JhZ2U6Ly9mb28tbW9kZWwnKTtcbiAgICBleHBlY3Qob3V0MS5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgZXhwZWN0KG91dDFbMF0gaW5zdGFuY2VvZiBCcm93c2VyTG9jYWxTdG9yYWdlKS50b0VxdWFsKHRydWUpO1xuICAgIGNvbnN0IG91dDIgPSB0Zi5pby5nZXRTYXZlSGFuZGxlcnMoJ2luZGV4ZWRkYjovL2Zvby1tb2RlbCcpO1xuICAgIGV4cGVjdChvdXQyLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICBleHBlY3Qob3V0MlswXSBpbnN0YW5jZW9mIEJyb3dzZXJJbmRleGVkREIpLnRvRXF1YWwodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdnZXRMb2FkSGFuZGxlciBzdWNjZWVkcycsICgpID0+IHtcbiAgICBJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyTG9hZFJvdXRlcihsb2NhbFN0b3JhZ2VSb3V0ZXIpO1xuICAgIElPUm91dGVyUmVnaXN0cnkucmVnaXN0ZXJMb2FkUm91dGVyKGluZGV4ZWREQlJvdXRlcik7XG5cbiAgICBjb25zdCBvdXQxID0gdGYuaW8uZ2V0TG9hZEhhbmRsZXJzKCdsb2NhbHN0b3JhZ2U6Ly9mb28tbW9kZWwnKTtcbiAgICBleHBlY3Qob3V0MS5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgZXhwZWN0KG91dDFbMF0gaW5zdGFuY2VvZiBCcm93c2VyTG9jYWxTdG9yYWdlKS50b0VxdWFsKHRydWUpO1xuICAgIGNvbnN0IG91dDIgPSB0Zi5pby5nZXRMb2FkSGFuZGxlcnMoJ2luZGV4ZWRkYjovL2Zvby1tb2RlbCcpO1xuICAgIGV4cGVjdChvdXQyLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICBleHBlY3Qob3V0MlswXSBpbnN0YW5jZW9mIEJyb3dzZXJJbmRleGVkREIpLnRvRXF1YWwodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdnZXRMb2FkSGFuZGxlciB3aXRoIHN0cmluZyBhcnJheSBhcmd1bWVudCBzdWNjZWVkcycsICgpID0+IHtcbiAgICBJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyTG9hZFJvdXRlcihmYWtlTXVsdGlTdHJpbmdSb3V0ZXIpO1xuICAgIGNvbnN0IGxvYWRIYW5kbGVyID1cbiAgICAgICAgSU9Sb3V0ZXJSZWdpc3RyeS5nZXRMb2FkSGFuZGxlcnMoWydmb286Ly8vMTIzJywgJ2ZvbzovLy80NTYnXSk7XG4gICAgZXhwZWN0KGxvYWRIYW5kbGVyWzBdIGluc3RhbmNlb2YgRmFrZUlPSGFuZGxlcikudG9FcXVhbCh0cnVlKTtcblxuICAgIGV4cGVjdChJT1JvdXRlclJlZ2lzdHJ5LmdldExvYWRIYW5kbGVycyhbXG4gICAgICAnZm9vOi8vLzEyMycsICdiYXI6Ly8vNDU2J1xuICAgIF0pKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3QoSU9Sb3V0ZXJSZWdpc3RyeS5nZXRMb2FkSGFuZGxlcnMoWydmb286Ly8vMTIzJ10pKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3QoSU9Sb3V0ZXJSZWdpc3RyeS5nZXRMb2FkSGFuZGxlcnMoJ2ZvbzovLy8xMjMnKSkudG9FcXVhbChbXSk7XG4gIH0pO1xuXG4gIGl0KCdnZXRTYXZlSGFuZGxlciBmYWlscycsICgpID0+IHtcbiAgICBJT1JvdXRlclJlZ2lzdHJ5LnJlZ2lzdGVyU2F2ZVJvdXRlcihsb2NhbFN0b3JhZ2VSb3V0ZXIpO1xuXG4gICAgZXhwZWN0KHRmLmlvLmdldFNhdmVIYW5kbGVycygnaW52YWxpZHNjaGVtZTovL2Zvby1tb2RlbCcpKS50b0VxdWFsKFtdKTtcbiAgICAvLyBDaGVjayB0aGVyZSBpcyBubyBjcm9zc3RhbGsgYmV0d2VlbiBzYXZlIGFuZCBsb2FkIGhhbmRsZXJzLlxuICAgIGV4cGVjdCh0Zi5pby5nZXRMb2FkSGFuZGxlcnMoJ2xvY2Fsc3RvcmFnZTovL2Zvby1tb2RlbCcpKS50b0VxdWFsKFtdKTtcbiAgfSk7XG5cbiAgY29uc3QgZmFrZUxvYWRPcHRpb25zUm91dGVyID0gKHVybDogc3RyaW5nLCBsb2FkT3B0aW9ucz86IExvYWRPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBGYWtlTG9hZE9wdGlvbnNIYW5kbGVyKHVybCwgbG9hZE9wdGlvbnMpO1xuICB9O1xuXG4gIGNsYXNzIEZha2VMb2FkT3B0aW9uc0hhbmRsZXIgaW1wbGVtZW50cyBJT0hhbmRsZXIge1xuICAgIHNhdmU/OiBTYXZlSGFuZGxlcjtcbiAgICBsb2FkPzogTG9hZEhhbmRsZXI7XG4gICAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgbG9hZE9wdGlvbnM/OiBMb2FkT3B0aW9ucykge31cbiAgICBnZXQgbG9hZE9wdGlvbnNEYXRhKCkge1xuICAgICAgcmV0dXJuIHRoaXMubG9hZE9wdGlvbnM7XG4gICAgfVxuICB9XG5cbiAgaXQoJ2dldExvYWRIYW5kbGVyIGxvYWRPcHRpb25zJywgKCkgPT4ge1xuICAgIElPUm91dGVyUmVnaXN0cnkucmVnaXN0ZXJMb2FkUm91dGVyKGZha2VMb2FkT3B0aW9uc1JvdXRlcik7XG5cbiAgICBjb25zdCBsb2FkT3B0aW9uczogTG9hZE9wdGlvbnMgPSB7XG4gICAgICBvblByb2dyZXNzOiAoZnJhY3Rpb246IG51bWJlcikgPT4ge30sXG4gICAgICBmZXRjaEZ1bmM6ICgoKCkgPT4ge30pIGFzIHVua25vd24gYXMgdHlwZW9mIGZldGNoKSxcbiAgICB9O1xuICAgIGNvbnN0IGxvYWRIYW5kbGVyID0gdGYuaW8uZ2V0TG9hZEhhbmRsZXJzKCdmb286Ly8vMTIzJywgbG9hZE9wdGlvbnMpO1xuICAgIGV4cGVjdChsb2FkSGFuZGxlci5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgZXhwZWN0KGxvYWRIYW5kbGVyWzBdIGluc3RhbmNlb2YgRmFrZUxvYWRPcHRpb25zSGFuZGxlcikudG9FcXVhbCh0cnVlKTtcbiAgICAvLyBDaGVjayBjYWxsYmFjayBmdW5jdGlvbiBwYXNzZWQgdG8gSU9IYW5kbGVyXG4gICAgZXhwZWN0KChsb2FkSGFuZGxlclswXSBhcyBGYWtlTG9hZE9wdGlvbnNIYW5kbGVyKS5sb2FkT3B0aW9uc0RhdGEpXG4gICAgICAgIC50b0JlKGxvYWRPcHRpb25zKTtcbiAgfSk7XG59KTtcbiJdfQ==