@bitgo-beta/blockapis 1.3.3-alpha.0 → 1.3.3-alpha.2

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.
@@ -0,0 +1,16 @@
1
+ import { BaseHttpClient, HttpClient, Response } from './BaseHttpClient';
2
+ export declare class CachingHttpClient implements HttpClient {
3
+ private cacheDir;
4
+ client: BaseHttpClient;
5
+ isHttpEnabled: boolean;
6
+ constructor(cacheDir: string, { client, isHttpEnabled }?: {
7
+ client?: BaseHttpClient | undefined;
8
+ isHttpEnabled?: boolean | undefined;
9
+ });
10
+ cachePath(p: string): string;
11
+ readCache<T>(path: string): Promise<Response<T> | undefined>;
12
+ writeCache<T>(path: string, data: T): Promise<void>;
13
+ get<T>(path: string): Promise<Response<T>>;
14
+ withBaseUrl(baseUrl: string): HttpClient;
15
+ }
16
+ //# sourceMappingURL=CachingHttpClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CachingHttpClient.d.ts","sourceRoot":"","sources":["../../src/CachingHttpClient.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQxE,qBAAa,iBAAkB,YAAW,UAAU;IAItC,OAAO,CAAC,QAAQ;IAH5B,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;gBAEH,QAAQ,EAAE,MAAM,EAAE,EAAE,MAA6B,EAAE,aAAoB,EAAE;;;KAAK;IAKlG,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAMtB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAkB5D,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAgBhD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CAMzC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CachingHttpClient = void 0;
4
+ const url_1 = require("url");
5
+ const path = require("path");
6
+ const crypto = require("crypto");
7
+ const fs_1 = require("fs");
8
+ const BaseHttpClient_1 = require("./BaseHttpClient");
9
+ function stripApiTokens(uri) {
10
+ const url = new url_1.URL(uri, 'http://localhost');
11
+ url.searchParams.delete('key');
12
+ return url.pathname + url.searchParams;
13
+ }
14
+ class CachingHttpClient {
15
+ constructor(cacheDir, { client = new BaseHttpClient_1.BaseHttpClient(), isHttpEnabled = true } = {}) {
16
+ this.cacheDir = cacheDir;
17
+ this.client = client;
18
+ this.isHttpEnabled = isHttpEnabled;
19
+ }
20
+ cachePath(p) {
21
+ p = stripApiTokens(p).replace(/[^a-z0-9]/gi, '_');
22
+ const hash = crypto.createHash('sha256').update(p).digest().toString('hex').slice(0, 8);
23
+ return path.join(this.cacheDir, `${p}.${hash}.json`);
24
+ }
25
+ async readCache(path) {
26
+ let data;
27
+ try {
28
+ data = await fs_1.promises.readFile(this.cachePath(path), 'utf8');
29
+ }
30
+ catch (e) {
31
+ if (e.code === 'ENOENT') {
32
+ return;
33
+ }
34
+ throw e;
35
+ }
36
+ return {
37
+ map(f) {
38
+ return f(JSON.parse(data));
39
+ },
40
+ };
41
+ }
42
+ async writeCache(path, data) {
43
+ await fs_1.promises.writeFile(this.cachePath(path), JSON.stringify(data, null, 2), 'utf8');
44
+ }
45
+ async get(path) {
46
+ const cached = await this.readCache(path);
47
+ if (cached) {
48
+ return cached;
49
+ }
50
+ if (!this.isHttpEnabled) {
51
+ throw new Error(`networking disabled`);
52
+ }
53
+ const resp = await this.client.get(path);
54
+ await this.writeCache(path, resp.map((v) => v));
55
+ return resp;
56
+ }
57
+ withBaseUrl(baseUrl) {
58
+ return new CachingHttpClient(this.cacheDir, {
59
+ client: this.client.withBaseUrl(baseUrl),
60
+ isHttpEnabled: this.isHttpEnabled,
61
+ });
62
+ }
63
+ }
64
+ exports.CachingHttpClient = CachingHttpClient;
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FjaGluZ0h0dHBDbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvQ2FjaGluZ0h0dHBDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTBCO0FBQzFCLDZCQUE2QjtBQUM3QixpQ0FBaUM7QUFDakMsMkJBQW9DO0FBRXBDLHFEQUF3RTtBQUV4RSxTQUFTLGNBQWMsQ0FBQyxHQUFXO0lBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksU0FBRyxDQUFDLEdBQUcsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0lBQzdDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9CLE9BQU8sR0FBRyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDO0FBQ3pDLENBQUM7QUFFRCxNQUFhLGlCQUFpQjtJQUk1QixZQUFvQixRQUFnQixFQUFFLEVBQUUsTUFBTSxHQUFHLElBQUksK0JBQWMsRUFBRSxFQUFFLGFBQWEsR0FBRyxJQUFJLEVBQUUsR0FBRyxFQUFFO1FBQTlFLGFBQVEsR0FBUixRQUFRLENBQVE7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7SUFDckMsQ0FBQztJQUVELFNBQVMsQ0FBQyxDQUFTO1FBQ2pCLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUyxDQUFJLElBQVk7UUFDN0IsSUFBSSxJQUFZLENBQUM7UUFDakIsSUFBSTtZQUNGLElBQUksR0FBRyxNQUFNLGFBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztTQUN4RDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsSUFBSyxDQUFTLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtnQkFDaEMsT0FBTzthQUNSO1lBQ0QsTUFBTSxDQUFDLENBQUM7U0FDVDtRQUVELE9BQU87WUFDTCxHQUFHLENBQUksQ0FBaUI7Z0JBQ3RCLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM3QixDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFJLElBQVksRUFBRSxJQUFPO1FBQ3ZDLE1BQU0sYUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRUQsS0FBSyxDQUFDLEdBQUcsQ0FBSSxJQUFZO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBSSxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLE1BQU0sRUFBRTtZQUNWLE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7U0FDeEM7UUFDRCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFJLElBQUksQ0FBQyxDQUFDO1FBQzVDLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FDbkIsSUFBSSxFQUNKLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUNuQixDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQWU7UUFDekIsT0FBTyxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDMUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztZQUN4QyxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBM0RELDhDQTJEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFVSTCB9IGZyb20gJ3VybCc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBwcm9taXNlcyBhcyBmcyB9IGZyb20gJ2ZzJztcblxuaW1wb3J0IHsgQmFzZUh0dHBDbGllbnQsIEh0dHBDbGllbnQsIFJlc3BvbnNlIH0gZnJvbSAnLi9CYXNlSHR0cENsaWVudCc7XG5cbmZ1bmN0aW9uIHN0cmlwQXBpVG9rZW5zKHVyaTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsID0gbmV3IFVSTCh1cmksICdodHRwOi8vbG9jYWxob3N0Jyk7XG4gIHVybC5zZWFyY2hQYXJhbXMuZGVsZXRlKCdrZXknKTtcbiAgcmV0dXJuIHVybC5wYXRobmFtZSArIHVybC5zZWFyY2hQYXJhbXM7XG59XG5cbmV4cG9ydCBjbGFzcyBDYWNoaW5nSHR0cENsaWVudCBpbXBsZW1lbnRzIEh0dHBDbGllbnQge1xuICBjbGllbnQ6IEJhc2VIdHRwQ2xpZW50O1xuICBpc0h0dHBFbmFibGVkOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2FjaGVEaXI6IHN0cmluZywgeyBjbGllbnQgPSBuZXcgQmFzZUh0dHBDbGllbnQoKSwgaXNIdHRwRW5hYmxlZCA9IHRydWUgfSA9IHt9KSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5pc0h0dHBFbmFibGVkID0gaXNIdHRwRW5hYmxlZDtcbiAgfVxuXG4gIGNhY2hlUGF0aChwOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHAgPSBzdHJpcEFwaVRva2VucyhwKS5yZXBsYWNlKC9bXmEtejAtOV0vZ2ksICdfJyk7XG4gICAgY29uc3QgaGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUocCkuZGlnZXN0KCkudG9TdHJpbmcoJ2hleCcpLnNsaWNlKDAsIDgpO1xuICAgIHJldHVybiBwYXRoLmpvaW4odGhpcy5jYWNoZURpciwgYCR7cH0uJHtoYXNofS5qc29uYCk7XG4gIH1cblxuICBhc3luYyByZWFkQ2FjaGU8VD4ocGF0aDogc3RyaW5nKTogUHJvbWlzZTxSZXNwb25zZTxUPiB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBkYXRhOiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGRhdGEgPSBhd2FpdCBmcy5yZWFkRmlsZSh0aGlzLmNhY2hlUGF0aChwYXRoKSwgJ3V0ZjgnKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoKGUgYXMgYW55KS5jb2RlID09PSAnRU5PRU5UJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBtYXA8Vj4oZjogKGJvZHk6IFQpID0+IFYpIHtcbiAgICAgICAgcmV0dXJuIGYoSlNPTi5wYXJzZShkYXRhKSk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBhc3luYyB3cml0ZUNhY2hlPFQ+KHBhdGg6IHN0cmluZywgZGF0YTogVCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0aGlzLmNhY2hlUGF0aChwYXRoKSwgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMiksICd1dGY4Jyk7XG4gIH1cblxuICBhc3luYyBnZXQ8VD4ocGF0aDogc3RyaW5nKTogUHJvbWlzZTxSZXNwb25zZTxUPj4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGF3YWl0IHRoaXMucmVhZENhY2hlPFQ+KHBhdGgpO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuICAgIGlmICghdGhpcy5pc0h0dHBFbmFibGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG5ldHdvcmtpbmcgZGlzYWJsZWRgKTtcbiAgICB9XG4gICAgY29uc3QgcmVzcCA9IGF3YWl0IHRoaXMuY2xpZW50LmdldDxUPihwYXRoKTtcbiAgICBhd2FpdCB0aGlzLndyaXRlQ2FjaGUoXG4gICAgICBwYXRoLFxuICAgICAgcmVzcC5tYXAoKHYpID0+IHYpXG4gICAgKTtcbiAgICByZXR1cm4gcmVzcDtcbiAgfVxuXG4gIHdpdGhCYXNlVXJsKGJhc2VVcmw6IHN0cmluZyk6IEh0dHBDbGllbnQge1xuICAgIHJldHVybiBuZXcgQ2FjaGluZ0h0dHBDbGllbnQodGhpcy5jYWNoZURpciwge1xuICAgICAgY2xpZW50OiB0aGlzLmNsaWVudC53aXRoQmFzZVVybChiYXNlVXJsKSxcbiAgICAgIGlzSHR0cEVuYWJsZWQ6IHRoaXMuaXNIdHRwRW5hYmxlZCxcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -3,6 +3,7 @@ export * from './AddressApi';
3
3
  export * from './TransactionApi';
