@candidstartup/event-sourced-spreadsheet-data 0.11.0

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/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023-2024, Tim Wiegand
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,10 @@
1
+ [![TypeScript](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2FTheCandidStartup%2Finfinisheet%2Fmain%2Fpackage.json&query=%24.devDependencies.typescript&label=TypeScript&color=blue)](https://github.com/TheCandidStartup/infinisheet/blob/main/README.md#typescript-semantic-versioning)
2
+ [![NPM Version](https://img.shields.io/npm/v/@candidstartup/event-sourced-spreadsheet-data)](https://www.npmjs.com/package/@candidstartup/event-sourced-spreadsheet-data)
3
+ [![NPM bundle size](https://img.shields.io/bundlephobia/minzip/@candidstartup/event-sourced-spreadsheet-data)](https://www.npmjs.com/package/@candidstartup/event-sourced-spreadsheet-data)
4
+ [![Build Status](https://github.com/TheCandidStartup/infinisheet/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/TheCandidStartup/infinisheet/actions/workflows/build.yml)
5
+
6
+ [GitHub](https://github.com/TheCandidStartup/infinisheet/tree/main/packages/event-sourced-spreadsheet-data) | [NPM](https://www.npmjs.com/package/@candidstartup/event-sourced-spreadsheet-data) | [API](https://www.thecandidstartup.org/infinisheet/modules/_candidstartup_event-sourced-spreadsheet-data.html)
7
+
8
+ # @candidstartup/event-sourced-spreadsheet-data
9
+
10
+ Event Sourced implementation of `SpreadsheetData`
@@ -0,0 +1,48 @@
1
+ import { LogEntry, CellValue, SpreadsheetData, EventLog, ItemOffsetMapping, Result, SpreadsheetDataError, ValidationError } from '@candidstartup/infinisheet-types';
2
+
3
+ interface SetCellValueAndFormatLogEntry extends LogEntry {
4
+ type: 'SetCellValueAndFormat';
5
+ row: number;
6
+ column: number;
7
+ value: CellValue;
8
+ format?: string | undefined;
9
+ }
10
+ type SpreadsheetLogEntry = SetCellValueAndFormatLogEntry;
11
+
12
+ /**
13
+ * Branding Enum. Used by {@link EventSourcedSnapshot} to ensure that
14
+ * you'll get a type error if you pass some random object where a `EventSourcedSnapshot`
15
+ * is expected.
16
+ * @internal
17
+ */
18
+ declare enum _EventSourcedSnapshotBrand {
19
+ _DO_NOT_USE = ""
20
+ }
21
+ /**
22
+ * Opaque type representing a {@link SimpleSpreadsheetData} snapshot. All the
23
+ * internal implementation details are hidden from the exported API.
24
+ */
25
+ interface EventSourcedSnapshot {
26
+ /** @internal */
27
+ _brand: _EventSourcedSnapshotBrand;
28
+ }
29
+ /**
30
+ * Event sourced implementation of {@link SpreadsheetData}
31
+ *
32
+ */
33
+ declare class EventSourcedSpreadsheetData implements SpreadsheetData<EventSourcedSnapshot> {
34
+ #private;
35
+ constructor(eventLog: EventLog<SpreadsheetLogEntry>);
36
+ subscribe(onDataChange: () => void): () => void;
37
+ getSnapshot(): EventSourcedSnapshot;
38
+ getRowCount(snapshot: EventSourcedSnapshot): number;
39
+ getRowItemOffsetMapping(_snapshot: EventSourcedSnapshot): ItemOffsetMapping;
40
+ getColumnCount(snapshot: EventSourcedSnapshot): number;
41
+ getColumnItemOffsetMapping(_snapshot: EventSourcedSnapshot): ItemOffsetMapping;
42
+ getCellValue(snapshot: EventSourcedSnapshot, row: number, column: number): CellValue;
43
+ getCellFormat(snapshot: EventSourcedSnapshot, row: number, column: number): string | undefined;
44
+ setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void, SpreadsheetDataError>;
45
+ isValidCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void, ValidationError>;
46
+ }
47
+
48
+ export { type EventSourcedSnapshot, EventSourcedSpreadsheetData, type SetCellValueAndFormatLogEntry, type SpreadsheetLogEntry, _EventSourcedSnapshotBrand };
package/dist/index.js ADDED
@@ -0,0 +1,168 @@
1
+ import { FixedSizeItemOffsetMapping, ok } from '@candidstartup/infinisheet-types';
2
+
3
+ const EVENT_LOG_CHECK_DELAY = 10000;
4
+ /**
5
+ * Branding Enum. Used by {@link EventSourcedSnapshot} to ensure that
6
+ * you'll get a type error if you pass some random object where a `EventSourcedSnapshot`
7
+ * is expected.
8
+ * @internal
9
+ */
10
+ var _EventSourcedSnapshotBrand;
11
+ (function (_EventSourcedSnapshotBrand) {
12
+ _EventSourcedSnapshotBrand["_DO_NOT_USE"] = "";
13
+ })(_EventSourcedSnapshotBrand || (_EventSourcedSnapshotBrand = {}));
14
+ const rowItemOffsetMapping = new FixedSizeItemOffsetMapping(30);
15
+ const columnItemOffsetMapping = new FixedSizeItemOffsetMapping(100);
16
+ function asContent(snapshot) {
17
+ return snapshot;
18
+ }
19
+ function asSnapshot(snapshot) {
20
+ return snapshot;
21
+ }
22
+ /**
23
+ * Event sourced implementation of {@link SpreadsheetData}
24
+ *
25
+ */
26
+ class EventSourcedSpreadsheetData {
27
+ constructor(eventLog) {
28
+ this.#intervalId = undefined;
29
+ this.#isInSyncLogs = false;
30
+ this.#eventLog = eventLog;
31
+ this.#listeners = [];
32
+ this.#content = {
33
+ endSequenceId: 0n,
34
+ logSegment: { startSequenceId: 0n, entries: [] },
35
+ isComplete: false,
36
+ rowCount: 0,
37
+ colCount: 0
38
+ };
39
+ this.#syncLogs();
40
+ }
41
+ subscribe(onDataChange) {
42
+ if (!this.#intervalId)
43
+ this.#intervalId = setInterval(() => { this.#syncLogs(); }, EVENT_LOG_CHECK_DELAY);
44
+ this.#listeners = [...this.#listeners, onDataChange];
45
+ return () => {
46
+ this.#listeners = this.#listeners.filter(l => l !== onDataChange);
47
+ if (this.#listeners.length == 0 && this.#intervalId !== undefined) {
48
+ clearInterval(this.#intervalId);
49
+ this.#intervalId = undefined;
50
+ }
51
+ };
52
+ }
53
+ getSnapshot() {
54
+ return asSnapshot(this.#content);
55
+ }
56
+ getRowCount(snapshot) {
57
+ return asContent(snapshot).rowCount;
58
+ }
59
+ getRowItemOffsetMapping(_snapshot) {
60
+ return rowItemOffsetMapping;
61
+ }
62
+ getColumnCount(snapshot) {
63
+ return asContent(snapshot).colCount;
64
+ }
65
+ getColumnItemOffsetMapping(_snapshot) {
66
+ return columnItemOffsetMapping;
67
+ }
68
+ getCellValue(snapshot, row, column) {
69
+ const entry = this.#getCellValueAndFormatEntry(snapshot, row, column);
70
+ return entry?.value;
71
+ }
72
+ getCellFormat(snapshot, row, column) {
73
+ const entry = this.#getCellValueAndFormatEntry(snapshot, row, column);
74
+ return entry?.format;
75
+ }
76
+ setCellValueAndFormat(row, column, value, format) {
77
+ const curr = this.#content;
78
+ const result = this.#eventLog.addEntry({ type: 'SetCellValueAndFormat', row, column, value, format }, curr.endSequenceId);
79
+ result.andTee(() => {
80
+ if (this.#content == curr) {
81
+ // Nothing else has updated local copy (no async load has snuck in), so safe to do it myself avoiding round trip with event log
82
+ curr.logSegment.entries.push({ type: 'SetCellValueAndFormat', row, column, value, format });
83
+ // Snapshot semantics preserved by treating EventSourcedSnapshot as an immutable data structure which is
84
+ // replaced with a modified copy on every update.
85
+ this.#content = {
86
+ endSequenceId: curr.endSequenceId + 1n,
87
+ logSegment: curr.logSegment,
88
+ isComplete: true,
89
+ rowCount: Math.max(curr.rowCount, row + 1),
90
+ colCount: Math.max(curr.colCount, column + 1)
91
+ };
92
+ this.#notifyListeners();
93
+ }
94
+ }).orElse((err) => { throw Error(err.message); });
95
+ // Oh no, this method needs to become async ...
96
+ return ok();
97
+ }
98
+ isValidCellValueAndFormat(_row, _column, _value, _format) {
99
+ return ok();
100
+ }
101
+ #notifyListeners() {
102
+ for (const listener of this.#listeners)
103
+ listener();
104
+ }
105
+ #getCellValueAndFormatEntry(snapshot, row, column) {
106
+ const content = asContent(snapshot);
107
+ const endIndex = Number(content.endSequenceId - content.logSegment.startSequenceId);
108
+ for (let i = endIndex - 1; i >= 0; i--) {
109
+ const entry = content.logSegment.entries[i];
110
+ if (entry.row == row && entry.column == column)
111
+ return entry;
112
+ }
113
+ return undefined;
114
+ }
115
+ #syncLogs() {
116
+ if (this.#isInSyncLogs)
117
+ return;
118
+ this.#syncLogsAsync().catch((reason) => { throw Error("Rejected promise from #syncLogsAsync", { cause: reason }); });
119
+ }
120
+ async #syncLogsAsync() {
121
+ this.#isInSyncLogs = true;
122
+ // Set up load of first batch of entries
123
+ const segment = this.#content.logSegment;
124
+ let isComplete = false;
125
+ while (!isComplete) {
126
+ const curr = this.#content;
127
+ const start = (segment.entries.length == 0) ? 'snapshot' : curr.endSequenceId;
128
+ const result = await this.#eventLog.query(start, 'end');
129
+ if (!result.isOk()) {
130
+ // Depending on error may need to retry (limited times, jitter and backoff), reload from scratch or panic
131
+ throw Error("Error querying log entries");
132
+ }
133
+ // Extend the current loaded segment.
134
+ // Once snapshots supported need to look out for new snapshot and start new segment
135
+ const value = result.value;
136
+ if (segment.entries.length == 0)
137
+ segment.startSequenceId = value.startSequenceId;
138
+ else if (curr.endSequenceId != value.startSequenceId)
139
+ throw Error(`Query returned start ${value.startSequenceId}, expected ${curr.endSequenceId}`);
140
+ isComplete = value.isComplete;
141
+ if (value.entries.length > 0) {
142
+ segment.entries.push(...value.entries);
143
+ // Create a new snapshot based on the new data
144
+ let rowCount = curr.rowCount;
145
+ let colCount = curr.colCount;
146
+ for (const entry of value.entries) {
147
+ rowCount = Math.max(rowCount, entry.row + 1);
148
+ colCount = Math.max(colCount, entry.column + 1);
149
+ }
150
+ this.#content = {
151
+ endSequenceId: value.endSequenceId,
152
+ logSegment: segment,
153
+ isComplete, rowCount, colCount
154
+ };
155
+ this.#notifyListeners();
156
+ }
157
+ }
158
+ this.#isInSyncLogs = false;
159
+ }
160
+ #intervalId;
161
+ #isInSyncLogs;
162
+ #eventLog;
163
+ #listeners;
164
+ #content;
165
+ }
166
+
167
+ export { EventSourcedSpreadsheetData, _EventSourcedSnapshotBrand };
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/EventSourcedSpreadsheetData.ts"],"sourcesContent":["import type { CellValue, SpreadsheetData, ItemOffsetMapping, Result, \n SpreadsheetDataError, ValidationError, SequenceId, BlobId, EventLog } from \"@candidstartup/infinisheet-types\";\nimport { FixedSizeItemOffsetMapping, ok } from \"@candidstartup/infinisheet-types\";\n\nimport type { SpreadsheetLogEntry, SetCellValueAndFormatLogEntry } from \"./SpreadsheetLogEntry\";\n\nconst EVENT_LOG_CHECK_DELAY = 10000;\n\ninterface LogSegment {\n startSequenceId: SequenceId;\n entries: SpreadsheetLogEntry[];\n snapshot?: BlobId | undefined;\n}\n\ninterface EventSourcedSnapshotContent {\n endSequenceId: SequenceId;\n logSegment: LogSegment;\n isComplete: boolean;\n rowCount: number;\n colCount: number;\n}\n\n/** \n * Branding Enum. Used by {@link EventSourcedSnapshot} to ensure that\n * you'll get a type error if you pass some random object where a `EventSourcedSnapshot`\n * is expected.\n * @internal\n */\nexport enum _EventSourcedSnapshotBrand { _DO_NOT_USE=\"\" };\n\n/**\n * Opaque type representing a {@link SimpleSpreadsheetData} snapshot. All the\n * internal implementation details are hidden from the exported API.\n */\nexport interface EventSourcedSnapshot {\n /** @internal */\n _brand: _EventSourcedSnapshotBrand;\n}\n\nconst rowItemOffsetMapping = new FixedSizeItemOffsetMapping(30);\nconst columnItemOffsetMapping = new FixedSizeItemOffsetMapping(100);\n\nfunction asContent(snapshot: EventSourcedSnapshot) {\n return snapshot as unknown as EventSourcedSnapshotContent;\n}\n\nfunction asSnapshot(snapshot: EventSourcedSnapshotContent) {\n return snapshot as unknown as EventSourcedSnapshot;\n}\n\n/**\n * Event sourced implementation of {@link SpreadsheetData}\n *\n */\nexport class EventSourcedSpreadsheetData implements SpreadsheetData<EventSourcedSnapshot> {\n constructor (eventLog: EventLog<SpreadsheetLogEntry>) {\n this.#intervalId = undefined;\n this.#isInSyncLogs = false;\n this.#eventLog = eventLog;\n this.#listeners = [];\n this.#content = {\n endSequenceId: 0n,\n logSegment: { startSequenceId: 0n, entries: [] },\n isComplete: false,\n rowCount: 0,\n colCount: 0\n }\n\n this.#syncLogs();\n }\n\n subscribe(onDataChange: () => void): () => void {\n if (!this.#intervalId)\n this.#intervalId = setInterval(() => { this.#syncLogs() }, EVENT_LOG_CHECK_DELAY);\n this.#listeners = [...this.#listeners, onDataChange];\n return () => {\n this.#listeners = this.#listeners.filter(l => l !== onDataChange);\n if (this.#listeners.length == 0 && this.#intervalId !== undefined) {\n clearInterval(this.#intervalId);\n this.#intervalId = undefined;\n }\n }\n }\n\n getSnapshot(): EventSourcedSnapshot {\n return asSnapshot(this.#content);\n }\n\n getRowCount(snapshot: EventSourcedSnapshot): number {\n return asContent(snapshot).rowCount;\n }\n\n getRowItemOffsetMapping(_snapshot: EventSourcedSnapshot): ItemOffsetMapping {\n return rowItemOffsetMapping;\n }\n\n getColumnCount(snapshot: EventSourcedSnapshot): number {\n return asContent(snapshot).colCount;\n }\n\n getColumnItemOffsetMapping(_snapshot: EventSourcedSnapshot): ItemOffsetMapping {\n return columnItemOffsetMapping\n }\n\n getCellValue(snapshot: EventSourcedSnapshot, row: number, column: number): CellValue {\n const entry = this.#getCellValueAndFormatEntry(snapshot, row, column);\n return entry?.value;\n }\n\n getCellFormat(snapshot: EventSourcedSnapshot, row: number, column: number): string | undefined {\n const entry = this.#getCellValueAndFormatEntry(snapshot, row, column);\n return entry?.format;\n }\n\n setCellValueAndFormat(row: number, column: number, value: CellValue, format: string | undefined): Result<void,SpreadsheetDataError> {\n const curr = this.#content;\n\n const result = this.#eventLog.addEntry({ type: 'SetCellValueAndFormat', row, column, value, format}, curr.endSequenceId);\n result.andTee(() => {\n if (this.#content == curr) {\n // Nothing else has updated local copy (no async load has snuck in), so safe to do it myself avoiding round trip with event log\n curr.logSegment.entries.push({ type: 'SetCellValueAndFormat', row, column, value, format});\n\n // Snapshot semantics preserved by treating EventSourcedSnapshot as an immutable data structure which is \n // replaced with a modified copy on every update.\n this.#content = {\n endSequenceId: curr.endSequenceId + 1n,\n logSegment: curr.logSegment,\n isComplete: true,\n rowCount: Math.max(curr.rowCount, row+1),\n colCount: Math.max(curr.colCount, column+1)\n }\n\n this.#notifyListeners();\n }\n }).orElse((err) => { throw Error(err.message); });\n\n // Oh no, this method needs to become async ...\n return ok();\n }\n\n isValidCellValueAndFormat(_row: number, _column: number, _value: CellValue, _format: string | undefined): Result<void,ValidationError> {\n return ok(); \n }\n\n #notifyListeners() {\n for (const listener of this.#listeners)\n listener();\n }\n\n #getCellValueAndFormatEntry(snapshot: EventSourcedSnapshot, row: number, column: number): SetCellValueAndFormatLogEntry | undefined {\n const content = asContent(snapshot);\n const endIndex = Number(content.endSequenceId-content.logSegment.startSequenceId);\n for (let i = endIndex-1; i >= 0; i --) {\n const entry = content.logSegment.entries[i]!;\n if (entry.row == row && entry.column == column)\n return entry;\n }\n return undefined;\n }\n\n #syncLogs(): void {\n if (this.#isInSyncLogs)\n return;\n\n this.#syncLogsAsync().catch((reason) => { throw Error(\"Rejected promise from #syncLogsAsync\", { cause: reason }) });\n }\n\n async #syncLogsAsync(): Promise<void> {\n this.#isInSyncLogs = true;\n\n // Set up load of first batch of entries\n const segment = this.#content.logSegment;\n let isComplete = false;\n\n while (!isComplete) {\n const curr = this.#content;\n const start = (segment.entries.length == 0) ? 'snapshot' : curr.endSequenceId;\n const result = await this.#eventLog.query(start, 'end');\n\n if (!result.isOk()) {\n // Depending on error may need to retry (limited times, jitter and backoff), reload from scratch or panic\n throw Error(\"Error querying log entries\");\n }\n\n // Extend the current loaded segment.\n // Once snapshots supported need to look out for new snapshot and start new segment\n const value = result.value;\n if (segment.entries.length == 0)\n segment.startSequenceId = value.startSequenceId;\n else if (curr.endSequenceId != value.startSequenceId)\n throw Error(`Query returned start ${value.startSequenceId}, expected ${curr.endSequenceId}`);\n isComplete = value.isComplete;\n\n if (value.entries.length > 0) {\n segment.entries.push(...value.entries);\n\n // Create a new snapshot based on the new data\n let rowCount = curr.rowCount;\n let colCount = curr.colCount;\n for (const entry of value.entries) {\n rowCount = Math.max(rowCount, entry.row+1);\n colCount = Math.max(colCount, entry.column+1);\n }\n\n this.#content = {\n endSequenceId: value.endSequenceId,\n logSegment: segment,\n isComplete, rowCount, colCount\n }\n\n this.#notifyListeners();\n }\n }\n\n this.#isInSyncLogs = false;\n }\n\n #intervalId: ReturnType<typeof setInterval> | undefined;\n #isInSyncLogs: boolean;\n #eventLog: EventLog<SpreadsheetLogEntry>;\n #listeners: (() => void)[];\n #content: EventSourcedSnapshotContent;\n}\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@candidstartup/event-sourced-spreadsheet-data",
3
+ "private": false,
4
+ "version": "0.11.0",
5
+ "description": "Event sourced implementation of SpreadsheetData",
6
+ "author": "Tim Wiegand <tim.wiegand@thecandidstartup.org>",
7
+ "license": "BSD-3-Clause",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/TheCandidStartup/infinisheet.git",
11
+ "directory": "packages/event-sourced-spreadsheet-data"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/TheCandidStartup/infinisheet/issues"
15
+ },
16
+ "homepage": "https://github.com/TheCandidStartup/infinisheet/blob/main/packages/event-sourced-spreadsheet-data/README.md",
17
+ "keywords": [
18
+ "typescript",
19
+ "spreadsheet",
20
+ "infinisheet"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "type": "module",
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ }
36
+ },
37
+ "scripts": {
38
+ "dev": "vite",
39
+ "clean": "rimraf {dist,temp}",
40
+ "prebuild": "npm run clean",
41
+ "typecheck": "tsc -p tsconfig.json",
42
+ "build-tsc": "tsc -p tsconfig.build.json",
43
+ "build-rollup": "rollup -c ../rollup.config.mjs",
44
+ "build": "npm run build-rollup",
45
+ "lint": "eslint . --report-unused-disable-directives --max-warnings 0",
46
+ "devapi": "api-extractor run --local",
47
+ "prodapi": "api-extractor run",
48
+ "devbuild": "npm run build && npm run lint && npm run devapi",
49
+ "test": "vitest"
50
+ },
51
+ "dependencies": {
52
+ "@candidstartup/infinisheet-types": "^0.11.0"
53
+ },
54
+ "gitHead": "0c72d04996502cb84f8720972bfda453e4989106"
55
+ }