Files
snk/svg-only/dist/155.index.js
release bot a69d1dbca7 📦 3.3.0
2025-02-20 17:07:41 +00:00

2129 lines
54 KiB
JavaScript

exports.id = 155;
exports.ids = [155];
exports.modules = {
/***/ 1680:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
module.exports = __webpack_require__(7739)
/***/ }),
/***/ 7739:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
const stream = __webpack_require__(2203)
const EventEmitter = __webpack_require__(4434)
const LZWEncoder = __webpack_require__(3500)
const NeuQuant = __webpack_require__(222)
const { OctreeQuant, Color } = __webpack_require__(2756)
class ByteArray {
constructor() {
this.data = []
}
getData() {
return Buffer.from(this.data)
}
writeByte(val) {
this.data.push(val)
}
writeUTFBytes(str) {
for (var len = str.length, i = 0; i < len; i++) {
this.writeByte(str.charCodeAt(i))
}
}
writeBytes(array, offset, length) {
for (var len = length || array.length, i = offset || 0; i < len; i++) {
this.writeByte(array[i])
}
}
}
class GIFEncoder extends EventEmitter {
constructor(width, height, algorithm = 'neuquant', useOptimizer = false, totalFrames = 0) {
super()
this.width = ~~width
this.height = ~~height
this.algorithm = algorithm
this.useOptimizer = useOptimizer
this.totalFrames = totalFrames
this.frames = 1
this.threshold = 90
this.indexedPixels = null
this.palSizeNeu = 7
this.palSizeOct = 7
this.sample = 10
this.colorTab = null
this.reuseTab = null
this.colorDepth = null
this.usedEntry = new Array()
this.firstFrame = true
this.started = false
this.image = null
this.prevImage = null
this.dispose = -1
this.repeat = 0
this.delay = 0
this.transparent = null
this.transIndex = 0
this.readStreams = []
this.out = new ByteArray()
}
createReadStream(rs) {
if (!rs) {
rs = new stream.Readable()
rs._read = function() {}
}
this.readStreams.push(rs)
return rs
}
emitData() {
if (this.readStreams.length === 0) {
return
}
if (this.out.data.length) {
this.readStreams.forEach(rs => {
rs.push(Buffer.from(this.out.data))
})
this.out.data = []
}
}
start() {
this.out.writeUTFBytes('GIF89a')
this.started = true
this.emitData()
}
end() {
if (this.readStreams.length === null) {
return
}
this.emitData()
this.readStreams.forEach(rs => rs.push(null))
this.readStreams = []
}
addFrame(input) {
if (input && input.getImageData) {
this.image = input.getImageData(0, 0, this.width, this.height).data
} else {
this.image = input
}
this.analyzePixels()
if (this.firstFrame) {
this.writeLSD()
this.writePalette()
if (this.repeat >= 0) {
this.writeNetscapeExt()
}
}
this.writeGraphicCtrlExt()
this.writeImageDesc()
if (!this.firstFrame) {
this.writePalette()
}
this.writePixels()
this.firstFrame = false
this.emitData()
if (this.totalFrames) {
this.emit('progress', Math.floor((this.frames++ / this.totalFrames) * 100))
}
}
analyzePixels() {
const w = this.width
const h = this.height
var data = this.image
if (this.useOptimizer && this.prevImage) {
var delta = 0
for (var len = data.length, i = 0; i < len; i += 4) {
if (
data[i] !== this.prevImage[i] ||
data[i + 1] !== this.prevImage[i + 1] ||
data[i + 2] !== this.prevImage[i + 2]
) {
delta++
}
}
const match = 100 - Math.ceil((delta / (data.length / 4)) * 100)
this.reuseTab = match >= this.threshold
}
this.prevImage = data
if (this.algorithm === 'neuquant') {
var count = 0
this.pixels = new Uint8Array(w * h * 3)
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
var b = i * w * 4 + j * 4
this.pixels[count++] = data[b]
this.pixels[count++] = data[b + 1]
this.pixels[count++] = data[b + 2]
}
}
var nPix = this.pixels.length / 3
this.indexedPixels = new Uint8Array(nPix)
if (!this.reuseTab) {
this.quantizer = new NeuQuant(this.pixels, this.sample)
this.quantizer.buildColormap()
this.colorTab = this.quantizer.getColormap()
}
var k = 0
for (var j = 0; j < nPix; j++) {
var index = this.quantizer.lookupRGB(
this.pixels[k++] & 0xff,
this.pixels[k++] & 0xff,
this.pixels[k++] & 0xff
)
this.usedEntry[index] = true
this.indexedPixels[j] = index
}
this.colorDepth = 8
this.palSizeNeu = 7
this.pixels = null
} else if (this.algorithm === 'octree') {
this.colors = []
if (!this.reuseTab) {
this.quantizer = new OctreeQuant()
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
var b = i * w * 4 + j * 4
const color = new Color(data[b], data[b + 1], data[b + 2])
this.colors.push(color)
if (!this.reuseTab) {
this.quantizer.addColor(color)
}
}
}
const nPix = this.colors.length
this.indexedPixels = new Uint8Array(nPix)
if (!this.reuseTab) {
this.colorTab = []
const palette = this.quantizer.makePalette(Math.pow(2, this.palSizeOct + 1))
for (const p of palette) {
this.colorTab.push(p.red, p.green, p.blue)
}
}
for (var i = 0; i < nPix; i++) {
this.indexedPixels[i] = this.quantizer.getPaletteIndex(this.colors[i])
}
this.colorDepth = this.palSizeOct + 1
}
if (this.transparent !== null) {
this.transIndex = this.findClosest(this.transparent)
for (var pixelIndex = 0; pixelIndex < nPix; pixelIndex++) {
if (this.image[pixelIndex * 4 + 3] == 0) {
this.indexedPixels[pixelIndex] = this.transIndex
}
}
}
}
findClosest(c) {
if (this.colorTab === null) {
return -1
}
var r = (c & 0xff0000) >> 16
var g = (c & 0x00ff00) >> 8
var b = c & 0x0000ff
var minpos = 0
var dmin = 256 * 256 * 256
var len = this.colorTab.length
for (var i = 0; i < len; ) {
var index = i / 3
var dr = r - (this.colorTab[i++] & 0xff)
var dg = g - (this.colorTab[i++] & 0xff)
var db = b - (this.colorTab[i++] & 0xff)
var d = dr * dr + dg * dg + db * db
if (this.usedEntry[index] && d < dmin) {
dmin = d
minpos = index
}
}
return minpos
}
setFrameRate(fps) {
this.delay = Math.round(100 / fps)
}
setDelay(ms) {
this.delay = Math.round(ms / 10)
}
setDispose(code) {
if (code >= 0) {
this.dispose = code
}
}
setRepeat(repeat) {
this.repeat = repeat
}
setTransparent(color) {
this.transparent = color
}
setQuality(quality) {
if (quality < 1) {
quality = 1
}
this.quality = quality
}
setThreshold(threshold) {
if (threshold > 100) {
threshold = 100
} else if (threshold < 0) {
threshold = 0
}
this.threshold = threshold
}
setPaletteSize(size) {
if (size > 7) {
size = 7
} else if (size < 4) {
size = 4
}
this.palSizeOct = size
}
writeLSD() {
this.writeShort(this.width)
this.writeShort(this.height)
this.out.writeByte(0x80 | 0x70 | 0x00 | this.palSizeNeu)
this.out.writeByte(0)
this.out.writeByte(0)
}
writeGraphicCtrlExt() {
this.out.writeByte(0x21)
this.out.writeByte(0xf9)
this.out.writeByte(4)
var transp, disp
if (this.transparent === null) {
transp = 0
disp = 0
} else {
transp = 1
disp = 2
}
if (this.dispose >= 0) {
disp = this.dispose & 7
}
disp <<= 2
this.out.writeByte(0 | disp | 0 | transp)
this.writeShort(this.delay)
this.out.writeByte(this.transIndex)
this.out.writeByte(0)
}
writeNetscapeExt() {
this.out.writeByte(0x21)
this.out.writeByte(0xff)
this.out.writeByte(11)
this.out.writeUTFBytes('NETSCAPE2.0')
this.out.writeByte(3)
this.out.writeByte(1)
this.writeShort(this.repeat)
this.out.writeByte(0)
}
writeImageDesc() {
this.out.writeByte(0x2c)
this.writeShort(0)
this.writeShort(0)
this.writeShort(this.width)
this.writeShort(this.height)
if (this.firstFrame) {
this.out.writeByte(0)
} else {
this.out.writeByte(0x80 | 0 | 0 | 0 | this.palSizeNeu)
}
}
writePalette() {
this.out.writeBytes(this.colorTab)
var n = 3 * 256 - this.colorTab.length
for (var i = 0; i < n; i++) {
this.out.writeByte(0)
}
}
writeShort(pValue) {
this.out.writeByte(pValue & 0xff)
this.out.writeByte((pValue >> 8) & 0xff)
}
writePixels() {
var enc = new LZWEncoder(this.width, this.height, this.indexedPixels, this.colorDepth)
enc.encode(this.out)
}
finish() {
this.out.writeByte(0x3b)
this.end()
}
}
module.exports = GIFEncoder
/***/ }),
/***/ 3500:
/***/ ((module) => {
/*
LZWEncoder.js
Authors
Kevin Weiner (original Java version - kweiner@fmsware.com)
Thibault Imbert (AS3 version - bytearray.org)
Johan Nordberg (JS version - code@johan-nordberg.com)
Acknowledgements
GIFCOMPR.C - GIF Image compression routines
Lempel-Ziv compression based on 'compress'. GIF modifications by
David Rowley (mgardi@watdcsu.waterloo.edu)
GIF Image compression - modified 'compress'
Based on: compress.c - File compression ala IEEE Computer, June 1984.
By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
Jim McKie (decvax!mcvax!jim)
Steve Davies (decvax!vax135!petsd!peora!srd)
Ken Turkowski (decvax!decwrl!turtlevax!ken)
James A. Woods (decvax!ihnp4!ames!jaw)
Joe Orost (decvax!vax135!petsd!joe)
*/
var EOF = -1
var BITS = 12
var HSIZE = 5003 // 80% occupancy
var masks = [
0x0000,
0x0001,
0x0003,
0x0007,
0x000f,
0x001f,
0x003f,
0x007f,
0x00ff,
0x01ff,
0x03ff,
0x07ff,
0x0fff,
0x1fff,
0x3fff,
0x7fff,
0xffff
]
function LZWEncoder(width, height, pixels, colorDepth) {
var initCodeSize = Math.max(2, colorDepth)
var accum = new Uint8Array(256)
var htab = new Int32Array(HSIZE)
var codetab = new Int32Array(HSIZE)
var cur_accum,
cur_bits = 0
var a_count
var free_ent = 0 // first unused entry
var maxcode
// block compression parameters -- after all codes are used up,
// and compression rate changes, start over.
var clear_flg = false
// Algorithm: use open addressing double hashing (no chaining) on the
// prefix code / next character combination. We do a variant of Knuth's
// algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
// secondary probe. Here, the modular division first probe is gives way
// to a faster exclusive-or manipulation. Also do block compression with
// an adaptive reset, whereby the code table is cleared when the compression
// ratio decreases, but after the table fills. The variable-length output
// codes are re-sized at this point, and a special CLEAR code is generated
// for the decompressor. Late addition: construct the table according to
// file size for noticeable speed improvement on small files. Please direct
// questions about this implementation to ames!jaw.
var g_init_bits, ClearCode, EOFCode
// Add a character to the end of the current packet, and if it is 254
// characters, flush the packet to disk.
function char_out(c, outs) {
accum[a_count++] = c
if (a_count >= 254) flush_char(outs)
}
// Clear out the hash table
// table clear for block compress
function cl_block(outs) {
cl_hash(HSIZE)
free_ent = ClearCode + 2
clear_flg = true
output(ClearCode, outs)
}
// Reset code table
function cl_hash(hsize) {
for (var i = 0; i < hsize; ++i) htab[i] = -1
}
function compress(init_bits, outs) {
var fcode, c, i, ent, disp, hsize_reg, hshift
// Set up the globals: g_init_bits - initial number of bits
g_init_bits = init_bits
// Set up the necessary values
clear_flg = false
n_bits = g_init_bits
maxcode = MAXCODE(n_bits)
ClearCode = 1 << (init_bits - 1)
EOFCode = ClearCode + 1
free_ent = ClearCode + 2
a_count = 0 // clear packet
ent = nextPixel()
hshift = 0
for (fcode = HSIZE; fcode < 65536; fcode *= 2) ++hshift
hshift = 8 - hshift // set hash code range bound
hsize_reg = HSIZE
cl_hash(hsize_reg) // clear hash table
output(ClearCode, outs)
outer_loop: while ((c = nextPixel()) != EOF) {
fcode = (c << BITS) + ent
i = (c << hshift) ^ ent // xor hashing
if (htab[i] === fcode) {
ent = codetab[i]
continue
} else if (htab[i] >= 0) {
// non-empty slot
disp = hsize_reg - i // secondary hash (after G. Knott)
if (i === 0) disp = 1
do {
if ((i -= disp) < 0) i += hsize_reg
if (htab[i] === fcode) {
ent = codetab[i]
continue outer_loop
}
} while (htab[i] >= 0)
}
output(ent, outs)
ent = c
if (free_ent < 1 << BITS) {
codetab[i] = free_ent++ // code -> hashtable
htab[i] = fcode
} else {
cl_block(outs)
}
}
// Put out the final code.
output(ent, outs)
output(EOFCode, outs)
}
function encode(outs) {
outs.writeByte(initCodeSize) // write "initial code size" byte
remaining = width * height // reset navigation variables
curPixel = 0
compress(initCodeSize + 1, outs) // compress and write the pixel data
outs.writeByte(0) // write block terminator
}
// Flush the packet to disk, and reset the accumulator
function flush_char(outs) {
if (a_count > 0) {
outs.writeByte(a_count)
outs.writeBytes(accum, 0, a_count)
a_count = 0
}
}
function MAXCODE(n_bits) {
return (1 << n_bits) - 1
}
// Return the next pixel from the image
function nextPixel() {
if (remaining === 0) return EOF
--remaining
var pix = pixels[curPixel++]
return pix & 0xff
}
function output(code, outs) {
cur_accum &= masks[cur_bits]
if (cur_bits > 0) cur_accum |= code << cur_bits
else cur_accum = code
cur_bits += n_bits
while (cur_bits >= 8) {
char_out(cur_accum & 0xff, outs)
cur_accum >>= 8
cur_bits -= 8
}
// If the next entry is going to be too big for the code size,
// then increase it, if possible.
if (free_ent > maxcode || clear_flg) {
if (clear_flg) {
maxcode = MAXCODE((n_bits = g_init_bits))
clear_flg = false
} else {
++n_bits
if (n_bits == BITS) maxcode = 1 << BITS
else maxcode = MAXCODE(n_bits)
}
}
if (code == EOFCode) {
// At EOF, write the rest of the buffer.
while (cur_bits > 0) {
char_out(cur_accum & 0xff, outs)
cur_accum >>= 8
cur_bits -= 8
}
flush_char(outs)
}
}
this.encode = encode
}
module.exports = LZWEncoder
/***/ }),
/***/ 2756:
/***/ ((module) => {
/*
Authors
Dmitry Alimov (Python version) https://github.com/delimitry/octree_color_quantizer
Tom MacWright (JavaScript version) https://observablehq.com/@tmcw/octree-color-quantization
*/
const MAX_DEPTH = 8
class OctreeQuant {
constructor() {
this.levels = Array.from({ length: MAX_DEPTH }, () => [])
this.root = new Node(0, this)
}
addColor(color) {
this.root.addColor(color, 0, this)
}
makePalette(colorCount) {
let palette = []
let paletteIndex = 0
let leafCount = this.leafNodes.length
for (let level = MAX_DEPTH - 1; level > -1; level -= 1) {
if (this.levels[level]) {
for (let node of this.levels[level]) {
leafCount -= node.removeLeaves()
if (leafCount <= colorCount) break
}
if (leafCount <= colorCount) break
this.levels[level] = []
}
}
for (let node of this.leafNodes) {
if (paletteIndex >= colorCount) break
if (node.isLeaf) palette.push(node.color)
node.paletteIndex = paletteIndex
paletteIndex++
}
return palette
}
*makePaletteIncremental(colorCount) {
let palette = []
let paletteIndex = 0
let leafCount = this.leafNodes.length
for (let level = MAX_DEPTH - 1; level > -1; level -= 1) {
if (this.levels[level]) {
for (let node of this.levels[level]) {
leafCount -= node.removeLeaves()
if (leafCount <= colorCount) break
}
if (leafCount <= colorCount) break
this.levels[level] = []
}
yield
}
for (let node of this.leafNodes) {
if (paletteIndex >= colorCount) break
if (node.isLeaf) palette.push(node.color)
node.paletteIndex = paletteIndex
paletteIndex++
}
yield
return palette
}
get leafNodes() {
return this.root.leafNodes
}
addLevelNode(level, node) {
this.levels[level].push(node)
}
getPaletteIndex(color) {
return this.root.getPaletteIndex(color, 0)
}
}
class Node {
constructor(level, parent) {
this._color = new Color(0, 0, 0)
this.pixelCount = 0
this.paletteIndex = 0
this.children = []
this._debugColor
if (level < MAX_DEPTH - 1) parent.addLevelNode(level, this)
}
get isLeaf() {
return this.pixelCount > 0
}
get leafNodes() {
let leafNodes = []
for (let node of this.children) {
if (!node) continue
if (node.isLeaf) {
leafNodes.push(node)
} else {
leafNodes.push(...node.leafNodes)
}
}
return leafNodes
}
addColor(color, level, parent) {
if (level >= MAX_DEPTH) {
this._color.add(color)
this.pixelCount++
return
}
let index = getColorIndex(color, level)
if (!this.children[index]) {
this.children[index] = new Node(level, parent)
}
this.children[index].addColor(color, level + 1, parent)
}
getPaletteIndex(color, level) {
if (this.isLeaf) {
return this.paletteIndex
}
let index = getColorIndex(color, level)
if (this.children[index]) {
return this.children[index].getPaletteIndex(color, level + 1)
} else {
for (let node of this.children) {
if (node) {
return node.getPaletteIndex(color, level + 1)
}
}
}
}
removeLeaves() {
let result = 0
for (let node of this.children) {
if (!node) continue
this._color.add(node._color)
this.pixelCount += node.pixelCount
result++
}
this.children = []
return result - 1
}
get debugColor() {
if (this._debugColor) return this._debugColor
if (this.isLeaf) return this.color
let c = new Color()
let count = 0
function traverse(node) {
for (let child of node.children) {
if (child.isLeaf) {
c.add(child._color)
count++
} else {
traverse(child)
}
}
}
traverse(this)
return c.normalized(count)
}
get color() {
return this._color.normalized(this.pixelCount)
}
}
class Color {
constructor(red = 0, green = 0, blue = 0) {
this.red = red
this.green = green
this.blue = blue
}
clone() {
return new Color(this.red, this.green, this.blue)
}
get array() {
return [this.red, this.green, this.blue, this.red + this.green + this.blue]
}
toString() {
return [this.red, this.green, this.blue].join(',')
}
toCSS() {
return `rgb(${[this.red, this.green, this.blue].map(n => Math.floor(n)).join(',')})`
}
normalized(pixelCount) {
return new Color(this.red / pixelCount, this.green / pixelCount, this.blue / pixelCount)
}
add(color) {
this.red += color.red
this.green += color.green
this.blue += color.blue
}
}
function getColorIndex(color, level) {
let index = 0
let mask = 0b10000000 >> level
if (color.red & mask) index |= 0b100
if (color.green & mask) index |= 0b010
if (color.blue & mask) index |= 0b001
return index
}
module.exports = { OctreeQuant, Node, Color }
/***/ }),
/***/ 222:
/***/ ((module) => {
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*
* (JavaScript port 2012 by Johan Nordberg)
*/
var ncycles = 100 // number of learning cycles
var netsize = 256 // number of colors used
var maxnetpos = netsize - 1
// defs for freq and bias
var netbiasshift = 4 // bias for colour values
var intbiasshift = 16 // bias for fractions
var intbias = 1 << intbiasshift
var gammashift = 10
var gamma = 1 << gammashift
var betashift = 10
var beta = intbias >> betashift /* beta = 1/1024 */
var betagamma = intbias << (gammashift - betashift)
// defs for decreasing radius factor
var initrad = netsize >> 3 // for 256 cols, radius starts
var radiusbiasshift = 6 // at 32.0 biased by 6 bits
var radiusbias = 1 << radiusbiasshift
var initradius = initrad * radiusbias //and decreases by a
var radiusdec = 30 // factor of 1/30 each cycle
// defs for decreasing alpha factor
var alphabiasshift = 10 // alpha starts at 1.0
var initalpha = 1 << alphabiasshift
var alphadec // biased by 10 bits
/* radbias and alpharadbias used for radpower calculation */
var radbiasshift = 8
var radbias = 1 << radbiasshift
var alpharadbshift = alphabiasshift + radbiasshift
var alpharadbias = 1 << alpharadbshift
// four primes near 500 - assume no image has a length so large that it is
// divisible by all four primes
var prime1 = 499
var prime2 = 491
var prime3 = 487
var prime4 = 503
var minpicturebytes = 3 * prime4
/*
Constructor: NeuQuant
Arguments:
pixels - array of pixels in RGB format
samplefac - sampling factor 1 to 30 where lower is better quality
>
> pixels = [r, g, b, r, g, b, r, g, b, ..]
>
*/
function NeuQuant(pixels, samplefac) {
var network // int[netsize][4]
var netindex // for network lookup - really 256
// bias and freq arrays for learning
var bias
var freq
var radpower
/*
Private Method: init
sets up arrays
*/
function init() {
network = []
netindex = new Int32Array(256)
bias = new Int32Array(netsize)
freq = new Int32Array(netsize)
radpower = new Int32Array(netsize >> 3)
var i, v
for (i = 0; i < netsize; i++) {
v = (i << (netbiasshift + 8)) / netsize
network[i] = new Float64Array([v, v, v, 0])
//network[i] = [v, v, v, 0]
freq[i] = intbias / netsize
bias[i] = 0
}
}
/*
Private Method: unbiasnet
unbiases network to give byte values 0..255 and record position i to prepare for sort
*/
function unbiasnet() {
for (var i = 0; i < netsize; i++) {
network[i][0] >>= netbiasshift
network[i][1] >>= netbiasshift
network[i][2] >>= netbiasshift
network[i][3] = i // record color number
}
}
/*
Private Method: altersingle
moves neuron *i* towards biased (b,g,r) by factor *alpha*
*/
function altersingle(alpha, i, b, g, r) {
network[i][0] -= (alpha * (network[i][0] - b)) / initalpha
network[i][1] -= (alpha * (network[i][1] - g)) / initalpha
network[i][2] -= (alpha * (network[i][2] - r)) / initalpha
}
/*
Private Method: alterneigh
moves neurons in *radius* around index *i* towards biased (b,g,r) by factor *alpha*
*/
function alterneigh(radius, i, b, g, r) {
var lo = Math.abs(i - radius)
var hi = Math.min(i + radius, netsize)
var j = i + 1
var k = i - 1
var m = 1
var p, a
while (j < hi || k > lo) {
a = radpower[m++]
if (j < hi) {
p = network[j++]
p[0] -= (a * (p[0] - b)) / alpharadbias
p[1] -= (a * (p[1] - g)) / alpharadbias
p[2] -= (a * (p[2] - r)) / alpharadbias
}
if (k > lo) {
p = network[k--]
p[0] -= (a * (p[0] - b)) / alpharadbias
p[1] -= (a * (p[1] - g)) / alpharadbias
p[2] -= (a * (p[2] - r)) / alpharadbias
}
}
}
/*
Private Method: contest
searches for biased BGR values
*/
function contest(b, g, r) {
/*
finds closest neuron (min dist) and updates freq
finds best neuron (min dist-bias) and returns position
for frequently chosen neurons, freq[i] is high and bias[i] is negative
bias[i] = gamma * ((1 / netsize) - freq[i])
*/
var bestd = ~(1 << 31)
var bestbiasd = bestd
var bestpos = -1
var bestbiaspos = bestpos
var i, n, dist, biasdist, betafreq
for (i = 0; i < netsize; i++) {
n = network[i]
dist = Math.abs(n[0] - b) + Math.abs(n[1] - g) + Math.abs(n[2] - r)
if (dist < bestd) {
bestd = dist
bestpos = i
}
biasdist = dist - (bias[i] >> (intbiasshift - netbiasshift))
if (biasdist < bestbiasd) {
bestbiasd = biasdist
bestbiaspos = i
}
betafreq = freq[i] >> betashift
freq[i] -= betafreq
bias[i] += betafreq << gammashift
}
freq[bestpos] += beta
bias[bestpos] -= betagamma
return bestbiaspos
}
/*
Private Method: inxbuild
sorts network and builds netindex[0..255]
*/
function inxbuild() {
var i,
j,
p,
q,
smallpos,
smallval,
previouscol = 0,
startpos = 0
for (i = 0; i < netsize; i++) {
p = network[i]
smallpos = i
smallval = p[1] // index on g
// find smallest in i..netsize-1
for (j = i + 1; j < netsize; j++) {
q = network[j]
if (q[1] < smallval) {
// index on g
smallpos = j
smallval = q[1] // index on g
}
}
q = network[smallpos]
// swap p (i) and q (smallpos) entries
if (i != smallpos) {
j = q[0]
q[0] = p[0]
p[0] = j
j = q[1]
q[1] = p[1]
p[1] = j
j = q[2]
q[2] = p[2]
p[2] = j
j = q[3]
q[3] = p[3]
p[3] = j
}
// smallval entry is now in position i
if (smallval != previouscol) {
netindex[previouscol] = (startpos + i) >> 1
for (j = previouscol + 1; j < smallval; j++) netindex[j] = i
previouscol = smallval
startpos = i
}
}
netindex[previouscol] = (startpos + maxnetpos) >> 1
for (j = previouscol + 1; j < 256; j++) netindex[j] = maxnetpos // really 256
}
/*
Private Method: inxsearch
searches for BGR values 0..255 and returns a color index
*/
function inxsearch(b, g, r) {
var a, p, dist
var bestd = 1000 // biggest possible dist is 256*3
var best = -1
var i = netindex[g] // index on g
var j = i - 1 // start at netindex[g] and work outwards
while (i < netsize || j >= 0) {
if (i < netsize) {
p = network[i]
dist = p[1] - g // inx key
if (dist >= bestd) i = netsize
// stop iter
else {
i++
if (dist < 0) dist = -dist
a = p[0] - b
if (a < 0) a = -a
dist += a
if (dist < bestd) {
a = p[2] - r
if (a < 0) a = -a
dist += a
if (dist < bestd) {
bestd = dist
best = p[3]
}
}
}
}
if (j >= 0) {
p = network[j]
dist = g - p[1] // inx key - reverse dif
if (dist >= bestd) j = -1
// stop iter
else {
j--
if (dist < 0) dist = -dist
a = p[0] - b
if (a < 0) a = -a
dist += a
if (dist < bestd) {
a = p[2] - r
if (a < 0) a = -a
dist += a
if (dist < bestd) {
bestd = dist
best = p[3]
}
}
}
}
}
return best
}
/*
Private Method: learn
"Main Learning Loop"
*/
function learn() {
var i
var lengthcount = pixels.length
var alphadec = 30 + (samplefac - 1) / 3
var samplepixels = lengthcount / (3 * samplefac)
var delta = ~~(samplepixels / ncycles)
var alpha = initalpha
var radius = initradius
var rad = radius >> radiusbiasshift
if (rad <= 1) rad = 0
for (i = 0; i < rad; i++) radpower[i] = alpha * (((rad * rad - i * i) * radbias) / (rad * rad))
var step
if (lengthcount < minpicturebytes) {
samplefac = 1
step = 3
} else if (lengthcount % prime1 !== 0) {
step = 3 * prime1
} else if (lengthcount % prime2 !== 0) {
step = 3 * prime2
} else if (lengthcount % prime3 !== 0) {
step = 3 * prime3
} else {
step = 3 * prime4
}
var b, g, r, j
var pix = 0 // current pixel
i = 0
while (i < samplepixels) {
b = (pixels[pix] & 0xff) << netbiasshift
g = (pixels[pix + 1] & 0xff) << netbiasshift
r = (pixels[pix + 2] & 0xff) << netbiasshift
j = contest(b, g, r)
altersingle(alpha, j, b, g, r)
if (rad !== 0) alterneigh(rad, j, b, g, r) // alter neighbours
pix += step
if (pix >= lengthcount) pix -= lengthcount
i++
if (delta === 0) delta = 1
if (i % delta === 0) {
alpha -= alpha / alphadec
radius -= radius / radiusdec
rad = radius >> radiusbiasshift
if (rad <= 1) rad = 0
for (j = 0; j < rad; j++)
radpower[j] = alpha * (((rad * rad - j * j) * radbias) / (rad * rad))
}
}
}
/*
Method: buildColormap
1. initializes network
2. trains it
3. removes misconceptions
4. builds colorindex
*/
function buildColormap() {
init()
learn()
unbiasnet()
inxbuild()
}
this.buildColormap = buildColormap
/*
Method: getColormap
builds colormap from the index
returns array in the format:
>
> [r, g, b, r, g, b, r, g, b, ..]
>
*/
function getColormap() {
var map = []
var index = []
for (var i = 0; i < netsize; i++) index[network[i][3]] = i
var k = 0
for (var l = 0; l < netsize; l++) {
var j = index[l]
map[k++] = network[j][0]
map[k++] = network[j][1]
map[k++] = network[j][2]
}
return map
}
this.getColormap = getColormap
/*
Method: lookupRGB
looks for the closest *r*, *g*, *b* color in the map and
returns its index
*/
this.lookupRGB = inxsearch
}
module.exports = NeuQuant
/***/ }),
/***/ 2644:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/*!
* Tmp
*
* Copyright (c) 2011-2017 KARASZI Istvan <github@spam.raszi.hu>
*
* MIT Licensed
*/
/*
* Module dependencies.
*/
const fs = __webpack_require__(9896);
const os = __webpack_require__(857);
const path = __webpack_require__(6928);
const crypto = __webpack_require__(6982);
const _c = { fs: fs.constants, os: os.constants };
/*
* The working inner variables.
*/
const
// the random characters to choose from
RANDOM_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
TEMPLATE_PATTERN = /XXXXXX/,
DEFAULT_TRIES = 3,
CREATE_FLAGS = (_c.O_CREAT || _c.fs.O_CREAT) | (_c.O_EXCL || _c.fs.O_EXCL) | (_c.O_RDWR || _c.fs.O_RDWR),
// constants are off on the windows platform and will not match the actual errno codes
IS_WIN32 = os.platform() === 'win32',
EBADF = _c.EBADF || _c.os.errno.EBADF,
ENOENT = _c.ENOENT || _c.os.errno.ENOENT,
DIR_MODE = 0o700 /* 448 */,
FILE_MODE = 0o600 /* 384 */,
EXIT = 'exit',
// this will hold the objects need to be removed on exit
_removeObjects = [],
// API change in fs.rmdirSync leads to error when passing in a second parameter, e.g. the callback
FN_RMDIR_SYNC = fs.rmdirSync.bind(fs);
let
_gracefulCleanup = false;
/**
* Recursively remove a directory and its contents.
*
* @param {string} dirPath path of directory to remove
* @param {Function} callback
* @private
*/
function rimraf(dirPath, callback) {
return fs.rm(dirPath, { recursive: true }, callback);
}
/**
* Recursively remove a directory and its contents, synchronously.
*
* @param {string} dirPath path of directory to remove
* @private
*/
function FN_RIMRAF_SYNC(dirPath) {
return fs.rmSync(dirPath, { recursive: true });
}
/**
* Gets a temporary file name.
*
* @param {(Options|tmpNameCallback)} options options or callback
* @param {?tmpNameCallback} callback the callback function
*/
function tmpName(options, callback) {
const
args = _parseArguments(options, callback),
opts = args[0],
cb = args[1];
try {
_assertAndSanitizeOptions(opts);
} catch (err) {
return cb(err);
}
let tries = opts.tries;
(function _getUniqueName() {
try {
const name = _generateTmpName(opts);
// check whether the path exists then retry if needed
fs.stat(name, function (err) {
/* istanbul ignore else */
if (!err) {
/* istanbul ignore else */
if (tries-- > 0) return _getUniqueName();
return cb(new Error('Could not get a unique tmp filename, max tries reached ' + name));
}
cb(null, name);
});
} catch (err) {
cb(err);
}
}());
}
/**
* Synchronous version of tmpName.
*
* @param {Object} options
* @returns {string} the generated random name
* @throws {Error} if the options are invalid or could not generate a filename
*/
function tmpNameSync(options) {
const
args = _parseArguments(options),
opts = args[0];
_assertAndSanitizeOptions(opts);
let tries = opts.tries;
do {
const name = _generateTmpName(opts);
try {
fs.statSync(name);
} catch (e) {
return name;
}
} while (tries-- > 0);
throw new Error('Could not get a unique tmp filename, max tries reached');
}
/**
* Creates and opens a temporary file.
*
* @param {(Options|null|undefined|fileCallback)} options the config options or the callback function or null or undefined
* @param {?fileCallback} callback
*/
function file(options, callback) {
const
args = _parseArguments(options, callback),
opts = args[0],
cb = args[1];
// gets a temporary filename
tmpName(opts, function _tmpNameCreated(err, name) {
/* istanbul ignore else */
if (err) return cb(err);
// create and open the file
fs.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err, fd) {
/* istanbu ignore else */
if (err) return cb(err);
if (opts.discardDescriptor) {
return fs.close(fd, function _discardCallback(possibleErr) {
// the chance of getting an error on close here is rather low and might occur in the most edgiest cases only
return cb(possibleErr, name, undefined, _prepareTmpFileRemoveCallback(name, -1, opts, false));
});
} else {
// detachDescriptor passes the descriptor whereas discardDescriptor closes it, either way, we no longer care
// about the descriptor
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
cb(null, name, fd, _prepareTmpFileRemoveCallback(name, discardOrDetachDescriptor ? -1 : fd, opts, false));
}
});
});
}
/**
* Synchronous version of file.
*
* @param {Options} options
* @returns {FileSyncObject} object consists of name, fd and removeCallback
* @throws {Error} if cannot create a file
*/
function fileSync(options) {
const
args = _parseArguments(options),
opts = args[0];
const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
const name = tmpNameSync(opts);
var fd = fs.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
/* istanbul ignore else */
if (opts.discardDescriptor) {
fs.closeSync(fd);
fd = undefined;
}
return {
name: name,
fd: fd,
removeCallback: _prepareTmpFileRemoveCallback(name, discardOrDetachDescriptor ? -1 : fd, opts, true)
};
}
/**
* Creates a temporary directory.
*
* @param {(Options|dirCallback)} options the options or the callback function
* @param {?dirCallback} callback
*/
function dir(options, callback) {
const
args = _parseArguments(options, callback),
opts = args[0],
cb = args[1];
// gets a temporary filename
tmpName(opts, function _tmpNameCreated(err, name) {
/* istanbul ignore else */
if (err) return cb(err);
// create the directory
fs.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err) {
/* istanbul ignore else */
if (err) return cb(err);
cb(null, name, _prepareTmpDirRemoveCallback(name, opts, false));
});
});
}
/**
* Synchronous version of dir.
*
* @param {Options} options
* @returns {DirSyncObject} object consists of name and removeCallback
* @throws {Error} if it cannot create a directory
*/
function dirSync(options) {
const
args = _parseArguments(options),
opts = args[0];
const name = tmpNameSync(opts);
fs.mkdirSync(name, opts.mode || DIR_MODE);
return {
name: name,
removeCallback: _prepareTmpDirRemoveCallback(name, opts, true)
};
}
/**
* Removes files asynchronously.
*
* @param {Object} fdPath
* @param {Function} next
* @private
*/
function _removeFileAsync(fdPath, next) {
const _handler = function (err) {
if (err && !_isENOENT(err)) {
// reraise any unanticipated error
return next(err);
}
next();
};
if (0 <= fdPath[0])
fs.close(fdPath[0], function () {
fs.unlink(fdPath[1], _handler);
});
else fs.unlink(fdPath[1], _handler);
}
/**
* Removes files synchronously.
*
* @param {Object} fdPath
* @private
*/
function _removeFileSync(fdPath) {
let rethrownException = null;
try {
if (0 <= fdPath[0]) fs.closeSync(fdPath[0]);
} catch (e) {
// reraise any unanticipated error
if (!_isEBADF(e) && !_isENOENT(e)) throw e;
} finally {
try {
fs.unlinkSync(fdPath[1]);
}
catch (e) {
// reraise any unanticipated error
if (!_isENOENT(e)) rethrownException = e;
}
}
if (rethrownException !== null) {
throw rethrownException;
}
}
/**
* Prepares the callback for removal of the temporary file.
*
* Returns either a sync callback or a async callback depending on whether
* fileSync or file was called, which is expressed by the sync parameter.
*
* @param {string} name the path of the file
* @param {number} fd file descriptor
* @param {Object} opts
* @param {boolean} sync
* @returns {fileCallback | fileCallbackSync}
* @private
*/
function _prepareTmpFileRemoveCallback(name, fd, opts, sync) {
const removeCallbackSync = _prepareRemoveCallback(_removeFileSync, [fd, name], sync);
const removeCallback = _prepareRemoveCallback(_removeFileAsync, [fd, name], sync, removeCallbackSync);
if (!opts.keep) _removeObjects.unshift(removeCallbackSync);
return sync ? removeCallbackSync : removeCallback;
}
/**
* Prepares the callback for removal of the temporary directory.
*
* Returns either a sync callback or a async callback depending on whether
* tmpFileSync or tmpFile was called, which is expressed by the sync parameter.
*
* @param {string} name
* @param {Object} opts
* @param {boolean} sync
* @returns {Function} the callback
* @private
*/
function _prepareTmpDirRemoveCallback(name, opts, sync) {
const removeFunction = opts.unsafeCleanup ? rimraf : fs.rmdir.bind(fs);
const removeFunctionSync = opts.unsafeCleanup ? FN_RIMRAF_SYNC : FN_RMDIR_SYNC;
const removeCallbackSync = _prepareRemoveCallback(removeFunctionSync, name, sync);
const removeCallback = _prepareRemoveCallback(removeFunction, name, sync, removeCallbackSync);
if (!opts.keep) _removeObjects.unshift(removeCallbackSync);
return sync ? removeCallbackSync : removeCallback;
}
/**
* Creates a guarded function wrapping the removeFunction call.
*
* The cleanup callback is save to be called multiple times.
* Subsequent invocations will be ignored.
*
* @param {Function} removeFunction
* @param {string} fileOrDirName
* @param {boolean} sync
* @param {cleanupCallbackSync?} cleanupCallbackSync
* @returns {cleanupCallback | cleanupCallbackSync}
* @private
*/
function _prepareRemoveCallback(removeFunction, fileOrDirName, sync, cleanupCallbackSync) {
let called = false;
// if sync is true, the next parameter will be ignored
return function _cleanupCallback(next) {
/* istanbul ignore else */
if (!called) {
// remove cleanupCallback from cache
const toRemove = cleanupCallbackSync || _cleanupCallback;
const index = _removeObjects.indexOf(toRemove);
/* istanbul ignore else */
if (index >= 0) _removeObjects.splice(index, 1);
called = true;
if (sync || removeFunction === FN_RMDIR_SYNC || removeFunction === FN_RIMRAF_SYNC) {
return removeFunction(fileOrDirName);
} else {
return removeFunction(fileOrDirName, next || function() {});
}
}
};
}
/**
* The garbage collector.
*
* @private
*/
function _garbageCollector() {
/* istanbul ignore else */
if (!_gracefulCleanup) return;
// the function being called removes itself from _removeObjects,
// loop until _removeObjects is empty
while (_removeObjects.length) {
try {
_removeObjects[0]();
} catch (e) {
// already removed?
}
}
}
/**
* Random name generator based on crypto.
* Adapted from http://blog.tompawlak.org/how-to-generate-random-values-nodejs-javascript
*
* @param {number} howMany
* @returns {string} the generated random name
* @private
*/
function _randomChars(howMany) {
let
value = [],
rnd = null;
// make sure that we do not fail because we ran out of entropy
try {
rnd = crypto.randomBytes(howMany);
} catch (e) {
rnd = crypto.pseudoRandomBytes(howMany);
}
for (var i = 0; i < howMany; i++) {
value.push(RANDOM_CHARS[rnd[i] % RANDOM_CHARS.length]);
}
return value.join('');
}
/**
* Helper which determines whether a string s is blank, that is undefined, or empty or null.
*
* @private
* @param {string} s
* @returns {Boolean} true whether the string s is blank, false otherwise
*/
function _isBlank(s) {
return s === null || _isUndefined(s) || !s.trim();
}
/**
* Checks whether the `obj` parameter is defined or not.
*
* @param {Object} obj
* @returns {boolean} true if the object is undefined
* @private
*/
function _isUndefined(obj) {
return typeof obj === 'undefined';
}
/**
* Parses the function arguments.
*
* This function helps to have optional arguments.
*
* @param {(Options|null|undefined|Function)} options
* @param {?Function} callback
* @returns {Array} parsed arguments
* @private
*/
function _parseArguments(options, callback) {
/* istanbul ignore else */
if (typeof options === 'function') {
return [{}, options];
}
/* istanbul ignore else */
if (_isUndefined(options)) {
return [{}, callback];
}
// copy options so we do not leak the changes we make internally
const actualOptions = {};
for (const key of Object.getOwnPropertyNames(options)) {
actualOptions[key] = options[key];
}
return [actualOptions, callback];
}
/**
* Generates a new temporary name.
*
* @param {Object} opts
* @returns {string} the new random name according to opts
* @private
*/
function _generateTmpName(opts) {
const tmpDir = opts.tmpdir;
/* istanbul ignore else */
if (!_isUndefined(opts.name))
return path.join(tmpDir, opts.dir, opts.name);
/* istanbul ignore else */
if (!_isUndefined(opts.template))
return path.join(tmpDir, opts.dir, opts.template).replace(TEMPLATE_PATTERN, _randomChars(6));
// prefix and postfix
const name = [
opts.prefix ? opts.prefix : 'tmp',
'-',
process.pid,
'-',
_randomChars(12),
opts.postfix ? '-' + opts.postfix : ''
].join('');
return path.join(tmpDir, opts.dir, name);
}
/**
* Asserts whether the specified options are valid, also sanitizes options and provides sane defaults for missing
* options.
*
* @param {Options} options
* @private
*/
function _assertAndSanitizeOptions(options) {
options.tmpdir = _getTmpDir(options);
const tmpDir = options.tmpdir;
/* istanbul ignore else */
if (!_isUndefined(options.name))
_assertIsRelative(options.name, 'name', tmpDir);
/* istanbul ignore else */
if (!_isUndefined(options.dir))
_assertIsRelative(options.dir, 'dir', tmpDir);
/* istanbul ignore else */
if (!_isUndefined(options.template)) {
_assertIsRelative(options.template, 'template', tmpDir);
if (!options.template.match(TEMPLATE_PATTERN))
throw new Error(`Invalid template, found "${options.template}".`);
}
/* istanbul ignore else */
if (!_isUndefined(options.tries) && isNaN(options.tries) || options.tries < 0)
throw new Error(`Invalid tries, found "${options.tries}".`);
// if a name was specified we will try once
options.tries = _isUndefined(options.name) ? options.tries || DEFAULT_TRIES : 1;
options.keep = !!options.keep;
options.detachDescriptor = !!options.detachDescriptor;
options.discardDescriptor = !!options.discardDescriptor;
options.unsafeCleanup = !!options.unsafeCleanup;
// sanitize dir, also keep (multiple) blanks if the user, purportedly sane, requests us to
options.dir = _isUndefined(options.dir) ? '' : path.relative(tmpDir, _resolvePath(options.dir, tmpDir));
options.template = _isUndefined(options.template) ? undefined : path.relative(tmpDir, _resolvePath(options.template, tmpDir));
// sanitize further if template is relative to options.dir
options.template = _isBlank(options.template) ? undefined : path.relative(options.dir, options.template);
// for completeness' sake only, also keep (multiple) blanks if the user, purportedly sane, requests us to
options.name = _isUndefined(options.name) ? undefined : options.name;
options.prefix = _isUndefined(options.prefix) ? '' : options.prefix;
options.postfix = _isUndefined(options.postfix) ? '' : options.postfix;
}
/**
* Resolve the specified path name in respect to tmpDir.
*
* The specified name might include relative path components, e.g. ../
* so we need to resolve in order to be sure that is is located inside tmpDir
*
* @param name
* @param tmpDir
* @returns {string}
* @private
*/
function _resolvePath(name, tmpDir) {
if (name.startsWith(tmpDir)) {
return path.resolve(name);
} else {
return path.resolve(path.join(tmpDir, name));
}
}
/**
* Asserts whether specified name is relative to the specified tmpDir.
*
* @param {string} name
* @param {string} option
* @param {string} tmpDir
* @throws {Error}
* @private
*/
function _assertIsRelative(name, option, tmpDir) {
if (option === 'name') {
// assert that name is not absolute and does not contain a path
if (path.isAbsolute(name))
throw new Error(`${option} option must not contain an absolute path, found "${name}".`);
// must not fail on valid .<name> or ..<name> or similar such constructs
let basename = path.basename(name);
if (basename === '..' || basename === '.' || basename !== name)
throw new Error(`${option} option must not contain a path, found "${name}".`);
}
else { // if (option === 'dir' || option === 'template') {
// assert that dir or template are relative to tmpDir
if (path.isAbsolute(name) && !name.startsWith(tmpDir)) {
throw new Error(`${option} option must be relative to "${tmpDir}", found "${name}".`);
}
let resolvedPath = _resolvePath(name, tmpDir);
if (!resolvedPath.startsWith(tmpDir))
throw new Error(`${option} option must be relative to "${tmpDir}", found "${resolvedPath}".`);
}
}
/**
* Helper for testing against EBADF to compensate changes made to Node 7.x under Windows.
*
* @private
*/
function _isEBADF(error) {
return _isExpectedError(error, -EBADF, 'EBADF');
}
/**
* Helper for testing against ENOENT to compensate changes made to Node 7.x under Windows.
*
* @private
*/
function _isENOENT(error) {
return _isExpectedError(error, -ENOENT, 'ENOENT');
}
/**
* Helper to determine whether the expected error code matches the actual code and errno,
* which will differ between the supported node versions.
*
* - Node >= 7.0:
* error.code {string}
* error.errno {number} any numerical value will be negated
*
* CAVEAT
*
* On windows, the errno for EBADF is -4083 but os.constants.errno.EBADF is different and we must assume that ENOENT
* is no different here.
*
* @param {SystemError} error
* @param {number} errno
* @param {string} code
* @private
*/
function _isExpectedError(error, errno, code) {
return IS_WIN32 ? error.code === code : error.code === code && error.errno === errno;
}
/**
* Sets the graceful cleanup.
*
* If graceful cleanup is set, tmp will remove all controlled temporary objects on process exit, otherwise the
* temporary objects will remain in place, waiting to be cleaned up on system restart or otherwise scheduled temporary
* object removals.
*/
function setGracefulCleanup() {
_gracefulCleanup = true;
}
/**
* Returns the currently configured tmp dir from os.tmpdir().
*
* @private
* @param {?Options} options
* @returns {string} the currently configured tmp dir
*/
function _getTmpDir(options) {
return path.resolve(options && options.tmpdir || os.tmpdir());
}
// Install process exit listener
process.addListener(EXIT, _garbageCollector);
/**
* Configuration options.
*
* @typedef {Object} Options
* @property {?boolean} keep the temporary object (file or dir) will not be garbage collected
* @property {?number} tries the number of tries before give up the name generation
* @property (?int) mode the access mode, defaults are 0o700 for directories and 0o600 for files
* @property {?string} template the "mkstemp" like filename template
* @property {?string} name fixed name relative to tmpdir or the specified dir option
* @property {?string} dir tmp directory relative to the root tmp directory in use
* @property {?string} prefix prefix for the generated name
* @property {?string} postfix postfix for the generated name
* @property {?string} tmpdir the root tmp directory which overrides the os tmpdir
* @property {?boolean} unsafeCleanup recursively removes the created temporary directory, even when it's not empty
* @property {?boolean} detachDescriptor detaches the file descriptor, caller is responsible for closing the file, tmp will no longer try closing the file during garbage collection
* @property {?boolean} discardDescriptor discards the file descriptor (closes file, fd is -1), tmp will no longer try closing the file during garbage collection
*/
/**
* @typedef {Object} FileSyncObject
* @property {string} name the name of the file
* @property {string} fd the file descriptor or -1 if the fd has been discarded
* @property {fileCallback} removeCallback the callback function to remove the file
*/
/**
* @typedef {Object} DirSyncObject
* @property {string} name the name of the directory
* @property {fileCallback} removeCallback the callback function to remove the directory
*/
/**
* @callback tmpNameCallback
* @param {?Error} err the error object if anything goes wrong
* @param {string} name the temporary file name
*/
/**
* @callback fileCallback
* @param {?Error} err the error object if anything goes wrong
* @param {string} name the temporary file name
* @param {number} fd the file descriptor or -1 if the fd had been discarded
* @param {cleanupCallback} fn the cleanup callback function
*/
/**
* @callback fileCallbackSync
* @param {?Error} err the error object if anything goes wrong
* @param {string} name the temporary file name
* @param {number} fd the file descriptor or -1 if the fd had been discarded
* @param {cleanupCallbackSync} fn the cleanup callback function
*/
/**
* @callback dirCallback
* @param {?Error} err the error object if anything goes wrong
* @param {string} name the temporary file name
* @param {cleanupCallback} fn the cleanup callback function
*/
/**
* @callback dirCallbackSync
* @param {?Error} err the error object if anything goes wrong
* @param {string} name the temporary file name
* @param {cleanupCallbackSync} fn the cleanup callback function
*/
/**
* Removes the temporary created file or directory.
*
* @callback cleanupCallback
* @param {simpleCallback} [next] function to call whenever the tmp object needs to be removed
*/
/**
* Removes the temporary created file or directory.
*
* @callback cleanupCallbackSync
*/
/**
* Callback function for function composition.
* @see {@link https://github.com/raszi/node-tmp/issues/57|raszi/node-tmp#57}
*
* @callback simpleCallback
*/
// exporting all the needed methods
// evaluate _getTmpDir() lazily, mainly for simplifying testing but it also will
// allow users to reconfigure the temporary directory
Object.defineProperty(module.exports, "tmpdir", ({
enumerable: true,
configurable: false,
get: function () {
return _getTmpDir();
}
}));
module.exports.dir = dir;
module.exports.dirSync = dirSync;
module.exports.file = file;
module.exports.fileSync = fileSync;
module.exports.tmpName = tmpName;
module.exports.tmpNameSync = tmpNameSync;
module.exports.setGracefulCleanup = setGracefulCleanup;
/***/ })
};
;