4
4
  export * from './UtxoApi';
5
5
  export * from './BaseHttpClient';
6
+ export * from './CachingHttpClient';
6
7
  export * from './impl/BlockchairApi';
7
8
  export * from './impl/BlockstreamApi';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
package/dist/src/index.js CHANGED
@@ -15,6 +15,7 @@ __exportStar(require("./AddressApi"), exports);
15
15
  __exportStar(require("./TransactionApi"), exports);
16
16
  __exportStar(require("./UtxoApi"), exports);
17
17
  __exportStar(require("./BaseHttpClient"), exports);
18
+ __exportStar(require("./CachingHttpClient"), exports);
18
19
  __exportStar(require("./impl/BlockchairApi"), exports);
19
20
  __exportStar(require("./impl/BlockstreamApi"), exports);
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQTZCO0FBQzdCLCtDQUE2QjtBQUM3QixtREFBaUM7QUFDakMsNENBQTBCO0FBQzFCLG1EQUFpQztBQUVqQyx1REFBcUM7QUFDckMsd0RBQXNDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9BcGlCdWlsZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vQWRkcmVzc0FwaSc7XG5leHBvcnQgKiBmcm9tICcuL1RyYW5zYWN0aW9uQXBpJztcbmV4cG9ydCAqIGZyb20gJy4vVXR4b0FwaSc7XG5leHBvcnQgKiBmcm9tICcuL0Jhc2VIdHRwQ2xpZW50JztcblxuZXhwb3J0ICogZnJvbSAnLi9pbXBsL0Jsb2NrY2hhaXJBcGknO1xuZXhwb3J0ICogZnJvbSAnLi9pbXBsL0Jsb2Nrc3RyZWFtQXBpJztcbiJdfQ==
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsK0NBQTZCO0FBQzdCLCtDQUE2QjtBQUM3QixtREFBaUM7QUFDakMsNENBQTBCO0FBQzFCLG1EQUFpQztBQUNqQyxzREFBb0M7QUFFcEMsdURBQXFDO0FBQ3JDLHdEQUFzQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vQXBpQnVpbGRlcic7XG5leHBvcnQgKiBmcm9tICcuL0FkZHJlc3NBcGknO1xuZXhwb3J0ICogZnJvbSAnLi9UcmFuc2FjdGlvbkFwaSc7XG5leHBvcnQgKiBmcm9tICcuL1V0eG9BcGknO1xuZXhwb3J0ICogZnJvbSAnLi9CYXNlSHR0cENsaWVudCc7XG5leHBvcnQgKiBmcm9tICcuL0NhY2hpbmdIdHRwQ2xpZW50JztcblxuZXhwb3J0ICogZnJvbSAnLi9pbXBsL0Jsb2NrY2hhaXJBcGknO1xuZXhwb3J0ICogZnJvbSAnLi9pbXBsL0Jsb2Nrc3RyZWFtQXBpJztcbiJdfQ==
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitgo-beta/blockapis",
3
3
  "description": "Access public block explorer APIs for a variety of coins",
4
- "version": "1.3.3-alpha.0",
4
+ "version": "1.3.3-alpha.2",
5
5
  "main": "dist/src/index.js",
6
6
  "files": [
7
7
  "dist/src/**/*"
@@ -22,7 +22,7 @@
22
22
  "directory": "modules/blockapis"
23
23
  },
24
24
  "dependencies": {
25
- "@bitgo-beta/utxo-lib": "4.0.1-alpha.0",
25
+ "@bitgo-beta/utxo-lib": "4.0.1-alpha.2",
26
26
  "@types/superagent": "4.1.15",
27
27
  "bluebird": "^3.7.2",
28
28
  "superagent": "^7.1.1"
@@ -37,5 +37,5 @@
37
37
  "access": "public"
38
38
  },
39
39
  "license": "MIT",
40
- "gitHead": "a6b8d2439a0706feeea464d920e8103177883617"
40
+ "gitHead": "57b13fa1fa91c3514a378de0e661f94e9748f1fa"
41
41
  }