mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #8950 from overleaf/bg-use-qpdf-xref-table
[clsi] parse xref table from qpdf output GitOrigin-RevId: cc400c65082c7c8c28c21037b97b4fde66a85835
This commit is contained in:
parent
a2010bf901
commit
18768d3f1b
38 changed files with 880 additions and 262 deletions
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -23390,14 +23390,6 @@
|
|||
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"node_modules/pdfjs-dist": {
|
||||
"version": "2.7.570",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.7.570.tgz",
|
||||
"integrity": "sha512-/ZkA1FwkEOyDaq11JhMLazdwQAA0F9uwrP7h/1L9Akt9KWh1G5/tkzS+bPuUELq2s2GDFnaT+kooN/aSjT7DXQ==",
|
||||
"peerDependencies": {
|
||||
"worker-loader": "^3.0.7"
|
||||
}
|
||||
},
|
||||
"node_modules/pdfjs-dist210": {
|
||||
"name": "pdfjs-dist",
|
||||
"version": "2.10.377",
|
||||
|
@ -31849,7 +31841,6 @@
|
|||
"lockfile": "^1.0.4",
|
||||
"lodash": "^4.17.21",
|
||||
"p-limit": "^3.1.0",
|
||||
"pdfjs-dist": "~2.7.570",
|
||||
"request": "^2.88.2",
|
||||
"send": "^0.17.1",
|
||||
"workerpool": "^6.1.5"
|
||||
|
@ -39703,7 +39694,6 @@
|
|||
"mocha": "^8.4.0",
|
||||
"mock-fs": "^5.1.2",
|
||||
"p-limit": "^3.1.0",
|
||||
"pdfjs-dist": "~2.7.570",
|
||||
"request": "^2.88.2",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"send": "^0.17.1",
|
||||
|
@ -59303,12 +59293,6 @@
|
|||
"resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"pdfjs-dist": {
|
||||
"version": "2.7.570",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.7.570.tgz",
|
||||
"integrity": "sha512-/ZkA1FwkEOyDaq11JhMLazdwQAA0F9uwrP7h/1L9Akt9KWh1G5/tkzS+bPuUELq2s2GDFnaT+kooN/aSjT7DXQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"pdfjs-dist210": {
|
||||
"version": "npm:pdfjs-dist@2.10.377",
|
||||
"resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.10.377.tgz",
|
||||
|
|
|
@ -9,8 +9,12 @@ const Path = require('path')
|
|||
const Settings = require('@overleaf/settings')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const pLimit = require('p-limit')
|
||||
const { parseXrefTable } = require('../lib/pdfjs/parseXrefTable')
|
||||
const { QueueLimitReachedError, TimedOutError } = require('./Errors')
|
||||
const { parseXrefTable } = require('./XrefParser')
|
||||
const {
|
||||
QueueLimitReachedError,
|
||||
TimedOutError,
|
||||
NoXrefTableError,
|
||||
} = require('./Errors')
|
||||
const workerpool = require('workerpool')
|
||||
const Metrics = require('@overleaf/metrics')
|
||||
|
||||
|
@ -89,6 +93,9 @@ async function updateOtherEventLoop(contentDir, filePath, size, compileTime) {
|
|||
if (e.message?.includes?.('Max queue size of ')) {
|
||||
throw new QueueLimitReachedError()
|
||||
}
|
||||
if (e.message?.includes?.('xref')) {
|
||||
throw new NoXrefTableError(e.message)
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +122,7 @@ async function updateSameEventLoop(contentDir, filePath, size, compileTime) {
|
|||
size,
|
||||
checkDeadline
|
||||
)
|
||||
|
||||
xRefEntries.sort((a, b) => {
|
||||
return a.offset - b.offset
|
||||
})
|
||||
|
|
|
@ -33,6 +33,7 @@ AlreadyCompilingError.prototype.__proto__ = Error.prototype
|
|||
|
||||
class QueueLimitReachedError extends OError {}
|
||||
class TimedOutError extends OError {}
|
||||
class NoXrefTableError extends OError {}
|
||||
|
||||
module.exports = Errors = {
|
||||
QueueLimitReachedError,
|
||||
|
@ -40,4 +41,5 @@ module.exports = Errors = {
|
|||
NotFoundError,
|
||||
FilesOutOfSyncError,
|
||||
AlreadyCompilingError,
|
||||
NoXrefTableError,
|
||||
}
|
||||
|
|
|
@ -24,7 +24,11 @@ const Metrics = require('./Metrics')
|
|||
|
||||
const OutputFileOptimiser = require('./OutputFileOptimiser')
|
||||
const ContentCacheManager = require('./ContentCacheManager')
|
||||
const { QueueLimitReachedError, TimedOutError } = require('./Errors')
|
||||
const {
|
||||
QueueLimitReachedError,
|
||||
TimedOutError,
|
||||
NoXrefTableError,
|
||||
} = require('./Errors')
|
||||
|
||||
const OLDEST_BUILD_DIR = new Map()
|
||||
const PENDING_PROJECT_ACTIONS = new Map()
|
||||
|
@ -397,6 +401,9 @@ module.exports = OutputCacheManager = {
|
|||
pdfSize,
|
||||
timings.compile,
|
||||
function (err, result) {
|
||||
if (err && err instanceof NoXrefTableError) {
|
||||
return callback(null, err.message)
|
||||
}
|
||||
if (err && err instanceof QueueLimitReachedError) {
|
||||
logger.warn({ err, outputDir }, 'pdf caching queue limit reached')
|
||||
stats['pdf-caching-queue-limit-reached'] = 1
|
||||
|
|
68
services/clsi/app/js/XrefParser.js
Normal file
68
services/clsi/app/js/XrefParser.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
const { NoXrefTableError } = require('./Errors')
|
||||
const fs = require('fs')
|
||||
const { O_RDONLY, O_NOFOLLOW } = fs.constants
|
||||
const MAX_XREF_FILE_SIZE = 1024 * 1024
|
||||
|
||||
/** Parse qpdf --show-xref output to get a table of xref entries
|
||||
*
|
||||
* @param {string} filePath
|
||||
* @param {integer} pdfFileSize
|
||||
* @returns
|
||||
*/
|
||||
async function parseXrefTable(filePath, pdfFileSize) {
|
||||
try {
|
||||
// the xref table will be written to output.pdfxref when available
|
||||
const xRefFilePath = filePath + 'xref'
|
||||
// check the size of the file (as it is untrusted)
|
||||
const stats = await fs.promises.stat(xRefFilePath)
|
||||
if (!stats.isFile()) {
|
||||
throw new NoXrefTableError('xref file invalid type')
|
||||
}
|
||||
if (stats.size === 0) {
|
||||
throw new NoXrefTableError('xref file empty')
|
||||
}
|
||||
if (stats.size > MAX_XREF_FILE_SIZE) {
|
||||
throw new NoXrefTableError('xref file too large')
|
||||
}
|
||||
const content = await fs.promises.readFile(xRefFilePath, {
|
||||
encoding: 'ascii',
|
||||
flag: O_RDONLY | O_NOFOLLOW,
|
||||
})
|
||||
// the qpdf xref table output looks like this:
|
||||
//
|
||||
// 3/0: uncompressed; offset = 194159
|
||||
//
|
||||
// we only need the uncompressed objects
|
||||
const matches = content.matchAll(
|
||||
// put an upper limit of 10^10 on all the matched numbers for safety
|
||||
// ignore the generation id in "id/gen"
|
||||
// in a linearized pdf all objects must have generation number 0
|
||||
/^(\d{1,9})\/\d{1,9}: uncompressed; offset = (\d{1,9})$/gm
|
||||
)
|
||||
// include a zero-index object for backwards compatibility with
|
||||
// our existing xref table parsing code
|
||||
const xRefEntries = [{ offset: 0 }]
|
||||
// extract all the xref table entries
|
||||
for (const match of matches) {
|
||||
const id = parseInt(match[1], 10) // must convert from strings to integers
|
||||
const offset = parseInt(match[2], 10)
|
||||
xRefEntries[id] = { offset, uncompressed: true }
|
||||
}
|
||||
if (xRefEntries.length === 1) {
|
||||
throw new NoXrefTableError('xref file has no objects')
|
||||
}
|
||||
return { xRefEntries }
|
||||
} catch (err) {
|
||||
if (err instanceof NoXrefTableError) {
|
||||
throw err
|
||||
} else if (err.code) {
|
||||
throw new NoXrefTableError(`xref file error ${err.code}`)
|
||||
} else {
|
||||
throw new NoXrefTableError('xref file parse error')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseXrefTable,
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
const { PDFDocument } = require('pdfjs-dist/lib/core/document')
|
||||
const { LocalPdfManager } = require('pdfjs-dist/lib/core/pdf_manager')
|
||||
const { MissingDataException } = require('pdfjs-dist/lib/core/core_utils')
|
||||
const { FSStream } = require('./FSStream')
|
||||
|
||||
class FSPdfManager extends LocalPdfManager {
|
||||
constructor(docId, { fh, size, checkDeadline }) {
|
||||
const nonEmptyDummyBuffer = Buffer.alloc(1, 0)
|
||||
super(docId, nonEmptyDummyBuffer)
|
||||
this.stream = new FSStream(fh, 0, size, null, null, checkDeadline)
|
||||
this.pdfDocument = new PDFDocument(this, this.stream)
|
||||
}
|
||||
|
||||
async ensure(obj, prop, args) {
|
||||
try {
|
||||
const value = obj[prop]
|
||||
if (typeof value === 'function') {
|
||||
return value.apply(obj, args)
|
||||
}
|
||||
return value
|
||||
} catch (ex) {
|
||||
if (!(ex instanceof MissingDataException)) {
|
||||
throw ex
|
||||
}
|
||||
await this.requestRange(ex.begin, ex.end)
|
||||
return this.ensure(obj, prop, args)
|
||||
}
|
||||
}
|
||||
|
||||
requestRange(begin, end) {
|
||||
return this.stream.requestRange(begin, end)
|
||||
}
|
||||
|
||||
requestLoadedStream() {}
|
||||
|
||||
onLoadedStream() {}
|
||||
|
||||
terminate(reason) {}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FSPdfManager,
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
const { Stream } = require('pdfjs-dist/lib/core/stream')
|
||||
const { MissingDataException } = require('pdfjs-dist/lib/core/core_utils')
|
||||
|
||||
const BUF_SIZE = 1024 // read from the file in 1024 byte pages
|
||||
|
||||
class FSStream extends Stream {
|
||||
constructor(fh, start, length, dict, cachedBytes, checkDeadline) {
|
||||
const nonEmptyDummyBuffer = Buffer.alloc(1, 0)
|
||||
super(nonEmptyDummyBuffer, start, length, dict)
|
||||
delete this.bytes
|
||||
this.fh = fh
|
||||
this.checkDeadline = checkDeadline
|
||||
this.cachedBytes = cachedBytes || []
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this.end - this.start
|
||||
}
|
||||
|
||||
get isEmpty() {
|
||||
return this.length === 0
|
||||
}
|
||||
|
||||
// Manage cached reads from the file
|
||||
|
||||
requestRange(begin, end) {
|
||||
this.checkDeadline(`request range ${begin} - ${end}`)
|
||||
// expand small ranges to read a larger amount
|
||||
if (end - begin < BUF_SIZE) {
|
||||
end = begin + BUF_SIZE
|
||||
}
|
||||
end = Math.min(end, this.length)
|
||||
// keep a cache of previous reads with {begin,end,buffer} values
|
||||
const result = {
|
||||
begin,
|
||||
end,
|
||||
buffer: Buffer.alloc(end - begin, 0),
|
||||
}
|
||||
this.cachedBytes.push(result)
|
||||
return this.fh.read(result.buffer, 0, end - begin, begin)
|
||||
}
|
||||
|
||||
_ensureGetPos(pos) {
|
||||
const found = this.cachedBytes.find(x => {
|
||||
return x.begin <= pos && pos < x.end
|
||||
})
|
||||
if (!found) {
|
||||
throw new MissingDataException(pos, pos + 1)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
_ensureGetRange(begin, end) {
|
||||
end = Math.min(end, this.length) // BG: handle overflow case
|
||||
const found = this.cachedBytes.find(x => {
|
||||
return x.begin <= begin && end <= x.end
|
||||
})
|
||||
if (!found) {
|
||||
throw new MissingDataException(begin, end)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
_readByte(found, pos) {
|
||||
return found.buffer[pos - found.begin]
|
||||
}
|
||||
|
||||
_readBytes(found, pos, end) {
|
||||
return found.buffer.subarray(pos - found.begin, end - found.begin)
|
||||
}
|
||||
|
||||
// handle accesses to the bytes
|
||||
|
||||
ensureByte(pos) {
|
||||
this._ensureGetPos(pos) // may throw a MissingDataException
|
||||
}
|
||||
|
||||
getByte() {
|
||||
const pos = this.pos
|
||||
if (this.pos >= this.end) {
|
||||
return -1
|
||||
}
|
||||
const found = this._ensureGetPos(pos)
|
||||
return this._readByte(found, this.pos++)
|
||||
}
|
||||
|
||||
// BG: for a range, end is not included (see Buffer.subarray for example)
|
||||
|
||||
ensureBytes(length, forceClamped = false) {
|
||||
const pos = this.pos
|
||||
this._ensureGetRange(pos, pos + length)
|
||||
}
|
||||
|
||||
getBytes(length, forceClamped = false) {
|
||||
const pos = this.pos
|
||||
const strEnd = this.end
|
||||
|
||||
const found = this._ensureGetRange(pos, pos + length)
|
||||
if (!length) {
|
||||
const subarray = this._readBytes(found, pos, strEnd)
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray
|
||||
}
|
||||
let end = pos + length
|
||||
if (end > strEnd) {
|
||||
end = strEnd
|
||||
}
|
||||
this.pos = end
|
||||
const subarray = this._readBytes(found, pos, end)
|
||||
// `this.bytes` is always a `Uint8Array` here.
|
||||
return forceClamped ? new Uint8ClampedArray(subarray) : subarray
|
||||
}
|
||||
|
||||
getByteRange() {
|
||||
// BG: this isn't needed as far as I can tell
|
||||
throw new Error('not implemented')
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.pos = this.start
|
||||
}
|
||||
|
||||
moveStart() {
|
||||
this.start = this.pos
|
||||
}
|
||||
|
||||
makeSubStream(start, length, dict = null) {
|
||||
this.checkDeadline(`make sub stream start=${start}/length=${length}`)
|
||||
// BG: had to add this check for null length, it is being called with only
|
||||
// the start value at one point in the xref decoding. The intent is clear
|
||||
// enough
|
||||
// - a null length means "to the end of the file" -- not sure how it is
|
||||
// working in the existing pdfjs code without this.
|
||||
if (!length) {
|
||||
length = this.end - start
|
||||
}
|
||||
return new FSStream(
|
||||
this.fh,
|
||||
start,
|
||||
length,
|
||||
dict,
|
||||
this.cachedBytes,
|
||||
this.checkDeadline
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { FSStream }
|
|
@ -1,29 +0,0 @@
|
|||
const fs = require('fs')
|
||||
const { FSPdfManager } = require('./FSPdfManager')
|
||||
|
||||
async function parseXrefTable(path, size, checkDeadline) {
|
||||
if (size === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const file = await fs.promises.open(path)
|
||||
try {
|
||||
const manager = new FSPdfManager(0, { fh: file, size, checkDeadline })
|
||||
|
||||
await manager.ensureDoc('checkHeader')
|
||||
checkDeadline('pdfjs: after checkHeader')
|
||||
await manager.ensureDoc('parseStartXRef')
|
||||
checkDeadline('pdfjs: after parseStartXRef')
|
||||
await manager.ensureDoc('parse')
|
||||
checkDeadline('pdfjs: after parse')
|
||||
const xRefEntries = manager.pdfDocument.xref.entries || []
|
||||
const startXRefTable = manager.pdfDocument.xref.topDict?.get('Prev')
|
||||
return { xRefEntries, startXRefTable }
|
||||
} finally {
|
||||
file.close()
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseXrefTable,
|
||||
}
|
|
@ -30,7 +30,6 @@
|
|||
"lockfile": "^1.0.4",
|
||||
"lodash": "^4.17.21",
|
||||
"p-limit": "^3.1.0",
|
||||
"pdfjs-dist": "~2.7.570",
|
||||
"request": "^2.88.2",
|
||||
"send": "^0.17.1",
|
||||
"workerpool": "^6.1.5"
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
1/0: uncompressed; offset = 123103
|
||||
2/0: uncompressed; offset = 123422
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 1084
|
||||
6/0: uncompressed; offset = 1244
|
||||
7/0: uncompressed; offset = 4001
|
||||
8/0: uncompressed; offset = 4155
|
||||
9/0: uncompressed; offset = 4297
|
||||
10/0: uncompressed; offset = 4933
|
||||
11/0: uncompressed; offset = 5309
|
||||
12/0: uncompressed; offset = 5498
|
||||
13/0: uncompressed; offset = 30250
|
||||
14/0: uncompressed; offset = 31471
|
||||
15/0: uncompressed; offset = 38404
|
||||
16/0: uncompressed; offset = 39046
|
||||
17/0: uncompressed; offset = 40166
|
||||
18/0: uncompressed; offset = 40906
|
||||
19/0: uncompressed; offset = 65560
|
||||
20/0: uncompressed; offset = 74702
|
||||
21/0: uncompressed; offset = 81705
|
||||
22/0: uncompressed; offset = 97182
|
||||
23/0: uncompressed; offset = 104117
|
||||
24/0: uncompressed; offset = 111195
|
||||
25/0: uncompressed; offset = 118571
|
||||
26/0: compressed; stream = 6, index = 0
|
||||
27/0: compressed; stream = 6, index = 1
|
||||
28/0: compressed; stream = 6, index = 2
|
||||
29/0: compressed; stream = 6, index = 3
|
||||
30/0: compressed; stream = 6, index = 4
|
||||
31/0: compressed; stream = 6, index = 5
|
||||
32/0: compressed; stream = 6, index = 6
|
||||
33/0: compressed; stream = 6, index = 7
|
||||
34/0: compressed; stream = 6, index = 8
|
||||
35/0: compressed; stream = 6, index = 9
|
||||
36/0: compressed; stream = 6, index = 10
|
||||
37/0: compressed; stream = 6, index = 11
|
||||
38/0: compressed; stream = 6, index = 12
|
||||
39/0: compressed; stream = 6, index = 13
|
||||
40/0: compressed; stream = 6, index = 14
|
||||
41/0: compressed; stream = 6, index = 15
|
||||
42/0: compressed; stream = 6, index = 16
|
||||
43/0: compressed; stream = 6, index = 17
|
||||
44/0: compressed; stream = 6, index = 18
|
||||
45/0: compressed; stream = 6, index = 19
|
||||
46/0: compressed; stream = 6, index = 20
|
||||
47/0: compressed; stream = 6, index = 21
|
||||
48/0: compressed; stream = 6, index = 22
|
||||
49/0: compressed; stream = 6, index = 23
|
||||
50/0: compressed; stream = 6, index = 24
|
||||
51/0: compressed; stream = 6, index = 25
|
||||
52/0: compressed; stream = 6, index = 26
|
||||
53/0: compressed; stream = 6, index = 27
|
||||
54/0: compressed; stream = 6, index = 28
|
||||
55/0: compressed; stream = 6, index = 29
|
||||
56/0: compressed; stream = 6, index = 30
|
||||
57/0: compressed; stream = 6, index = 31
|
||||
58/0: compressed; stream = 6, index = 32
|
||||
59/0: compressed; stream = 6, index = 33
|
||||
60/0: compressed; stream = 6, index = 34
|
||||
61/0: compressed; stream = 6, index = 35
|
||||
62/0: compressed; stream = 6, index = 36
|
||||
63/0: compressed; stream = 6, index = 37
|
||||
64/0: compressed; stream = 6, index = 38
|
||||
65/0: compressed; stream = 6, index = 39
|
||||
66/0: compressed; stream = 6, index = 40
|
||||
67/0: compressed; stream = 6, index = 41
|
||||
68/0: compressed; stream = 6, index = 42
|
||||
69/0: compressed; stream = 6, index = 43
|
||||
70/0: compressed; stream = 6, index = 44
|
||||
71/0: compressed; stream = 6, index = 45
|
||||
72/0: compressed; stream = 6, index = 46
|
||||
73/0: compressed; stream = 6, index = 47
|
||||
74/0: compressed; stream = 6, index = 48
|
||||
75/0: compressed; stream = 6, index = 49
|
||||
76/0: compressed; stream = 6, index = 50
|
||||
77/0: compressed; stream = 6, index = 51
|
||||
78/0: compressed; stream = 6, index = 52
|
||||
79/0: compressed; stream = 6, index = 53
|
||||
80/0: compressed; stream = 6, index = 54
|
||||
81/0: compressed; stream = 6, index = 55
|
|
@ -0,0 +1,31 @@
|
|||
1/0: uncompressed; offset = 59313
|
||||
2/0: uncompressed; offset = 59561
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 734
|
||||
6/0: uncompressed; offset = 784
|
||||
7/0: uncompressed; offset = 913
|
||||
8/0: uncompressed; offset = 1028
|
||||
9/0: uncompressed; offset = 1528
|
||||
10/0: uncompressed; offset = 9787
|
||||
11/0: uncompressed; offset = 18282
|
||||
12/0: uncompressed; offset = 33607
|
||||
13/0: uncompressed; offset = 45579
|
||||
14/0: uncompressed; offset = 58005
|
||||
15/0: compressed; stream = 14, index = 0
|
||||
16/0: compressed; stream = 14, index = 1
|
||||
17/0: compressed; stream = 14, index = 2
|
||||
18/0: compressed; stream = 14, index = 3
|
||||
19/0: compressed; stream = 14, index = 4
|
||||
20/0: compressed; stream = 14, index = 5
|
||||
21/0: compressed; stream = 14, index = 6
|
||||
22/0: compressed; stream = 14, index = 7
|
||||
23/0: compressed; stream = 14, index = 8
|
||||
24/0: compressed; stream = 14, index = 9
|
||||
25/0: compressed; stream = 14, index = 10
|
||||
26/0: compressed; stream = 14, index = 11
|
||||
27/0: compressed; stream = 14, index = 12
|
||||
28/0: compressed; stream = 14, index = 13
|
||||
29/0: compressed; stream = 14, index = 14
|
||||
30/0: compressed; stream = 14, index = 15
|
||||
31/0: compressed; stream = 14, index = 16
|
|
@ -0,0 +1,39 @@
|
|||
1/0: uncompressed; offset = 67338
|
||||
2/0: uncompressed; offset = 67606
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 790
|
||||
6/0: uncompressed; offset = 840
|
||||
7/0: uncompressed; offset = 975
|
||||
8/0: uncompressed; offset = 1083
|
||||
9/0: uncompressed; offset = 1578
|
||||
10/0: uncompressed; offset = 9881
|
||||
11/0: uncompressed; offset = 17868
|
||||
12/0: uncompressed; offset = 29906
|
||||
13/0: uncompressed; offset = 38400
|
||||
14/0: uncompressed; offset = 46656
|
||||
15/0: uncompressed; offset = 56198
|
||||
16/0: uncompressed; offset = 65682
|
||||
17/0: compressed; stream = 16, index = 0
|
||||
18/0: compressed; stream = 16, index = 1
|
||||
19/0: compressed; stream = 16, index = 2
|
||||
20/0: compressed; stream = 16, index = 3
|
||||
21/0: compressed; stream = 16, index = 4
|
||||
22/0: compressed; stream = 16, index = 5
|
||||
23/0: compressed; stream = 16, index = 6
|
||||
24/0: compressed; stream = 16, index = 7
|
||||
25/0: compressed; stream = 16, index = 8
|
||||
26/0: compressed; stream = 16, index = 9
|
||||
27/0: compressed; stream = 16, index = 10
|
||||
28/0: compressed; stream = 16, index = 11
|
||||
29/0: compressed; stream = 16, index = 12
|
||||
30/0: compressed; stream = 16, index = 13
|
||||
31/0: compressed; stream = 16, index = 14
|
||||
32/0: compressed; stream = 16, index = 15
|
||||
33/0: compressed; stream = 16, index = 16
|
||||
34/0: compressed; stream = 16, index = 17
|
||||
35/0: compressed; stream = 16, index = 18
|
||||
36/0: compressed; stream = 16, index = 19
|
||||
37/0: compressed; stream = 16, index = 20
|
||||
38/0: compressed; stream = 16, index = 21
|
||||
39/0: compressed; stream = 16, index = 22
|
|
@ -0,0 +1,50 @@
|
|||
1/0: uncompressed; offset = 69708
|
||||
2/0: uncompressed; offset = 70038
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 867
|
||||
6/0: uncompressed; offset = 990
|
||||
7/0: uncompressed; offset = 1143
|
||||
8/0: uncompressed; offset = 1251
|
||||
9/0: uncompressed; offset = 1834
|
||||
10/0: uncompressed; offset = 10137
|
||||
11/0: uncompressed; offset = 18124
|
||||
12/0: uncompressed; offset = 31939
|
||||
13/0: uncompressed; offset = 40433
|
||||
14/0: uncompressed; offset = 48689
|
||||
15/0: uncompressed; offset = 58231
|
||||
16/0: uncompressed; offset = 67715
|
||||
17/0: compressed; stream = 16, index = 0
|
||||
18/0: compressed; stream = 16, index = 1
|
||||
19/0: compressed; stream = 16, index = 2
|
||||
20/0: compressed; stream = 16, index = 3
|
||||
21/0: compressed; stream = 16, index = 4
|
||||
22/0: compressed; stream = 16, index = 5
|
||||
23/0: compressed; stream = 16, index = 6
|
||||
24/0: compressed; stream = 16, index = 7
|
||||
25/0: compressed; stream = 16, index = 8
|
||||
26/0: compressed; stream = 16, index = 9
|
||||
27/0: compressed; stream = 16, index = 10
|
||||
28/0: compressed; stream = 16, index = 11
|
||||
29/0: compressed; stream = 16, index = 12
|
||||
30/0: compressed; stream = 16, index = 13
|
||||
31/0: compressed; stream = 16, index = 14
|
||||
32/0: compressed; stream = 16, index = 15
|
||||
33/0: compressed; stream = 16, index = 16
|
||||
34/0: compressed; stream = 16, index = 17
|
||||
35/0: compressed; stream = 16, index = 18
|
||||
36/0: compressed; stream = 16, index = 19
|
||||
37/0: compressed; stream = 16, index = 20
|
||||
38/0: compressed; stream = 16, index = 21
|
||||
39/0: compressed; stream = 16, index = 22
|
||||
40/0: compressed; stream = 16, index = 23
|
||||
41/0: compressed; stream = 16, index = 24
|
||||
42/0: compressed; stream = 16, index = 25
|
||||
43/0: compressed; stream = 16, index = 26
|
||||
44/0: compressed; stream = 16, index = 27
|
||||
45/0: compressed; stream = 16, index = 28
|
||||
46/0: compressed; stream = 16, index = 29
|
||||
47/0: compressed; stream = 16, index = 30
|
||||
48/0: compressed; stream = 16, index = 31
|
||||
49/0: compressed; stream = 16, index = 32
|
||||
50/0: compressed; stream = 16, index = 33
|
|
@ -0,0 +1,30 @@
|
|||
1/0: uncompressed; offset = 31354
|
||||
2/0: uncompressed; offset = 31614
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 727
|
||||
6/0: uncompressed; offset = 777
|
||||
7/0: uncompressed; offset = 909
|
||||
8/0: uncompressed; offset = 1017
|
||||
9/0: uncompressed; offset = 19127
|
||||
10/0: uncompressed; offset = 19313
|
||||
11/0: uncompressed; offset = 19557
|
||||
12/0: uncompressed; offset = 19948
|
||||
13/0: uncompressed; offset = 20677
|
||||
14/0: uncompressed; offset = 23321
|
||||
15/0: uncompressed; offset = 30318
|
||||
16/0: compressed; stream = 15, index = 0
|
||||
17/0: compressed; stream = 15, index = 1
|
||||
18/0: compressed; stream = 15, index = 2
|
||||
19/0: compressed; stream = 15, index = 3
|
||||
20/0: compressed; stream = 15, index = 4
|
||||
21/0: compressed; stream = 15, index = 5
|
||||
22/0: compressed; stream = 15, index = 6
|
||||
23/0: compressed; stream = 15, index = 7
|
||||
24/0: compressed; stream = 15, index = 8
|
||||
25/0: compressed; stream = 15, index = 9
|
||||
26/0: compressed; stream = 15, index = 10
|
||||
27/0: compressed; stream = 15, index = 11
|
||||
28/0: compressed; stream = 15, index = 12
|
||||
29/0: compressed; stream = 15, index = 13
|
||||
30/0: compressed; stream = 15, index = 14
|
|
@ -0,0 +1,28 @@
|
|||
1/0: uncompressed; offset = 27064
|
||||
2/0: uncompressed; offset = 27312
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 713
|
||||
6/0: uncompressed; offset = 763
|
||||
7/0: uncompressed; offset = 892
|
||||
8/0: uncompressed; offset = 1007
|
||||
9/0: uncompressed; offset = 1235
|
||||
10/0: uncompressed; offset = 4832
|
||||
11/0: uncompressed; offset = 12199
|
||||
12/0: uncompressed; offset = 19196
|
||||
13/0: uncompressed; offset = 26341
|
||||
14/0: compressed; stream = 13, index = 0
|
||||
15/0: compressed; stream = 13, index = 1
|
||||
16/0: compressed; stream = 13, index = 2
|
||||
17/0: compressed; stream = 13, index = 3
|
||||
18/0: compressed; stream = 13, index = 4
|
||||
19/0: compressed; stream = 13, index = 5
|
||||
20/0: compressed; stream = 13, index = 6
|
||||
21/0: compressed; stream = 13, index = 7
|
||||
22/0: compressed; stream = 13, index = 8
|
||||
23/0: compressed; stream = 13, index = 9
|
||||
24/0: compressed; stream = 13, index = 10
|
||||
25/0: compressed; stream = 13, index = 11
|
||||
26/0: compressed; stream = 13, index = 12
|
||||
27/0: compressed; stream = 13, index = 13
|
||||
28/0: compressed; stream = 13, index = 14
|
|
@ -0,0 +1,20 @@
|
|||
1/0: uncompressed; offset = 4964
|
||||
2/0: uncompressed; offset = 5023
|
||||
3/0: uncompressed; offset = 5234
|
||||
4/0: uncompressed; offset = 15
|
||||
5/0: uncompressed; offset = 734
|
||||
6/0: uncompressed; offset = 799
|
||||
7/0: uncompressed; offset = 933
|
||||
8/0: uncompressed; offset = 1104
|
||||
9/0: uncompressed; offset = 1947
|
||||
10/0: uncompressed; offset = 1992
|
||||
11/0: uncompressed; offset = 2182
|
||||
12/0: uncompressed; offset = 2427
|
||||
13/0: uncompressed; offset = 2597
|
||||
14/0: uncompressed; offset = 2822
|
||||
15/0: uncompressed; offset = 2989
|
||||
16/0: uncompressed; offset = 3239
|
||||
17/0: uncompressed; offset = 3271
|
||||
18/0: uncompressed; offset = 3328
|
||||
19/0: uncompressed; offset = 3740
|
||||
20/0: uncompressed; offset = 4270
|
|
@ -0,0 +1,23 @@
|
|||
1/0: uncompressed; offset = 31058
|
||||
2/0: uncompressed; offset = 31307
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 678
|
||||
6/0: uncompressed; offset = 728
|
||||
7/0: uncompressed; offset = 855
|
||||
8/0: uncompressed; offset = 970
|
||||
9/0: uncompressed; offset = 1203
|
||||
10/0: uncompressed; offset = 18852
|
||||
11/0: uncompressed; offset = 30165
|
||||
12/0: compressed; stream = 11, index = 0
|
||||
13/0: compressed; stream = 11, index = 1
|
||||
14/0: compressed; stream = 11, index = 2
|
||||
15/0: compressed; stream = 11, index = 3
|
||||
16/0: compressed; stream = 11, index = 4
|
||||
17/0: compressed; stream = 11, index = 5
|
||||
18/0: compressed; stream = 11, index = 6
|
||||
19/0: compressed; stream = 11, index = 7
|
||||
20/0: compressed; stream = 11, index = 8
|
||||
21/0: compressed; stream = 11, index = 9
|
||||
22/0: compressed; stream = 11, index = 10
|
||||
23/0: compressed; stream = 11, index = 11
|
|
@ -0,0 +1,26 @@
|
|||
1/0: uncompressed; offset = 6344
|
||||
2/0: uncompressed; offset = 15
|
||||
3/0: uncompressed; offset = 216
|
||||
4/0: uncompressed; offset = 707
|
||||
5/0: uncompressed; offset = 757
|
||||
6/0: uncompressed; offset = 887
|
||||
7/0: uncompressed; offset = 990
|
||||
8/0: uncompressed; offset = 1257
|
||||
9/0: uncompressed; offset = 1679
|
||||
10/0: uncompressed; offset = 2052
|
||||
11/0: uncompressed; offset = 4249
|
||||
12/0: uncompressed; offset = 4343
|
||||
13/0: uncompressed; offset = 5387
|
||||
14/0: uncompressed; offset = 5481
|
||||
15/0: uncompressed; offset = 5519
|
||||
16/0: compressed; stream = 15, index = 0
|
||||
17/0: compressed; stream = 15, index = 1
|
||||
18/0: compressed; stream = 15, index = 2
|
||||
19/0: compressed; stream = 15, index = 3
|
||||
20/0: compressed; stream = 15, index = 4
|
||||
21/0: compressed; stream = 15, index = 5
|
||||
22/0: compressed; stream = 15, index = 6
|
||||
23/0: compressed; stream = 15, index = 7
|
||||
24/0: compressed; stream = 15, index = 8
|
||||
25/0: compressed; stream = 15, index = 9
|
||||
26/0: compressed; stream = 15, index = 10
|
|
@ -0,0 +1,23 @@
|
|||
1/0: uncompressed; offset = 34767
|
||||
2/0: uncompressed; offset = 35015
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 678
|
||||
6/0: uncompressed; offset = 728
|
||||
7/0: uncompressed; offset = 856
|
||||
8/0: uncompressed; offset = 971
|
||||
9/0: uncompressed; offset = 1394
|
||||
10/0: uncompressed; offset = 10990
|
||||
11/0: uncompressed; offset = 19087
|
||||
12/0: uncompressed; offset = 33769
|
||||
13/0: compressed; stream = 12, index = 0
|
||||
14/0: compressed; stream = 12, index = 1
|
||||
15/0: compressed; stream = 12, index = 2
|
||||
16/0: compressed; stream = 12, index = 3
|
||||
17/0: compressed; stream = 12, index = 4
|
||||
18/0: compressed; stream = 12, index = 5
|
||||
19/0: compressed; stream = 12, index = 6
|
||||
20/0: compressed; stream = 12, index = 7
|
||||
21/0: compressed; stream = 12, index = 8
|
||||
22/0: compressed; stream = 12, index = 9
|
||||
23/0: compressed; stream = 12, index = 10
|
|
@ -0,0 +1,22 @@
|
|||
1/0: uncompressed; offset = 23295
|
||||
2/0: uncompressed; offset = 23543
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 671
|
||||
6/0: uncompressed; offset = 721
|
||||
7/0: uncompressed; offset = 847
|
||||
8/0: uncompressed; offset = 955
|
||||
9/0: uncompressed; offset = 7385
|
||||
10/0: uncompressed; offset = 15752
|
||||
11/0: uncompressed; offset = 22721
|
||||
12/0: compressed; stream = 11, index = 0
|
||||
13/0: compressed; stream = 11, index = 1
|
||||
14/0: compressed; stream = 11, index = 2
|
||||
15/0: compressed; stream = 11, index = 3
|
||||
16/0: compressed; stream = 11, index = 4
|
||||
17/0: compressed; stream = 11, index = 5
|
||||
18/0: compressed; stream = 11, index = 6
|
||||
19/0: compressed; stream = 11, index = 7
|
||||
20/0: compressed; stream = 11, index = 8
|
||||
21/0: compressed; stream = 11, index = 9
|
||||
22/0: compressed; stream = 11, index = 10
|
|
@ -0,0 +1,20 @@
|
|||
1/0: uncompressed; offset = 24490
|
||||
2/0: uncompressed; offset = 24739
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 657
|
||||
6/0: uncompressed; offset = 707
|
||||
7/0: uncompressed; offset = 833
|
||||
8/0: uncompressed; offset = 948
|
||||
9/0: uncompressed; offset = 1290
|
||||
10/0: uncompressed; offset = 13083
|
||||
11/0: uncompressed; offset = 23411
|
||||
12/0: compressed; stream = 11, index = 0
|
||||
13/0: compressed; stream = 11, index = 1
|
||||
14/0: compressed; stream = 11, index = 2
|
||||
15/0: compressed; stream = 11, index = 3
|
||||
16/0: compressed; stream = 11, index = 4
|
||||
17/0: compressed; stream = 11, index = 5
|
||||
18/0: compressed; stream = 11, index = 6
|
||||
19/0: compressed; stream = 11, index = 7
|
||||
20/0: compressed; stream = 11, index = 8
|
|
@ -0,0 +1,31 @@
|
|||
1/0: uncompressed; offset = 43550
|
||||
2/0: uncompressed; offset = 43799
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 734
|
||||
6/0: uncompressed; offset = 784
|
||||
7/0: uncompressed; offset = 913
|
||||
8/0: uncompressed; offset = 1021
|
||||
9/0: uncompressed; offset = 1546
|
||||
10/0: uncompressed; offset = 5794
|
||||
11/0: uncompressed; offset = 12915
|
||||
12/0: uncompressed; offset = 23660
|
||||
13/0: uncompressed; offset = 30657
|
||||
14/0: uncompressed; offset = 42604
|
||||
15/0: compressed; stream = 14, index = 0
|
||||
16/0: compressed; stream = 14, index = 1
|
||||
17/0: compressed; stream = 14, index = 2
|
||||
18/0: compressed; stream = 14, index = 3
|
||||
19/0: compressed; stream = 14, index = 4
|
||||
20/0: compressed; stream = 14, index = 5
|
||||
21/0: compressed; stream = 14, index = 6
|
||||
22/0: compressed; stream = 14, index = 7
|
||||
23/0: compressed; stream = 14, index = 8
|
||||
24/0: compressed; stream = 14, index = 9
|
||||
25/0: compressed; stream = 14, index = 10
|
||||
26/0: compressed; stream = 14, index = 11
|
||||
27/0: compressed; stream = 14, index = 12
|
||||
28/0: compressed; stream = 14, index = 13
|
||||
29/0: compressed; stream = 14, index = 14
|
||||
30/0: compressed; stream = 14, index = 15
|
||||
31/0: compressed; stream = 14, index = 16
|
|
@ -0,0 +1,39 @@
|
|||
1/0: uncompressed; offset = 75299
|
||||
2/0: uncompressed; offset = 75548
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 790
|
||||
6/0: uncompressed; offset = 840
|
||||
7/0: uncompressed; offset = 975
|
||||
8/0: uncompressed; offset = 1083
|
||||
9/0: uncompressed; offset = 2128
|
||||
10/0: uncompressed; offset = 13799
|
||||
11/0: uncompressed; offset = 23682
|
||||
12/0: uncompressed; offset = 31867
|
||||
13/0: uncompressed; offset = 36116
|
||||
14/0: uncompressed; offset = 50352
|
||||
15/0: uncompressed; offset = 61569
|
||||
16/0: uncompressed; offset = 73516
|
||||
17/0: compressed; stream = 16, index = 0
|
||||
18/0: compressed; stream = 16, index = 1
|
||||
19/0: compressed; stream = 16, index = 2
|
||||
20/0: compressed; stream = 16, index = 3
|
||||
21/0: compressed; stream = 16, index = 4
|
||||
22/0: compressed; stream = 16, index = 5
|
||||
23/0: compressed; stream = 16, index = 6
|
||||
24/0: compressed; stream = 16, index = 7
|
||||
25/0: compressed; stream = 16, index = 8
|
||||
26/0: compressed; stream = 16, index = 9
|
||||
27/0: compressed; stream = 16, index = 10
|
||||
28/0: compressed; stream = 16, index = 11
|
||||
29/0: compressed; stream = 16, index = 12
|
||||
30/0: compressed; stream = 16, index = 13
|
||||
31/0: compressed; stream = 16, index = 14
|
||||
32/0: compressed; stream = 16, index = 15
|
||||
33/0: compressed; stream = 16, index = 16
|
||||
34/0: compressed; stream = 16, index = 17
|
||||
35/0: compressed; stream = 16, index = 18
|
||||
36/0: compressed; stream = 16, index = 19
|
||||
37/0: compressed; stream = 16, index = 20
|
||||
38/0: compressed; stream = 16, index = 21
|
||||
39/0: compressed; stream = 16, index = 22
|
|
@ -0,0 +1,26 @@
|
|||
1/0: uncompressed; offset = 25097
|
||||
2/0: uncompressed; offset = 25156
|
||||
3/0: uncompressed; offset = 25367
|
||||
4/0: uncompressed; offset = 15
|
||||
5/0: uncompressed; offset = 854
|
||||
6/0: uncompressed; offset = 919
|
||||
7/0: uncompressed; offset = 1074
|
||||
8/0: uncompressed; offset = 1245
|
||||
9/0: uncompressed; offset = 18343
|
||||
10/0: uncompressed; offset = 18388
|
||||
11/0: uncompressed; offset = 18752
|
||||
12/0: uncompressed; offset = 19071
|
||||
13/0: uncompressed; offset = 19360
|
||||
14/0: uncompressed; offset = 19604
|
||||
15/0: uncompressed; offset = 19770
|
||||
16/0: uncompressed; offset = 20007
|
||||
17/0: uncompressed; offset = 20174
|
||||
18/0: uncompressed; offset = 20424
|
||||
19/0: uncompressed; offset = 20456
|
||||
20/0: uncompressed; offset = 20525
|
||||
21/0: uncompressed; offset = 23109
|
||||
22/0: uncompressed; offset = 23500
|
||||
23/0: uncompressed; offset = 24229
|
||||
24/0: uncompressed; offset = 24641
|
||||
25/0: uncompressed; offset = 24741
|
||||
26/0: uncompressed; offset = 24985
|
|
@ -0,0 +1,18 @@
|
|||
1/0: uncompressed; offset = 3568
|
||||
2/0: uncompressed; offset = 3777
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 643
|
||||
6/0: uncompressed; offset = 693
|
||||
7/0: uncompressed; offset = 819
|
||||
8/0: uncompressed; offset = 934
|
||||
9/0: uncompressed; offset = 1118
|
||||
10/0: uncompressed; offset = 1210
|
||||
11/0: uncompressed; offset = 2555
|
||||
12/0: uncompressed; offset = 3030
|
||||
13/0: compressed; stream = 12, index = 0
|
||||
14/0: compressed; stream = 12, index = 1
|
||||
15/0: compressed; stream = 12, index = 2
|
||||
16/0: compressed; stream = 12, index = 3
|
||||
17/0: compressed; stream = 12, index = 4
|
||||
18/0: compressed; stream = 12, index = 5
|
|
@ -0,0 +1,26 @@
|
|||
1/0: uncompressed; offset = 16762
|
||||
2/0: uncompressed; offset = 16877
|
||||
3/0: uncompressed; offset = 17142
|
||||
4/0: uncompressed; offset = 24335
|
||||
5/0: uncompressed; offset = 32164
|
||||
6/0: uncompressed; offset = 32412
|
||||
7/0: uncompressed; offset = 15
|
||||
8/0: uncompressed; offset = 216
|
||||
9/0: uncompressed; offset = 671
|
||||
10/0: uncompressed; offset = 721
|
||||
11/0: uncompressed; offset = 856
|
||||
12/0: uncompressed; offset = 973
|
||||
13/0: uncompressed; offset = 1318
|
||||
14/0: uncompressed; offset = 2218
|
||||
15/0: compressed; stream = 13, index = 0
|
||||
16/0: compressed; stream = 13, index = 1
|
||||
17/0: compressed; stream = 13, index = 2
|
||||
18/0: compressed; stream = 13, index = 3
|
||||
19/0: compressed; stream = 13, index = 4
|
||||
20/0: compressed; stream = 13, index = 5
|
||||
21/0: compressed; stream = 13, index = 6
|
||||
22/0: compressed; stream = 13, index = 7
|
||||
23/0: compressed; stream = 13, index = 8
|
||||
24/0: compressed; stream = 13, index = 9
|
||||
25/0: compressed; stream = 13, index = 10
|
||||
26/0: compressed; stream = 13, index = 11
|
|
@ -0,0 +1,22 @@
|
|||
1/0: uncompressed; offset = 16778
|
||||
2/0: uncompressed; offset = 16893
|
||||
3/0: uncompressed; offset = 17109
|
||||
4/0: uncompressed; offset = 24938
|
||||
5/0: uncompressed; offset = 25186
|
||||
6/0: uncompressed; offset = 15
|
||||
7/0: uncompressed; offset = 216
|
||||
8/0: uncompressed; offset = 650
|
||||
9/0: uncompressed; offset = 700
|
||||
10/0: uncompressed; offset = 836
|
||||
11/0: uncompressed; offset = 953
|
||||
12/0: uncompressed; offset = 1298
|
||||
13/0: uncompressed; offset = 2103
|
||||
14/0: compressed; stream = 12, index = 0
|
||||
15/0: compressed; stream = 12, index = 1
|
||||
16/0: compressed; stream = 12, index = 2
|
||||
17/0: compressed; stream = 12, index = 3
|
||||
18/0: compressed; stream = 12, index = 4
|
||||
19/0: compressed; stream = 12, index = 5
|
||||
20/0: compressed; stream = 12, index = 6
|
||||
21/0: compressed; stream = 12, index = 7
|
||||
22/0: compressed; stream = 12, index = 8
|
|
@ -0,0 +1,19 @@
|
|||
1/0: uncompressed; offset = 20679
|
||||
2/0: uncompressed; offset = 20927
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 650
|
||||
6/0: uncompressed; offset = 700
|
||||
7/0: uncompressed; offset = 826
|
||||
8/0: uncompressed; offset = 934
|
||||
9/0: uncompressed; offset = 1252
|
||||
10/0: uncompressed; offset = 8248
|
||||
11/0: uncompressed; offset = 20115
|
||||
12/0: compressed; stream = 11, index = 0
|
||||
13/0: compressed; stream = 11, index = 1
|
||||
14/0: compressed; stream = 11, index = 2
|
||||
15/0: compressed; stream = 11, index = 3
|
||||
16/0: compressed; stream = 11, index = 4
|
||||
17/0: compressed; stream = 11, index = 5
|
||||
18/0: compressed; stream = 11, index = 6
|
||||
19/0: compressed; stream = 11, index = 7
|
|
@ -0,0 +1,32 @@
|
|||
1/0: uncompressed; offset = 29506
|
||||
2/0: uncompressed; offset = 29621
|
||||
3/0: uncompressed; offset = 29918
|
||||
4/0: uncompressed; offset = 30033
|
||||
5/0: uncompressed; offset = 30274
|
||||
6/0: uncompressed; offset = 30389
|
||||
7/0: uncompressed; offset = 30644
|
||||
8/0: uncompressed; offset = 42802
|
||||
9/0: uncompressed; offset = 43050
|
||||
10/0: uncompressed; offset = 15
|
||||
11/0: uncompressed; offset = 216
|
||||
12/0: uncompressed; offset = 695
|
||||
13/0: uncompressed; offset = 746
|
||||
14/0: uncompressed; offset = 900
|
||||
15/0: uncompressed; offset = 1017
|
||||
16/0: uncompressed; offset = 1286
|
||||
17/0: uncompressed; offset = 2443
|
||||
18/0: uncompressed; offset = 13147
|
||||
19/0: compressed; stream = 16, index = 0
|
||||
20/0: compressed; stream = 16, index = 1
|
||||
21/0: compressed; stream = 16, index = 2
|
||||
22/0: compressed; stream = 16, index = 3
|
||||
23/0: compressed; stream = 16, index = 4
|
||||
24/0: compressed; stream = 16, index = 5
|
||||
25/0: compressed; stream = 16, index = 6
|
||||
26/0: compressed; stream = 16, index = 7
|
||||
27/0: compressed; stream = 16, index = 8
|
||||
28/0: compressed; stream = 16, index = 9
|
||||
29/0: compressed; stream = 16, index = 10
|
||||
30/0: compressed; stream = 16, index = 11
|
||||
31/0: compressed; stream = 16, index = 12
|
||||
32/0: compressed; stream = 16, index = 13
|
|
@ -0,0 +1,23 @@
|
|||
1/0: uncompressed; offset = 34102
|
||||
2/0: uncompressed; offset = 34350
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 678
|
||||
6/0: uncompressed; offset = 728
|
||||
7/0: uncompressed; offset = 856
|
||||
8/0: uncompressed; offset = 971
|
||||
9/0: uncompressed; offset = 1514
|
||||
10/0: uncompressed; offset = 10973
|
||||
11/0: uncompressed; offset = 19139
|
||||
12/0: uncompressed; offset = 33047
|
||||
13/0: compressed; stream = 12, index = 0
|
||||
14/0: compressed; stream = 12, index = 1
|
||||
15/0: compressed; stream = 12, index = 2
|
||||
16/0: compressed; stream = 12, index = 3
|
||||
17/0: compressed; stream = 12, index = 4
|
||||
18/0: compressed; stream = 12, index = 5
|
||||
19/0: compressed; stream = 12, index = 6
|
||||
20/0: compressed; stream = 12, index = 7
|
||||
21/0: compressed; stream = 12, index = 8
|
||||
22/0: compressed; stream = 12, index = 9
|
||||
23/0: compressed; stream = 12, index = 10
|
|
@ -0,0 +1,22 @@
|
|||
1/0: uncompressed; offset = 9449
|
||||
2/0: uncompressed; offset = 9564
|
||||
3/0: uncompressed; offset = 9730
|
||||
4/0: uncompressed; offset = 17293
|
||||
5/0: uncompressed; offset = 17541
|
||||
6/0: uncompressed; offset = 15
|
||||
7/0: uncompressed; offset = 216
|
||||
8/0: uncompressed; offset = 650
|
||||
9/0: uncompressed; offset = 700
|
||||
10/0: uncompressed; offset = 835
|
||||
11/0: uncompressed; offset = 952
|
||||
12/0: uncompressed; offset = 1097
|
||||
13/0: uncompressed; offset = 1758
|
||||
14/0: compressed; stream = 12, index = 0
|
||||
15/0: compressed; stream = 12, index = 1
|
||||
16/0: compressed; stream = 12, index = 2
|
||||
17/0: compressed; stream = 12, index = 3
|
||||
18/0: compressed; stream = 12, index = 4
|
||||
19/0: compressed; stream = 12, index = 5
|
||||
20/0: compressed; stream = 12, index = 6
|
||||
21/0: compressed; stream = 12, index = 7
|
||||
22/0: compressed; stream = 12, index = 8
|
|
@ -0,0 +1,23 @@
|
|||
1/0: uncompressed; offset = 37282
|
||||
2/0: uncompressed; offset = 37530
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 678
|
||||
6/0: uncompressed; offset = 728
|
||||
7/0: uncompressed; offset = 856
|
||||
8/0: uncompressed; offset = 971
|
||||
9/0: uncompressed; offset = 1322
|
||||
10/0: uncompressed; offset = 9581
|
||||
11/0: uncompressed; offset = 24286
|
||||
12/0: uncompressed; offset = 36258
|
||||
13/0: compressed; stream = 12, index = 0
|
||||
14/0: compressed; stream = 12, index = 1
|
||||
15/0: compressed; stream = 12, index = 2
|
||||
16/0: compressed; stream = 12, index = 3
|
||||
17/0: compressed; stream = 12, index = 4
|
||||
18/0: compressed; stream = 12, index = 5
|
||||
19/0: compressed; stream = 12, index = 6
|
||||
20/0: compressed; stream = 12, index = 7
|
||||
21/0: compressed; stream = 12, index = 8
|
||||
22/0: compressed; stream = 12, index = 9
|
||||
23/0: compressed; stream = 12, index = 10
|
|
@ -0,0 +1,26 @@
|
|||
1/0: uncompressed; offset = 48194
|
||||
2/0: uncompressed; offset = 48442
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 699
|
||||
6/0: uncompressed; offset = 749
|
||||
7/0: uncompressed; offset = 878
|
||||
8/0: uncompressed; offset = 1000
|
||||
9/0: uncompressed; offset = 8546
|
||||
10/0: uncompressed; offset = 9072
|
||||
11/0: uncompressed; offset = 10659
|
||||
12/0: uncompressed; offset = 18919
|
||||
13/0: uncompressed; offset = 35129
|
||||
14/0: uncompressed; offset = 47101
|
||||
15/0: compressed; stream = 14, index = 0
|
||||
16/0: compressed; stream = 14, index = 1
|
||||
17/0: compressed; stream = 14, index = 2
|
||||
18/0: compressed; stream = 14, index = 3
|
||||
19/0: compressed; stream = 14, index = 4
|
||||
20/0: compressed; stream = 14, index = 5
|
||||
21/0: compressed; stream = 14, index = 6
|
||||
22/0: compressed; stream = 14, index = 7
|
||||
23/0: compressed; stream = 14, index = 8
|
||||
24/0: compressed; stream = 14, index = 9
|
||||
25/0: compressed; stream = 14, index = 10
|
||||
26/0: compressed; stream = 14, index = 11
|
|
@ -0,0 +1,35 @@
|
|||
1/0: uncompressed; offset = 2924
|
||||
2/0: uncompressed; offset = 3039
|
||||
3/0: uncompressed; offset = 4606
|
||||
4/0: uncompressed; offset = 4721
|
||||
5/0: uncompressed; offset = 7754
|
||||
6/0: uncompressed; offset = 7870
|
||||
7/0: uncompressed; offset = 11668
|
||||
8/0: uncompressed; offset = 21077
|
||||
9/0: uncompressed; offset = 28498
|
||||
10/0: uncompressed; offset = 35464
|
||||
11/0: uncompressed; offset = 35699
|
||||
12/0: uncompressed; offset = 15
|
||||
13/0: uncompressed; offset = 216
|
||||
14/0: uncompressed; offset = 703
|
||||
15/0: uncompressed; offset = 754
|
||||
16/0: uncompressed; offset = 909
|
||||
17/0: uncompressed; offset = 1026
|
||||
18/0: uncompressed; offset = 2161
|
||||
19/0: compressed; stream = 18, index = 0
|
||||
20/0: compressed; stream = 18, index = 1
|
||||
21/0: compressed; stream = 18, index = 2
|
||||
22/0: compressed; stream = 18, index = 3
|
||||
23/0: compressed; stream = 18, index = 4
|
||||
24/0: compressed; stream = 18, index = 5
|
||||
25/0: compressed; stream = 18, index = 6
|
||||
26/0: compressed; stream = 18, index = 7
|
||||
27/0: compressed; stream = 18, index = 8
|
||||
28/0: compressed; stream = 18, index = 9
|
||||
29/0: compressed; stream = 18, index = 10
|
||||
30/0: compressed; stream = 18, index = 11
|
||||
31/0: compressed; stream = 18, index = 12
|
||||
32/0: compressed; stream = 18, index = 13
|
||||
33/0: compressed; stream = 18, index = 14
|
||||
34/0: compressed; stream = 18, index = 15
|
||||
35/0: compressed; stream = 18, index = 16
|
|
@ -0,0 +1,19 @@
|
|||
1/0: uncompressed; offset = 8578
|
||||
2/0: uncompressed; offset = 15
|
||||
3/0: uncompressed; offset = 216
|
||||
4/0: uncompressed; offset = 658
|
||||
5/0: uncompressed; offset = 708
|
||||
6/0: uncompressed; offset = 837
|
||||
7/0: uncompressed; offset = 940
|
||||
8/0: uncompressed; offset = 1191
|
||||
9/0: uncompressed; offset = 1627
|
||||
10/0: uncompressed; offset = 7676
|
||||
11/0: uncompressed; offset = 7784
|
||||
12/0: uncompressed; offset = 7822
|
||||
13/0: compressed; stream = 12, index = 0
|
||||
14/0: compressed; stream = 12, index = 1
|
||||
15/0: compressed; stream = 12, index = 2
|
||||
16/0: compressed; stream = 12, index = 3
|
||||
17/0: compressed; stream = 12, index = 4
|
||||
18/0: compressed; stream = 12, index = 5
|
||||
19/0: compressed; stream = 12, index = 6
|
15
services/clsi/test/acceptance/fixtures/minimal.pdfxref
Normal file
15
services/clsi/test/acceptance/fixtures/minimal.pdfxref
Normal file
|
@ -0,0 +1,15 @@
|
|||
1/0: uncompressed; offset = 11784
|
||||
2/0: uncompressed; offset = 12033
|
||||
3/0: uncompressed; offset = 15
|
||||
4/0: uncompressed; offset = 216
|
||||
5/0: uncompressed; offset = 621
|
||||
6/0: uncompressed; offset = 671
|
||||
7/0: uncompressed; offset = 791
|
||||
8/0: uncompressed; offset = 906
|
||||
9/0: uncompressed; offset = 1070
|
||||
10/0: uncompressed; offset = 11235
|
||||
11/0: compressed; stream = 10, index = 0
|
||||
12/0: compressed; stream = 10, index = 1
|
||||
13/0: compressed; stream = 10, index = 2
|
||||
14/0: compressed; stream = 10, index = 3
|
||||
15/0: compressed; stream = 10, index = 4
|
|
@ -5,7 +5,7 @@ const { expect } = require('chai')
|
|||
const MODULE_PATH = '../../../app/js/ContentCacheManager'
|
||||
|
||||
describe('ContentCacheManager', function () {
|
||||
let contentDir, pdfPath
|
||||
let contentDir, pdfPath, xrefPath
|
||||
let ContentCacheManager, files, Settings
|
||||
before(function () {
|
||||
Settings = require('@overleaf/settings')
|
||||
|
@ -38,6 +38,8 @@ describe('ContentCacheManager', function () {
|
|||
'/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/content/1797a7f48f9-5abc1998509dea1f'
|
||||
pdfPath =
|
||||
'/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/generated-files/1797a7f48ea-8ac6805139f43351/output.pdf'
|
||||
xrefPath =
|
||||
'/overleaf/services/clsi/output/602cee6f6460fca0ba7921e6/generated-files/1797a7f48ea-8ac6805139f43351/output.pdfxref'
|
||||
|
||||
reclaimed = 0
|
||||
Settings.pdfCachingMinChunkSize = 1024
|
||||
|
@ -50,7 +52,8 @@ describe('ContentCacheManager', function () {
|
|||
})
|
||||
|
||||
describe('minimal', function () {
|
||||
const PATH_MINIMAL = 'test/acceptance/fixtures/minimal.pdf'
|
||||
const PATH_MINIMAL_PDF = 'test/acceptance/fixtures/minimal.pdf'
|
||||
const PATH_MINIMAL_XREF = 'test/acceptance/fixtures/minimal.pdfxref'
|
||||
const OBJECT_ID_1 = '9 0 '
|
||||
const HASH_LARGE =
|
||||
'd7cfc73ad2fba4578a437517923e3714927bbf35e63ea88bd93c7a8076cf1fcd'
|
||||
|
@ -62,9 +65,10 @@ describe('ContentCacheManager', function () {
|
|||
}
|
||||
let MINIMAL_SIZE, RANGE_1, RANGE_2, h1, h2, START_1, START_2, END_1, END_2
|
||||
before(async function () {
|
||||
await fs.promises.copyFile(PATH_MINIMAL, pdfPath)
|
||||
const MINIMAL = await fs.promises.readFile(PATH_MINIMAL)
|
||||
MINIMAL_SIZE = (await fs.promises.stat(PATH_MINIMAL)).size
|
||||
await fs.promises.copyFile(PATH_MINIMAL_PDF, pdfPath)
|
||||
await fs.promises.copyFile(PATH_MINIMAL_XREF, xrefPath)
|
||||
const MINIMAL = await fs.promises.readFile(PATH_MINIMAL_PDF)
|
||||
MINIMAL_SIZE = (await fs.promises.stat(PATH_MINIMAL_PDF)).size
|
||||
RANGE_1 = await fs.promises.readFile(getChunkPath(HASH_LARGE))
|
||||
RANGE_2 = await fs.promises.readFile(getChunkPath(HASH_SMALL))
|
||||
h1 = HASH_LARGE
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
const fs = require('fs')
|
||||
const Path = require('path')
|
||||
const { expect } = require('chai')
|
||||
const { parseXrefTable } = require('../../../app/lib/pdfjs/parseXrefTable')
|
||||
const { parseXrefTable } = require('../../../app/js/XrefParser')
|
||||
const { NoXrefTableError } = require('../../../app/js/Errors')
|
||||
const PATH_EXAMPLES = 'test/acceptance/fixtures/examples/'
|
||||
const PATH_SNAPSHOTS = 'test/unit/js/snapshots/pdfjs/'
|
||||
const EXAMPLES = fs.readdirSync(PATH_EXAMPLES)
|
||||
|
@ -48,24 +49,11 @@ describe('pdfjs', function () {
|
|||
describe('when the pdf is an empty file', function () {
|
||||
it('should yield no entries', async function () {
|
||||
const path = 'does/not/matter.pdf'
|
||||
const table = await parseXrefTable(path, 0)
|
||||
expect(table).to.deep.equal([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the operation times out', function () {
|
||||
it('should bail out', async function () {
|
||||
const path = pdfPath(EXAMPLES[0])
|
||||
const { size } = await loadContext(EXAMPLES[0])
|
||||
const err = new Error()
|
||||
let table
|
||||
try {
|
||||
table = await parseXrefTable(path, size, () => {
|
||||
throw err
|
||||
})
|
||||
table = await parseXrefTable(path, 0)
|
||||
} catch (e) {
|
||||
expect(e).to.equal(err)
|
||||
return
|
||||
expect(e).to.be.an.instanceof(NoXrefTableError)
|
||||
}
|
||||
expect(table).to.not.exist
|
||||
})
|
||||
|
@ -89,7 +77,16 @@ describe('pdfjs', function () {
|
|||
|
||||
it('should produce the expected xRef table', async function () {
|
||||
const table = await parseXrefTable(pdfPath(example), size, () => {})
|
||||
expect(table).to.deep.equal(snapshot)
|
||||
// compare the essential parts of the xref table only
|
||||
expect(table.xRefEntries[0]).to.include({ offset: 0 })
|
||||
expect(table.xRefEntries.slice(1)).to.deep.equal(
|
||||
snapshot.xRefEntries
|
||||
.slice(1)
|
||||
.filter(xref => xref.uncompressed) // we only use the uncompressed fields
|
||||
.map(xref => {
|
||||
return { offset: xref.offset, uncompressed: xref.uncompressed } // ignore unused gen field
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue