@fireproof/core 0.3.2 → 0.3.4
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/README.md +1 -1
- package/package.json +39 -5
- package/src/blockstore.js +3 -2
- package/src/clock.js +4 -3
- package/src/crypto.js +1 -0
- package/src/db-index.js +10 -5
- package/src/fireproof.js +15 -10
- package/src/hydrator.js +3 -3
- package/src/index.js +6 -0
- package/src/listener.js +2 -1
- package/src/prolly.js +11 -24
- package/src/sha1.js +2 -1
- package/src/valet.js +7 -5
- package/hooks/use-fireproof.js +0 -135
- package/index.js +0 -6
- package/scripts/keygen.js +0 -3
- package/test/block.js +0 -65
- package/test/clock.test.js +0 -694
- package/test/db-index.test.js +0 -261
- package/test/fireproof.test.js +0 -493
- package/test/fulltext.test.js +0 -66
- package/test/helpers.js +0 -45
- package/test/hydrator.test.js +0 -81
- package/test/listener.test.js +0 -102
- package/test/prolly.test.js +0 -190
- package/test/proofs.test.js +0 -53
- package/test/reproduce-fixture-bug.test.js +0 -65
- package/test/valet.test.js +0 -59
package/test/listener.test.js
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import Blockstore from '../src/blockstore.js'
|
4
|
-
import Fireproof from '../src/fireproof.js'
|
5
|
-
import Listener from '../src/listener.js'
|
6
|
-
import Hydrator from '../src/hydrator.js'
|
7
|
-
|
8
|
-
let database, listener, star
|
9
|
-
|
10
|
-
describe('Listener', () => {
|
11
|
-
beforeEach(async () => {
|
12
|
-
database = new Fireproof(new Blockstore(), []) // todo: these need a cloud name aka w3name, add this after we have cloud storage of blocks
|
13
|
-
const docs = [ // dave is first today
|
14
|
-
{ _id: 'd4s3b32a-3c3a', name: 'dave', age: 48 },
|
15
|
-
{ _id: 'a1s3b32a-3c3a', name: 'alice', age: 40 },
|
16
|
-
{ _id: 'b2s3b32a-3c3a', name: 'bob', age: 40 },
|
17
|
-
{ _id: 'c3s3b32a-3c3a', name: 'carol', age: 43 },
|
18
|
-
{ _id: 'e4s3b32a-3c3a', name: 'emily', age: 4 },
|
19
|
-
{ _id: 'f4s3b32a-3c3a', name: 'frank', age: 7 }
|
20
|
-
]
|
21
|
-
for (const doc of docs) {
|
22
|
-
const id = doc._id
|
23
|
-
const response = await database.put(doc)
|
24
|
-
assert(response)
|
25
|
-
assert(response.id, 'should have id')
|
26
|
-
assert.equal(response.id, id)
|
27
|
-
}
|
28
|
-
listener = new Listener(database, function (doc, emit) {
|
29
|
-
if (doc.name) { emit('person') }
|
30
|
-
})
|
31
|
-
star = new Listener(database)
|
32
|
-
})
|
33
|
-
it('all listeners get the reset event', (done) => {
|
34
|
-
let count = 0
|
35
|
-
const check = () => {
|
36
|
-
count++
|
37
|
-
if (count === 3) done()
|
38
|
-
}
|
39
|
-
const startClock = database.clock
|
40
|
-
database.put({ _id: 'k645-87tk', name: 'karl' }).then((ok) => {
|
41
|
-
listener.on('person', check)
|
42
|
-
listener.on('not-found', check)
|
43
|
-
star.on('*', check)
|
44
|
-
database.put({ _id: 'k645-87tk', name: 'karl2' }).then((ok) => {
|
45
|
-
assert(ok.id)
|
46
|
-
assert.notEqual(database.clock, startClock)
|
47
|
-
Hydrator.zoom(database, startClock)
|
48
|
-
}).catch(done)
|
49
|
-
})
|
50
|
-
})
|
51
|
-
|
52
|
-
it('can listen to all events', (done) => {
|
53
|
-
star.on('*', (key) => {
|
54
|
-
assert.equal(key, 'i645-87ti')
|
55
|
-
done()
|
56
|
-
})
|
57
|
-
database.put({ _id: 'i645-87ti', name: 'isaac' }).then((ok) => {
|
58
|
-
assert(ok.id)
|
59
|
-
}).catch(done)
|
60
|
-
})
|
61
|
-
it('shares only new events by default', (done) => {
|
62
|
-
listener.on('person', (key) => {
|
63
|
-
assert.equal(key, 'g645-87tg')
|
64
|
-
done()
|
65
|
-
})
|
66
|
-
database.put({ _id: 'g645-87tg', name: 'gwen' }).then((ok) => {
|
67
|
-
assert(ok.id)
|
68
|
-
}).catch(done)
|
69
|
-
}).timeout(200)
|
70
|
-
it('shares all events if asked', async () => {
|
71
|
-
let people = 0
|
72
|
-
listener.on('person', (key) => {
|
73
|
-
people++
|
74
|
-
}, null)
|
75
|
-
// this has to take longer than the database save operation
|
76
|
-
// it's safe to make this number longer if it start failing
|
77
|
-
await sleep(50)
|
78
|
-
assert.equal(people, 6)
|
79
|
-
}).timeout(2000)
|
80
|
-
it('shares events since db.clock', (done) => {
|
81
|
-
const clock = database.clock
|
82
|
-
const afterEvent = () => {
|
83
|
-
database.put({ _id: 'j645-87tj', name: 'jimmy' })
|
84
|
-
}
|
85
|
-
let people = 0
|
86
|
-
database.put({ _id: 'h645-87th', name: 'harold' }).then(newPerson => {
|
87
|
-
assert(newPerson.id)
|
88
|
-
listener.on('person', (key) => {
|
89
|
-
people++
|
90
|
-
if (people === 1) {
|
91
|
-
assert.equal(key, 'h645-87th')
|
92
|
-
} else {
|
93
|
-
assert.equal(key, 'j645-87tj')
|
94
|
-
done()
|
95
|
-
}
|
96
|
-
if (people === 1) afterEvent()
|
97
|
-
}, clock)
|
98
|
-
})
|
99
|
-
}).timeout(2000)
|
100
|
-
})
|
101
|
-
|
102
|
-
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
package/test/prolly.test.js
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
import { describe, it } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import { advance } from '../src/clock.js'
|
4
|
-
|
5
|
-
import { put, get, getAll, root, eventsSince } from '../src/prolly.js'
|
6
|
-
import { Blockstore, seqEventData, setSeq } from './helpers.js'
|
7
|
-
|
8
|
-
describe('Prolly', () => {
|
9
|
-
it('put a value to a new clock', async () => {
|
10
|
-
const blocks = new Blockstore()
|
11
|
-
const alice = new TestPail(blocks, [])
|
12
|
-
const key = 'key'
|
13
|
-
const value = seqEventData()
|
14
|
-
const { event, head } = await alice.put(key, value)
|
15
|
-
|
16
|
-
assert.equal(event.value.data.type, 'put')
|
17
|
-
assert.equal(event.value.data.key, key)
|
18
|
-
assert.equal(event.value.data.value.toString(), value.toString())
|
19
|
-
assert.equal(head.length, 1)
|
20
|
-
assert.equal(head[0].toString(), event.cid.toString())
|
21
|
-
|
22
|
-
const avalue = await alice.get('key')
|
23
|
-
assert(avalue)
|
24
|
-
assert.equal(JSON.stringify(avalue), JSON.stringify(value))
|
25
|
-
})
|
26
|
-
|
27
|
-
it('linear put multiple values', async () => {
|
28
|
-
setSeq(-1)
|
29
|
-
const blocks = new Blockstore()
|
30
|
-
const alice = new TestPail(blocks, [])
|
31
|
-
|
32
|
-
const key0 = 'key0'
|
33
|
-
const value0 = seqEventData()
|
34
|
-
const { head: oldHead } = await alice.put(key0, value0)
|
35
|
-
|
36
|
-
const key1 = 'key1'
|
37
|
-
const value1 = seqEventData()
|
38
|
-
const result = await alice.put(key1, value1)
|
39
|
-
|
40
|
-
assert.equal(result.event.value.data.type, 'put')
|
41
|
-
assert.equal(result.event.value.data.key, key1)
|
42
|
-
assert.equal(result.event.value.data.value.toString(), value1.toString())
|
43
|
-
assert.equal(result.head.length, 1)
|
44
|
-
assert.equal(result.head[0].toString(), result.event.cid.toString())
|
45
|
-
|
46
|
-
const allResp = await alice.getAll()
|
47
|
-
assert(allResp)
|
48
|
-
assert.equal(allResp.length, 2)
|
49
|
-
assert.equal(allResp[0].key, key0)
|
50
|
-
|
51
|
-
// add a third value
|
52
|
-
// try getSince
|
53
|
-
const sinceResp = await alice.getSince(oldHead)
|
54
|
-
assert.equal(sinceResp.length, 1)
|
55
|
-
assert.equal(sinceResp[0].value.value, 'event0')
|
56
|
-
})
|
57
|
-
|
58
|
-
it('get missing', async () => {
|
59
|
-
const blocks = new Blockstore()
|
60
|
-
const alice = new TestPail(blocks, [])
|
61
|
-
const key = 'key'
|
62
|
-
const value = seqEventData('test-missing-root')
|
63
|
-
await alice.put(key, value)
|
64
|
-
|
65
|
-
await alice.get('missing').then((value) => {
|
66
|
-
assert('false', 'should not get here')
|
67
|
-
}).catch((err) => {
|
68
|
-
assert.equal(err.message, 'Not found')
|
69
|
-
})
|
70
|
-
})
|
71
|
-
|
72
|
-
it('simple parallel put multiple values', async () => {
|
73
|
-
const blocks = new Blockstore()
|
74
|
-
const alice = new TestPail(blocks, [])
|
75
|
-
await alice.put('key0', seqEventData())
|
76
|
-
const bob = new TestPail(blocks, alice.head)
|
77
|
-
|
78
|
-
/** @type {Array<[string, import('../src/link').AnyLink]>} */
|
79
|
-
const data = [
|
80
|
-
['key1', seqEventData()],
|
81
|
-
['key2', seqEventData()],
|
82
|
-
['key3', seqEventData()],
|
83
|
-
['key4', seqEventData()]
|
84
|
-
]
|
85
|
-
|
86
|
-
const { event: aevent0 } = await alice.put(data[0][0], data[0][1])
|
87
|
-
const { event: bevent0 } = await bob.put(data[1][0], data[1][1])
|
88
|
-
const { event: bevent1 } = await bob.put(data[2][0], data[2][1])
|
89
|
-
|
90
|
-
await alice.advance(bevent0.cid)
|
91
|
-
await alice.advance(bevent1.cid)
|
92
|
-
await bob.advance(aevent0.cid)
|
93
|
-
|
94
|
-
const { event: aevent1 } = await alice.put(data[3][0], data[3][1])
|
95
|
-
|
96
|
-
await bob.advance(aevent1.cid)
|
97
|
-
|
98
|
-
assert(alice.root)
|
99
|
-
assert(bob.root)
|
100
|
-
assert.equal(alice.root.toString(), bob.root.toString())
|
101
|
-
|
102
|
-
// get item put to bob
|
103
|
-
const avalue = await alice.get(data[1][0])
|
104
|
-
assert(avalue)
|
105
|
-
assert.equal(avalue.toString(), data[1][1].toString())
|
106
|
-
|
107
|
-
// get item put to alice
|
108
|
-
const bvalue = await bob.get(data[0][0])
|
109
|
-
assert(bvalue)
|
110
|
-
assert.equal(bvalue.toString(), data[0][1].toString())
|
111
|
-
})
|
112
|
-
|
113
|
-
it.skip('passing, slow: linear put hundreds of values', async () => {
|
114
|
-
const blocks = new Blockstore()
|
115
|
-
const alice = new TestPail(blocks, [])
|
116
|
-
|
117
|
-
for (let i = 0; i < 100; i++) {
|
118
|
-
await alice.put('key' + i, seqEventData())
|
119
|
-
}
|
120
|
-
|
121
|
-
for (let i = 0; i < 100; i++) {
|
122
|
-
const vx = await alice.get('key' + i)
|
123
|
-
assert(vx)
|
124
|
-
// console.log('vx', vx)
|
125
|
-
// assert.equal(vx.toString(), value.toString())
|
126
|
-
}
|
127
|
-
console.log('blocks', Array.from(blocks.entries()).length)
|
128
|
-
}).timeout(10000)
|
129
|
-
})
|
130
|
-
|
131
|
-
class TestPail {
|
132
|
-
/**
|
133
|
-
* @param {Blockstore} blocks
|
134
|
-
* @param {import('../src/clock').EventLink<import('../src/crdt').EventData>[]} head
|
135
|
-
*/
|
136
|
-
constructor (blocks, head) {
|
137
|
-
this.blocks = blocks
|
138
|
-
this.head = head
|
139
|
-
/** @type {import('../src/shard.js').ShardLink?} */
|
140
|
-
this.root = null
|
141
|
-
}
|
142
|
-
|
143
|
-
/**
|
144
|
-
* @param {string} key
|
145
|
-
* @param {import('../src/link').AnyLink} value
|
146
|
-
*/
|
147
|
-
async put (key, value) {
|
148
|
-
const result = await put(this.blocks, this.head, { key, value })
|
149
|
-
if (!result) {
|
150
|
-
console.log('failed', key, value)
|
151
|
-
}
|
152
|
-
this.blocks.putSync(result.event.cid, result.event.bytes)
|
153
|
-
result.additions.forEach((a) => this.blocks.putSync(a.cid, a.bytes))
|
154
|
-
this.head = result.head
|
155
|
-
this.root = result.root.cid
|
156
|
-
// this difference probably matters, but we need to test it
|
157
|
-
// this.root = await root(this.blocks, this.head)
|
158
|
-
// console.log('prolly PUT', key, value, { head: result.head, additions: result.additions.map(a => a.cid), event: result.event.cid })
|
159
|
-
return result
|
160
|
-
}
|
161
|
-
|
162
|
-
// todo make bulk ops which should be easy at the prolly layer by passing a list of events instead of one
|
163
|
-
// async bulk() {}
|
164
|
-
|
165
|
-
/** @param {import('../src/clock').EventLink<import('../src/crdt').EventData>} event */
|
166
|
-
async advance (event) {
|
167
|
-
const { head } = await advance(this.blocks, this.head, event)
|
168
|
-
this.head = head
|
169
|
-
this.root = (await root(this.blocks, this.head)).node.block.cid
|
170
|
-
return this.head
|
171
|
-
}
|
172
|
-
|
173
|
-
/** @param {string} key */
|
174
|
-
async get (key) {
|
175
|
-
const resp = await get(this.blocks, this.head, key)
|
176
|
-
// console.log('prolly GET', key, resp)
|
177
|
-
return resp.result
|
178
|
-
}
|
179
|
-
|
180
|
-
/** @param {string} key */
|
181
|
-
async getAll () {
|
182
|
-
const resp = await getAll(this.blocks, this.head)
|
183
|
-
return resp.result
|
184
|
-
}
|
185
|
-
|
186
|
-
async getSince (since) {
|
187
|
-
const resp = await eventsSince(this.blocks, this.head, since)
|
188
|
-
return resp.result
|
189
|
-
}
|
190
|
-
}
|
package/test/proofs.test.js
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import Fireproof from '../src/fireproof.js'
|
4
|
-
|
5
|
-
let database, ok, doc
|
6
|
-
|
7
|
-
describe('Proofs', () => {
|
8
|
-
beforeEach(async () => {
|
9
|
-
database = Fireproof.storage()
|
10
|
-
ok = await database.put({
|
11
|
-
_id: 'test1',
|
12
|
-
score: 75
|
13
|
-
})
|
14
|
-
doc = await database.get(ok.id, { mvcc: true })
|
15
|
-
})
|
16
|
-
|
17
|
-
it('first put result shoud not include proof', async () => {
|
18
|
-
assert(ok.proof)
|
19
|
-
assert(ok.proof.data)
|
20
|
-
assert(ok.proof.clock)
|
21
|
-
// console.log('ok', ok)
|
22
|
-
assert.equal(ok.proof.data.length, 0)
|
23
|
-
assert.equal(ok.proof.clock.length, 0)
|
24
|
-
|
25
|
-
// assert.equal(ok.proof.data[0], 'bafyreibsbxxd4ueujryihk6xza2ekwhzsh6pzuu5fysft5ilz7cbw6bjju')
|
26
|
-
// assert.equal(ok.proof.clock[0].toString(), 'bafyreiactx5vku7zueq27i5zdrgcjnczxvepceo5yszjqb2exufwrwxg44')
|
27
|
-
})
|
28
|
-
|
29
|
-
it.skip('second put result shoud include proof', async () => {
|
30
|
-
const ok2 = await database.put({ ...doc, winner: true })
|
31
|
-
assert(ok2.proof)
|
32
|
-
assert(ok2.proof.data)
|
33
|
-
assert(ok2.proof.clock)
|
34
|
-
// console.log('ok2', ok2)
|
35
|
-
assert.equal(ok2.proof.data.length, 1)
|
36
|
-
assert.equal(ok2.proof.clock.length, 1)
|
37
|
-
|
38
|
-
// assert.equal(ok.proof.data[0], 'bafyreibsbxxd4ueujryihk6xza2ekwhzsh6pzuu5fysft5ilz7cbw6bjju')
|
39
|
-
// assert.equal(ok.proof.clock[0].toString(), 'bafyreiactx5vku7zueq27i5zdrgcjnczxvepceo5yszjqb2exufwrwxg44')
|
40
|
-
})
|
41
|
-
|
42
|
-
it('get result shoud include proof', async () => {
|
43
|
-
assert(doc._clock)
|
44
|
-
assert(doc._proof)
|
45
|
-
|
46
|
-
assert(doc._proof.data)
|
47
|
-
assert(doc._proof.clock)
|
48
|
-
assert.equal(doc._proof.data.length, 1)
|
49
|
-
assert.equal(doc._proof.clock.length, 1)
|
50
|
-
assert.equal(doc._proof.data[0], 'bafyreieilmvxq6wudu46i2ssmuyrmaszr4onzlqxzlvngrczbn7ppyvloq')
|
51
|
-
assert.equal(doc._proof.clock[0].toString(), 'bafyreict4aip45uwnm4xcsn4oikh73t5n7nzdmc2u36rdbguroun2yaf2y')
|
52
|
-
})
|
53
|
-
})
|
@@ -1,65 +0,0 @@
|
|
1
|
-
import { describe, it, beforeEach } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import Fireproof from '../src/fireproof.js'
|
4
|
-
import DbIndex from '../src/db-index.js'
|
5
|
-
|
6
|
-
let database
|
7
|
-
|
8
|
-
describe('IPLD encode error', () => {
|
9
|
-
beforeEach(async () => {
|
10
|
-
database = Fireproof.storage()
|
11
|
-
defineIndexes(database)
|
12
|
-
})
|
13
|
-
|
14
|
-
it('reproduce', async () => {
|
15
|
-
await loadFixtures(database)
|
16
|
-
assert(true)
|
17
|
-
})
|
18
|
-
})
|
19
|
-
|
20
|
-
const defineIndexes = (database) => {
|
21
|
-
database.allLists = new DbIndex(database, function (doc, map) {
|
22
|
-
if (doc.type === 'list') map(doc.type, doc)
|
23
|
-
})
|
24
|
-
database.todosByList = new DbIndex(database, function (doc, map) {
|
25
|
-
if (doc.type === 'todo' && doc.listId) {
|
26
|
-
map([doc.listId, doc.createdAt], doc)
|
27
|
-
}
|
28
|
-
})
|
29
|
-
return database
|
30
|
-
}
|
31
|
-
|
32
|
-
function mulberry32 (a) {
|
33
|
-
return function () {
|
34
|
-
let t = (a += 0x6d2b79f5)
|
35
|
-
t = Math.imul(t ^ (t >>> 15), t | 1)
|
36
|
-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
|
37
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296
|
38
|
-
}
|
39
|
-
}
|
40
|
-
const rand = mulberry32(1) // determinstic fixtures
|
41
|
-
|
42
|
-
async function loadFixtures (database) {
|
43
|
-
const nextId = (prefix = '') => prefix + rand().toString(32).slice(2)
|
44
|
-
const ok = await database.put({ title: 'Building Apps', type: 'list', _id: nextId() })
|
45
|
-
|
46
|
-
await database.put({
|
47
|
-
_id: nextId(),
|
48
|
-
title: 'In the browser',
|
49
|
-
listId: ok.id,
|
50
|
-
completed: rand() > 0.75,
|
51
|
-
type: 'todo',
|
52
|
-
createdAt: '2'
|
53
|
-
})
|
54
|
-
await reproduceBug(database)
|
55
|
-
}
|
56
|
-
|
57
|
-
const reproduceBug = async (database) => {
|
58
|
-
const id = '02pkji8'
|
59
|
-
const doc = await database.get(id)
|
60
|
-
// (await database.put({ completed: !completed, ...doc }))
|
61
|
-
await database.put(doc)
|
62
|
-
await database.todosByList.query({ range: [0, 1] })
|
63
|
-
|
64
|
-
// console.log('ok', ok)
|
65
|
-
}
|
package/test/valet.test.js
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
import { before, describe, it } from 'mocha'
|
2
|
-
import assert from 'node:assert'
|
3
|
-
import Valet from '../src/valet.js'
|
4
|
-
|
5
|
-
describe('new Valet', () => {
|
6
|
-
let val
|
7
|
-
const calls = []
|
8
|
-
|
9
|
-
before(async () => {
|
10
|
-
val = new Valet()
|
11
|
-
val.uploadFunction = async (carCid, value) => {
|
12
|
-
calls.push({ carCid, value })
|
13
|
-
}
|
14
|
-
})
|
15
|
-
it('has default attributes', async () => {
|
16
|
-
assert(val.getBlock)
|
17
|
-
assert(val.parkCar)
|
18
|
-
})
|
19
|
-
it('can park a car and serve the blocks', async () => {
|
20
|
-
await val
|
21
|
-
.parkCar('carCid', carBytes, [
|
22
|
-
'bafyreifwghknmzabvgearl72url3v5leqqhtafvybcsrceelc3psqkocoi',
|
23
|
-
'bafyreieth2ckopwivda5mf6vu76xwqvox3q5wsaxgbmxy2dgrd4hfuzmma'
|
24
|
-
])
|
25
|
-
.then((car) => {
|
26
|
-
assert('car parked')
|
27
|
-
val.getBlock('bafyreieth2ckopwivda5mf6vu76xwqvox3q5wsaxgbmxy2dgrd4hfuzmma').then((block) => {
|
28
|
-
assert.equal(block.length, carBytes.length)
|
29
|
-
})
|
30
|
-
})
|
31
|
-
})
|
32
|
-
it('calls the upload function', () => {
|
33
|
-
assert.equal(calls.length, 1)
|
34
|
-
assert.equal(calls[0].carCid, 'carCid')
|
35
|
-
})
|
36
|
-
})
|
37
|
-
|
38
|
-
const carBytes = new Uint8Array([
|
39
|
-
58, 162, 101, 114, 111, 111, 116, 115, 129, 216, 42, 88, 37, 0, 1, 113, 18, 32, 147, 62, 132, 167, 62, 200, 168, 193,
|
40
|
-
214, 23, 213, 167, 253, 123, 66, 174, 190, 225, 219, 72, 23, 48, 89, 124, 104, 102, 136, 248, 114, 211, 44, 96, 103,
|
41
|
-
118, 101, 114, 115, 105, 111, 110, 1, 108, 1, 113, 18, 32, 182, 49, 212, 214, 100, 1, 169, 136, 8, 175, 250, 164, 87,
|
42
|
-
186, 245, 100, 132, 15, 48, 22, 184, 8, 165, 17, 16, 139, 22, 223, 40, 41, 194, 114, 162, 100, 108, 101, 97, 102, 129,
|
43
|
-
130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101, 45, 57, 99, 49, 99, 45, 56,
|
44
|
-
99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109, 101, 101, 97, 108, 105,
|
45
|
-
99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 208, 2, 1, 113, 18, 32, 147, 62, 132, 167, 62, 200, 168, 193, 214, 23,
|
46
|
-
213, 167, 253, 123, 66, 174, 190, 225, 219, 72, 23, 48, 89, 124, 104, 102, 136, 248, 114, 211, 44, 96, 162, 100, 100,
|
47
|
-
97, 116, 97, 164, 99, 107, 101, 121, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53,
|
48
|
-
101, 45, 57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 100, 114, 111, 111, 116, 163, 99, 99,
|
49
|
-
105, 100, 216, 42, 88, 37, 0, 1, 113, 18, 32, 182, 49, 212, 214, 100, 1, 169, 136, 8, 175, 250, 164, 87, 186, 245,
|
50
|
-
100, 132, 15, 48, 22, 184, 8, 165, 17, 16, 139, 22, 223, 40, 41, 194, 114, 101, 98, 121, 116, 101, 115, 88, 72, 162,
|
51
|
-
100, 108, 101, 97, 102, 129, 130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101,
|
52
|
-
45, 57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97,
|
53
|
-
109, 101, 101, 97, 108, 105, 99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 101, 118, 97, 108, 117, 101, 162, 100,
|
54
|
-
108, 101, 97, 102, 129, 130, 120, 36, 49, 101, 102, 51, 98, 51, 50, 97, 45, 51, 99, 51, 97, 45, 52, 98, 53, 101, 45,
|
55
|
-
57, 99, 49, 99, 45, 56, 99, 53, 99, 48, 99, 53, 99, 48, 99, 53, 99, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109,
|
56
|
-
101, 101, 97, 108, 105, 99, 101, 102, 99, 108, 111, 115, 101, 100, 244, 100, 116, 121, 112, 101, 99, 112, 117, 116,
|
57
|
-
101, 118, 97, 108, 117, 101, 162, 99, 97, 103, 101, 24, 42, 100, 110, 97, 109, 101, 101, 97, 108, 105, 99, 101, 103,
|
58
|
-
112, 97, 114, 101, 110, 116, 115, 128
|
59
|
-
])
|