Skip to main content

Crackle 3D dense segmentation compression codec.

Project description

PyPI version

Crackle: Next gen. 3D segmentation compression codec.

# Command Line Interface
crackle data.npy # creates data.ckl
crackle -m 5 data.npy # use a 5th order context model
crackle -p data.npy # use pin encoding for labels
crackle -p -m 5 data.npy # use pins and markov model
crackle -d data.ckl # recovers data.npy
crackle -m 0 data.ckl # change markov model order
crackle -t data.ckl # check for file corruption
import crackle
import numpy

labels = np.load("example.npy") # a 2D or 3D dense segmentation

binary = crackle.compress(labels, allow_pins=False, markov_model_order=0)
labels = crackle.decompress(binary, parallel=0) # use all cores (default)

# faster extraction of binary images
binary_image = crackle.decompress(binary, label=1241)

# get unique labels without decompressing
uniq = crackle.labels(binary) 
# get num labels without decompressing
N = crackle.num_labels(binary) 
# get min and max without decompressing
mn = crackle.min(binary)
mx = crackle.max(binary)
# check if label in array in log(N) time
has_label = crackle.contains(binary, label)
# extract a range of labels in something like log(N) time
labels = crackle.contains_range(binary, low, high)

# iterate over all binary images rapidly. crop
# close crops to the ROI and makes iteration a bit faster
for label, binimg in crackle.each(binary, crop=True):
  pass

# iterate over 255 labels at a time. Useful if your downstream
# processing supports multilabel images but you need an 8x reduction
# in memory usage compared to a uint64 image. Much faster than binary
# image iteration. img is reused for 255 iterations before being replaced.
for label, tmp_label, img in crackle.each(binary, multi=True):
  pass

# Remap labels without decompressing. Could
# be useful for e.g. proofreading.
remapped = crackle.remap(
  binary, { 1: 2, 2: 3, ... },
  preserve_missing_labels=True
)

# change dtype to smallest possible w/o precision loss
remapped = crackle.refit(binary)
# renumber array and change dtype to smallest possible
remapped = crackle.renumber(binary, start=0)

is_equal = crackle.array_equal(binary1, binary2)
arr == arr2 # syntactic sugar for CrackleArrays
arr.array_equal(arr2) # method call for CrackleArrays

# for working with files
# if .gz is appended to the filename, the file will be
# automatically gzipped (or ungzipped)
crackle.save(labels, "example.ckl.gz")
labels = crackle.load("example.ckl.gz")

# Save a crackle array as a numpy array
# in a memory efficient manner.
crackle.save(binary, "example.npy.gz")

arr = crackle.CrackleArray(binary, parallel=0) # 0 means use all cores (default)
res = arr[:10,:10,:10] # array slicing (efficient z ranges)
arr[:,:,30] = 20 # write to a crackle array (whole z slices write faster)
20 in arr # log(N) check
arr = arr.numpy() # convert to a numpy array

# low memory extraction of point clouds
ptc = crackle.point_cloud(binary) # { label: np.ndarray, ... }
ptc = crackle.point_cloud(binary, label=777)
ptc = crackle.point_cloud(binary) 

# rapid and low memory
voxel_counts = crackle.voxel_counts(binary)
centroids = crackle.centroids(binary)
bbxes = crackle.bounding_boxes(binary)

# extract the 4-way or 6-way voxel connectivity graph
# note: 4-way is stored in the format so is extremely fast
vcg = crackle.voxel_connectivity_graph(binary, connectivity=6)

# surface area for 6-connected region contacts
contacts = crackle.contacts(binary, anisotropy=(32,32,40))

# low memory CCL, the more memory you provide, the faster it goes
ccl_binary = crackle.connected_components(
  binary, 
  connectivity=26, # 6 (faces) & 26 (faces,edges,corners) supported
  memory_target=int(1e9), # bytes
  progress=True,
  return_mapping = False, # can also return { cc label: original label }
)

# building big arrays with low memory
binary = crackle.zeros([5000,5000,5000], dtype=np.uint64, order='F')

part1 = np.zeros([1000, 1000, 1000], dtype=np.uint32)
part2 = crackle.ones([1000, 1000, 1000], dtype=np.uint32)

binary = crackle.asfortranarray(binary)
binary = crackle.ascontiguousarray(binary)

# creates a crackle binary with part1 stacked atop part2
# in the z dimension. x and y dimensions must match
# without needing to decompress anything.
binary = crackle.zstack([ part1, part2 ])

# splits a crackle binary into before, middle (single slice),
# and after sections without decompressing.
before, middle, after = crackle.zsplit(binary, z=742)

# splits binary into individual z slices
sections = crackle.zshatter(binary)

This repository is currently Beta. It works and the format is reasonably fixed. There may be some improvements down the line (such as 3d compression of crack codes, 2d chunking), but they will be a new format version number if necessary to retain backwards compatibility.

Crackle is a compression codec for 3D dense segmentation (labeled) images. The algorithm accepts both signed and unsigned integer labels (though the implementation currently has some restrictions on signed integers). It is written in C++ and has Python bindings. Crackle uses a two pass compression strategy where the output of crackle may be further comrpessed with a bitstream compressor like gzip, bzip2, zstd, or lzma. However, if the Crackle binary, which is already small, is not further compressed, it supports several efficient operations:

  • Query if a label exists in the image
  • Extract unique labels
  • Remap labels
  • Decode by Z-Range

Crackle is inspired by Compresso [1]. Compresso innovated by separating labels from boundary structures. There were conceptually four (but really five) elements in the format: header, labels, bit packed and RLE encoded binary image boundaries, and indeterminate boundary locations.

Crackle improves upon Compresso by replacing the bit-packed boundary map with a "crack code" and can also use 3D information to reduce redundancy in labels using "pins".

See benchmarks for more information on Crackle's size and compute effiency.

Optional Performance Enhancing Sidecar .ckl.meta.parquet File

Counting voxels or measuring bounding boxes is fully supported by the bare crackle file, but requires computation which on large images or numerous images can become substantial. Therefore, crackle comes with a facility for generating a .parquet file containing this metadata information for faster retrieval. Currently, to avoid engineering complexity, crackle does not make use of this file, so use pyarrow, duckdb, or similar to read it. This extra file adds nothing except performance enhancement for some use cases. All data can be generated from the crackle file alone, and nothing is lost if the sidecar file is lost.

You will need pyarrow installed to generate this file: pip install pyarrow

crackle -M myfile.ckl # generates myfile.ckl.meta.parquet
import crackle

arr = crackle.aload("myfile.ckl")
arr.cache_meta("myfile.ckl.meta.parquet") # generate the sidecar file

You can then read the parquet files using your favorite parquet reader. Sometimes it is faster to use crackle methods on single files, but when tested on hundreds of thousands of files, reading voxel counts out of parquet was 100x faster (20 files per second versus 2000 on a Macbook M3).

Parquet Schema

Bbox type is uint16 unless the xy dimensions of the crackle file exceed 16-bits (65,535) in which case it is uint32.

label: uint64
voxel_count: uint32
min_x: uint16 or uint32
max_x: uint16 or uint32
min_y: uint16 or uint32
max_y: uint16 or uint32
# if it's a 3d crackle file
min_z: uint16 or uint32
max_z: uint16 or uint32

Reading Example

import pyarrow.parquet as pq
table = pq.read_table("myfile.ckl.meta.parquet")
print(table)

Installation

pip install crackle-codec 

Building from source (requires cmake and a c++ compiler):

git clone https://github.com/seung-lab/crackle.git
cd crackle
git submodule update --init --recursive # fetches google/crc32c library
python setup.py develop

Versions

Format Version Description
0 Initial release w/ flat, pins, crack codes with finite context modeling. Beta.
1 Incr. header to 29 bytes from 24. num_label_bytes u32->u64, adds crcs to protect stream components.

Stream Format

Section Bytes Description
Header v0: 24, v1: 29 Metadata incl. length of fields.
Crack Index header.sz * sizeof(uint32), v1: +4 Number of bytes for the crack codes in each slice + CRC32c(le)
Labels header.num_label_bytes Can be either "flat" labels or "pins". Describes how to color connected components.
Crack Codes Variable length. Instructions for drawing crack boundaries.
Labels crc32c (v1 only) 4(le) v0: n/a, v1: crc32c of the labels binary.
Crack crc32c (v1 only) header.sz * 4(le) v0: n/a, v1: crc32c of the uncompressed uint32_t fortran order connected component labeling of each z-slice.

A Note on CRCs

CRCs protect each step of the decoding process. The fixed width header is protected by crc8, which contains information for decoding the crack index. The crack index is in turn protected by a crc32c. This is not overkill because a very large volume or a volume that is randomly accessible in XY as well as Z would need a crc32 vs a crc16.

The crack index is used for decoding the structural information (the connected components for each slice). We store a crc32c for each z-slice. This allows random z access to be validated while balancing against the storage cost of creating too many crc (e.g. vs. once per a grid).

We also store a crc32c for the labels binary independently of the crack codes.

All crcs are stored little endian.

Why not store a single crc for the entire uncompressed image? This would make it difficult to validate as a single crackle file could represent many terabytes of data. It would also make it difficult to edit the labels (remap) independently of the structure. Storing a crc32c per a z-slice also allows for z-stacking independent slices without recalculating crcs.

The downside to this strategy is a small increase in the file size and an increase in false positives for crc32s. This is the price of having the format be more of a random-access array format than a bitstream format. However, as crackle is designed to be two stage compressed, for example, with lzip, an LZMA variant with error correction properties, these issues are mitigated when archived.

crc8 (0xe7, initialized with 0xFF) was selected due to its ability to reliably detect two bit flips in up to 247 bits of message data, the best available for our header length.

crc32c was selected as the polynomial due to the availability of high performance implementations. This is important to avoid CRC calculation being a significant cost to the codec.

Error Detection and (Limited, Human Assisted) Correction

Due to this mutli-crc strategy, it is possible to narrow down corruptions to the section of the binary where they occur. For example, if you are concerned with only z=1-100 and the error occurs at z=200, you're ok. If the error occurs in the labels_binary, but you were planning on applying a full new mapping anyway, you can get away with discarding the extant labeling. Certain bit flips in the labels binary will create out of range keys, which will aid in identifying exactly where the error occured. Headers can be repaired potentially be human inspection (if they know the dataset).

Header

Attribute Value Type Description
magic crkl char[4] File magic number.
format_version 0 or 1 u8 Stream version.
format_field bitfield u16 See below.
sx, sy, sz >= 0 u32 x 3 Size of array dimensions.
grid_size log2(grid_size) u8 Stores log2 of grid dimensions in voxels.
num_label_bytes Any. u64 Number of bytes of the labels section. Note the labels come in at least two format types.
crc8 Any. u8 CRC8 of format_field thru num_label_bytes using polynomial 0xe7 (implicit) and 0xFF initialization.

Format Field (u16): DDSSCLLFGOOOOURR (each letter represents a bit, left is LSB)

DD: 2^(DD) = byte width of returned array (1,2,4,8 bytes)
SS: 2^(SS) = byte width of stored labels (sometimes you can store values in 2 bytes when the final array is 8 bytes)
C: 1: crack codes denote impermissible boundaries 0: they denote permissible boundaries.
LL: 0: "flat" label format, 1: fixed width pins (unused?) 2: variable width pins 3: reserved
F: whether the array is to be rendered as C (0) or F (1) order
G: Signed (if (1), data are signed int, otherwise unsigned int)
OOOO: Nth-Order of Markov Chain (as an unsigned integer, typical values 0, or 3 to 7). If 0, markov compression is disabled.
U: if 0, unique labels are sorted, else, unsorted
R: Reserved

CRC8 only covers the header. It doesn't cover the magic number or format version since those are easily human correctable if needed.

Flat Label Format

Attribute Type Description
num_unique u64 Number of unique labels in this volume.
unique_labels stored_type[num_unique] Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them.
cc_per_grid smallest_type(sx * sy)[sz] Array containing the number of CCL IDs in each grid (usually a z-slice).
cc_to_labels smallest_type(num_labels)[sum(cc_per_grid)] Array mapping CCL IDs to their proper value by indexing the unique labels array.

Flat labels are random access read, allow efficient reading of unique labels, efficient remapping, and efficient search for a given label's existence. Since the connected component labels can often use a smaller byte width than the unique values, even noise arrays can see some value from compression.

Encoding flat labels is fast.

Condensed (Variable Width) Pins Label Format

Attribute Type Description
background_color stored_data_width Background color of image.
num_unique u64 Number of unique labels in this volume.
unique_labels stored_type[num_unique] Sorted ascending array of all unique values in image, stored in the smallest data type that will hold them.
cc_per_grid smallest_type(sx * sy)[sz] Array containing the number of CCL IDs in each grid (usually a z-slice).
fmt_byte u8 00CCDDNN DD: 2^(DD) is the depth width NN: 2^(NN) is the num pins width, CC: 2^(CC) is the single components width.
pin_section Bitstream to end of labels section. Contains pin information.

PIN SECTION: | PINS FOR LABEL 0 | PINS FOR LABEL 1 | ... | PINS FOR LABEL N |

PINS: | num_pins | INDEX_0 | INDEX_1 | ... | INDEX_N | DEPTH_0 | DEPTH_1 | ... | DEPTH_N | num_single_labels | CC 0 | CC 1 | ... | CC N |

Both num_pins and num_single_labels use the num_pins_width.

Note that INDEX_0 to INDEX_N are stored with a difference filter applied to improve compressibility.

A pin (color, position, depth) is a line segment that joins together multiple connected component IDs and labels them with a color (an index into UNIQUE LABELS) in order to use 3D information to compress the labels as compared with the flat label format. Pins are slow to compute but fast to decode, however random access is lost (a full scan of the labels section is needed to decode a subset of crack codes). The most frequent pin is replaced with a background color. Like with flat, efficient reading of unique labels, efficient remapping, and search are supported.

Depending on the image statistics and quality of the pin solver, pins can be much smaller than flat or larger (some heuristics are used to avoid this case). An excellent example of where pins do well is a binary image where remarkable savings can be achieved in the labels section (though overall it is probably a small part of the file).

For very short pins (e.g. depth 0 or 1) that take more bytes to record than simply listing the corresponding CC label, we list the CC label instead. This calculation is made depending on the dimensions of the image and the max pin depth, and the byte width of the CCL labels.

Example calculation. For a 512 x 512 x 32 file with an average of 1000 CCL's per a slice and a maximum pin depth of 30, a pin takes 4 index + 1 depth = 5 bytes while a CCL takes 2 bytes. Therefore, depth 1 and 2 pins can be efficiently replaced with 1 and 2 CCL labels for a 60% and 20% savings respectively. CCLs are also difference coded to enhance second stage compressibility.

Fixed Width Pins (disabled)

| BACKGROUND COLOR (STORED_DATA_WIDTH) | NUM_LABELS (u64) | UNIQUE LABELS (NUM_LABELS \* STORED_DATA_WIDTH) | PIN SECTION |

PIN SECTION: |PIN0|PIN1|PIN2|...|PINN| PIN: |LABEL|INDEX|DEPTH|

A fixed width variant of pins has also been developed but is not enabled. It frequently is not significantly smaller than flat outside of special circumstances such as a binary image. An advantage this format would have over condensed is that the pins can be sorted and searched rapidly by index, which reduces the amount of reading one might have to do on an mmapped file. Please raise an issue if this seems like something that might be useful to you.

Crack Code Format

CRACK CODE: MARKOV MODEL | CHAIN 0 | CHAIN 1 | ... | CHAIN N |

CHAIN: | BEGINNING OF CHAIN INDEX (sizeof(sx * sy)) | BIT PACKED MOVES (2 bits each) |

MARKOV MODEL (if enabled): priority order of moves UDLR packed per a byte. 4^order bytes.

The BEGINNING OF CHAIN INDEX (BOC) locates the grid vertex where the crack code will begin. Vertices are the corners of the pixel grid, with 0 at the top left and sx*sy-1 at the bottom right (fortran order).

The crack code is a NEWS code (up,right,left,down). Impossible combinations of directions are used to signal branching and branch termination. The next chain begins in the next byte when a termination signal causes the current branch count to reach zero.

There may be ways to further improve the design of the crack code. For example, by applying a difference filter a few more percent compression under gzip can be obtained. In the literature, there are other shorter codes such as a left,right,straight (LRS) code and fancy large context compressors that can achieve fewer than one bit per a move.

Boundary Structure: Crack Code

Our different approach is partially inspired by the work of Zingaretti et al. [2]. We represent the boundary not by border voxels, but by a "crack code" that represents the edges between voxels. This code can be thought of as directions to draw edges on a graph where the vertices are where the corners of four pixels touch and the edges are the cracks in between them.

Since this regular graph is 4-connected, each "move" in a cardinal direction can be described using two bits. To represent special symbols such as "branch" and "terminate", an impossible set of instructions on an undirected graph such as "left-right" or "up-down" can be used (occupying 4 bits). In order to avoid creating palendromic sequences such as (3, 0, 3) meaning (down, branch) but can be read (terminate, down), we can use the left-right impossible directions to rewrite it as (3, 2, 1).

While the image is 3D, we treat the image in layers because working in 3D introduces a large increase in geometric complexity (a cube has 6 faces, 12 edges, and 8 corners while a square has 4 edges and 4 corners). This increase in complexity would inflate the size of the crack code and make the implementation more difficult.

Label Map: Method of Pins

Each 2D CCL region must has a label assigned. Due to the 2D nature of the crack code, we cannot use 3D CCL. However, for example, a solid cube of height 100 would need 100 labels to represent the same color on every slice as in Compresso.

It is still possible to reduce the amount of redundant information even without 3D CCL. For each label, we find a set of vertical line segments ("pins") that fully cover the label's 2D CCL regions. Sharp readers may note that this is the NP-hard set cover problem.

Once a reasonably small or minimal set of pins are found, they can be encoded in two forms:

Condensed Form: [label][num_pins][pin_1][pin_2]...[pin_N] Fixed Width Form: [label][pin_1][label][pin_2]...[label][pin_N] Pin Format: [linear index of pin top][number of voxels to bottom]

Fixed width example with label 1 with a pin between (1,1,1) and (1,1,5) on a 10x10x10 image: [1][111][4]

An alternative formulation [label][idx1][idx2] was shown in an experiment on connectomics.npy.cpso to compress slightly worse than Compresso labels. However, this alternative formulation theoretically allows arbitrary pin orientations and so might be useful for reducing the overall number of pins.

The condensed format is a bit smaller than the fixed width format, but the fixed width format enables rapid searches if the set of pins are sorted by either the label (enables fast label in file) or the likely more useful sorting by top index to filter candidate pins when performing random access to a z-slice.

References

  1. Matejek, B., Haehn, D., Lekschas, F., Mitzenmacher, M., Pfister, H., 2017. Compresso: Efficient Compression of Segmentation Data for Connectomics, in: Descoteaux, M., Maier-Hein, L., Franz, A., Jannin, P., Collins, D.L., Duchesne, S. (Eds.), Medical Image Computing and Computer Assisted Intervention − MICCAI 2017, Lecture Notes in Computer Science. Springer International Publishing, Cham, pp. 781–788. https://doi.org/10.1007/978-3-319-66182-7_89

  2. Zingaretti, P., Gasparroni, M., Vecci, L., 1998. Fast chain coding of region boundaries. IEEE Transactions on Pattern Analysis and Machine Intelligence 20, 407–415. https://doi.org/10.1109/34.677272

  3. Freeman, H., 1974. Computer Processing of Line-Drawing Images. ACM Comput. Surv. 6, 57–97. https://doi.org/10.1145/356625.356627

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crackle_codec-0.39.0.tar.gz (153.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

crackle_codec-0.39.0-cp314-cp314t-win_amd64.whl (347.8 kB view details)

Uploaded CPython 3.14tWindows x86-64

crackle_codec-0.39.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (501.7 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (481.9 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp314-cp314t-macosx_11_0_arm64.whl (460.7 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

crackle_codec-0.39.0-cp314-cp314t-macosx_10_15_x86_64.whl (520.7 kB view details)

Uploaded CPython 3.14tmacOS 10.15+ x86-64

crackle_codec-0.39.0-cp314-cp314-win_amd64.whl (334.7 kB view details)

Uploaded CPython 3.14Windows x86-64

crackle_codec-0.39.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (501.6 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (481.0 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp314-cp314-macosx_11_0_arm64.whl (453.1 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

crackle_codec-0.39.0-cp314-cp314-macosx_10_15_x86_64.whl (513.8 kB view details)

Uploaded CPython 3.14macOS 10.15+ x86-64

crackle_codec-0.39.0-cp313-cp313-win_amd64.whl (327.2 kB view details)

Uploaded CPython 3.13Windows x86-64

crackle_codec-0.39.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (501.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (480.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp313-cp313-macosx_11_0_arm64.whl (453.0 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

crackle_codec-0.39.0-cp313-cp313-macosx_10_13_x86_64.whl (513.3 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

crackle_codec-0.39.0-cp312-cp312-win_amd64.whl (327.1 kB view details)

Uploaded CPython 3.12Windows x86-64

crackle_codec-0.39.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (501.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (480.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp312-cp312-macosx_11_0_arm64.whl (453.0 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

crackle_codec-0.39.0-cp312-cp312-macosx_10_13_x86_64.whl (513.3 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

crackle_codec-0.39.0-cp311-cp311-win_amd64.whl (325.2 kB view details)

Uploaded CPython 3.11Windows x86-64

crackle_codec-0.39.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (497.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (477.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp311-cp311-macosx_11_0_arm64.whl (451.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

crackle_codec-0.39.0-cp311-cp311-macosx_10_9_x86_64.whl (511.3 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

crackle_codec-0.39.0-cp310-cp310-win_amd64.whl (324.2 kB view details)

Uploaded CPython 3.10Windows x86-64

crackle_codec-0.39.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (495.0 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (476.0 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp310-cp310-macosx_11_0_arm64.whl (451.0 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

crackle_codec-0.39.0-cp310-cp310-macosx_10_9_x86_64.whl (509.9 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

crackle_codec-0.39.0-cp39-cp39-win_amd64.whl (326.3 kB view details)

Uploaded CPython 3.9Windows x86-64

crackle_codec-0.39.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (494.6 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

crackle_codec-0.39.0-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl (476.2 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.26+ ARM64manylinux: glibc 2.28+ ARM64

crackle_codec-0.39.0-cp39-cp39-macosx_11_0_arm64.whl (451.1 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

crackle_codec-0.39.0-cp39-cp39-macosx_10_9_x86_64.whl (509.8 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

File details

Details for the file crackle_codec-0.39.0.tar.gz.

File metadata

  • Download URL: crackle_codec-0.39.0.tar.gz
  • Upload date:
  • Size: 153.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for crackle_codec-0.39.0.tar.gz
Algorithm Hash digest
SHA256 506c181f4c60ce9fef6ef2f72473c2d334d846afecfe292691c61b7efccf3224
MD5 df1e8a5a269e2a692acd383b71c21bb5
BLAKE2b-256 ec7d6053329480c6dd224937f5e19f2c359aa8876fb5770c2fe878f271934b7a

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314t-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314t-win_amd64.whl
Algorithm Hash digest
SHA256 dfe5b0df0b487806d50f87135d070bb4f2c7ea1dffe5058ea41f8e668d17737f
MD5 afbcdcefa8aacd83bcad0e3060694d31
BLAKE2b-256 b5995addb12980f80e0596ca0ed658e6f8c2d26d6cf93dbc86c5869282ca8ee1

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe675670d7e46063bd14be7a375c5c001cdf186748b6790b17b8a4af171fe162
MD5 66e50ab9f9f97060f513a3a576ee1cd5
BLAKE2b-256 adb8ffca70f9624f8b58a52d3b79f6ffc79c71ab28ec82ed4740c5a81cfacd43

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3bdc636e60366ba8b2ffab28c829913f98161a271ad950c0ab7ad820c5c70142
MD5 824c5ada18121282a3805bf99a5c29d6
BLAKE2b-256 e4b2da1c7b03b74c4c13bdc6d2ba5e689531e9e320295bf0e1fb95c503db9d54

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dc239ecdd39cdbfd6d88037196de5f50c8abd556fa19b0760004b9afa4bdd168
MD5 13fdcba73abcf3690b8e0a28ec1a7bd0
BLAKE2b-256 c4c2413929a46968c137537b1acb848c2f4567af1fb492abb2c406f1892f0d38

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314t-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314t-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 147fa4b012433f5b3db17438d3e59cfe61a6251f2bb41e50c87c36fd857f0b5a
MD5 1813debde27f3420a09d1186d13beaaa
BLAKE2b-256 f90f649046c429ba74a9400a01efa78fc06feeb380784e94e5889cc948e01db9

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 bfa38c0348e27ec4aab9067b4d34df621d6a4454ae7e933d08f269ae47fc9792
MD5 ef3e97b1da1826e9a27b4569b02564ea
BLAKE2b-256 d8b12c7352d32861c13d353b0feac04aab6872dd2173ae9c5f413304922f93d3

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 524e836aa543308f5ed912466c551ff165920d68b8db72c94a330f4fe1d95088
MD5 d9a1c00ddb338523f55faf6b51b098da
BLAKE2b-256 06d5c75a170913621dc2d1038483df7982c51a0e97e4362cb9f7240713c6cb58

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 74bcdda1e4ad42e25fce3abc7bef8d8898156d8460b1000ab79a9be27f14c357
MD5 50671906e8c74c5629be0f4544f8fdc9
BLAKE2b-256 77570e0877d0149ab031beeffd3501986a511203f65732a31ccd088b9b99d5d3

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 84ba353e99ede01a825da472c15c84e91913d6e5daf4487c1339e113a3a53a9e
MD5 183c7fa6da2f33b0413b259d16b247e8
BLAKE2b-256 a16aebb57680578aeed6a1d75d729f96296e59015d3b9f48312d04d11f569cff

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp314-cp314-macosx_10_15_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp314-cp314-macosx_10_15_x86_64.whl
Algorithm Hash digest
SHA256 424669ca7e8437bbcff50e79c1f41a3aae5e2b2bcc2d2ed2e7d63131bf155a9e
MD5 6924ca3ec53e651d3b70644ced6e69c2
BLAKE2b-256 d74a1c748adbdd53ffe687bff6a0edba799bd954384be8be6c60e4c95baf804a

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 76f6959487aa95505e3c3ce14c368a7ba2e7c68fdfcb22276eba6674d278911b
MD5 fa6ab43b9498e22bb17b4577ee39d2f0
BLAKE2b-256 51e16ecc1b4961de1f0d81ad1b87a729927737c284b288dca4e872b44f7c47d1

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41619054088553b897a3b59a4d4426fdf19a0f24db908e051479adda4becbbb4
MD5 22066f188e9404c945454506be599d23
BLAKE2b-256 8369eacfd826e838bd02d87ee8ceb79fb1e6f5fab48aa24c1d00077baea4fd6b

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 b8296e476c4dcb015318eab9ef854c1b083e139b9fbc3d7c0bd479a4b96390c7
MD5 4dfcaf7808496eaf964be907152b10dc
BLAKE2b-256 83bb2e77603f3119c15acbef7824177facb5429e6728c0af5afd6951990a51fb

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6377e7df4f99cdf88a75c7a200fba81395c344661824392a35fe202e0bf5918a
MD5 9fc911e106dda81dc029020db7cb3362
BLAKE2b-256 455f66b30b6167949adc37248099229b30969edcf1204f3b0468698964e5c6ed

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 5d3605cd41a6a55fa2ed9e9005e5fad07e508ec71ed0058f46d9b875a2a22968
MD5 85015ab13cc5737228f684df1cc1d335
BLAKE2b-256 2d29a005d88d06905fc322b21199d8b9646da1705a53d6e60b7020a1d21e1ac8

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 1f75ce1658959fa6050e018f0cac37d03aeab65aec9fc3b1f81a80aaa9fde290
MD5 d5c16fe51c64038e3faeaebbf9e8b17b
BLAKE2b-256 8cb485ae7e2f252947a3475ae736fea0d8989102a55fb3c0765c11c80de1ed29

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 426a361eb444d8e026a3ac8ef1e97da2b8f62487970842849dcf5ff263705f87
MD5 dcda0166cc540d583113573e987ecc01
BLAKE2b-256 98e268950b12458f99cbbc6c9bef07abc05db42f39b208988dc9c365ee980b42

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9a8718f06acab55b6df6800a906ceb080cad2247dd99c61fc6e420bbb4a72332
MD5 f87656e2b45d32cd92263db8bc40aff5
BLAKE2b-256 3b615af0a4f3605d554cdd8618f2635304cb196abcf2b97c5589ac3cf854c112

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c02e2f930ec19bd0caea35ccd7cd7c5b53600fd7b7ded204be165cffd27c6631
MD5 7a5470367d92d1498993ad0ee60dfc21
BLAKE2b-256 fd95817e1d9b70f3fd30fe6333c29e38d8deb0c4a00d8716818dec97a4e08e39

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 16aad859b68491c949cb7ad3c8e8484cad3bfdfdb63382e9a4df5334ca17f70d
MD5 b71c919901f5616bd3bfcaa2f812a9be
BLAKE2b-256 13ec7c99d7adaf685a46315b1aac5cad8903caaf2ae8612aa37427ed7cc201eb

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 b66d679ea9174ce0c2d9ee888e4f75f0132f496f588aab95c177cdf149c6dbd5
MD5 1d4134cf6daba827d4291a63e5ff5817
BLAKE2b-256 fc8302577ca583f2fe7c8d9040b2cd9f2217d9684758e3dd5363811a54ad38d4

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a14e8bf01e3a6776c5a71cef439e279c22a35254b30ff7083e5a8933ad2df758
MD5 761630679f1fb8a58bbb6abc71ae106d
BLAKE2b-256 a5a9e85d57efcb4c093a6e63dacc5f5227ba74d89bc8aa666d9816f55c3876fc

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3c3637c3279b61c290cb7f0156d4482aa6f6ea5eb50a6367e44142a56dd7b3e9
MD5 66ba0c3af3458993d8ad87076e0bc874
BLAKE2b-256 913a56a327668fc199900a1e0ffe299a64da232f54c63847d35cb93a15596776

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 274bdc1f35670b20a38163a1e97ea17e2e3e4b0776f3c6b594a955ce6839bfc3
MD5 4d08a8d18f2c3510e86ac23a42150c27
BLAKE2b-256 471135e7ed4533ae22199d93c5025c93521d5672597d0fcc728da70a39bade56

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 256b0bc83419f3ed4584d359b8d06a3c150b7760f93e8f3856189d70cdf05730
MD5 7a30e2415663eca7c98cfa7920f1f48a
BLAKE2b-256 3cf1c5765cccb040ca056de012624a6698ecebe6a5c0d8a65e0dfb676b8fbd8d

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 81090b5b8894797b380f92670639772d9d8d3a84fd39f6835f5ff86c6fa8ea92
MD5 7d9ec09e3ed9ce8ad5649c3b5116113d
BLAKE2b-256 0fcc18e70677460e54321df9ed380dc825f4d9c1f08a044cf069f0f8d192b965

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 9a469c05fc470faa062493e984e35e37fefb8b80f9115918d4e7654ed40489f7
MD5 6874615c93dec46cc2144012c9632faa
BLAKE2b-256 5bfe887392a148d85407a03aa6481f47cab811d413ab1729f9611f31b7d2c785

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 56564459b1c647402d9951c6fcd2f44c1820fe01b706d0eac8243d0bca148ca2
MD5 7a7a56e7f0dd773e9496f637a03f0364
BLAKE2b-256 5bfcc6b20b466b249857a22f97816e1f7171cb835aeb185ffa31ab24cc613064

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f02f4f3592bd355b81cd1fc9857a4fb405b29ff6e7d4cd63b71025cb09cf78a8
MD5 f08c6877085c933b3ffc3012cfbcd565
BLAKE2b-256 a458dcda4da73574e24c0ceb2799cdb8052ada304c7d50316d45e150946cc10c

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 8944f784821a5e41acc9461d4bb74816afbe42c4747245f6aaac0105c96176b6
MD5 46725c65c532130285e4bdadcabc927b
BLAKE2b-256 a618d66b12d705d6d68c7970e6bc41d3993e6e9734a31f74c540d5c9c860302b

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp39-cp39-win_amd64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 ce7f6bbf795581156f5d300b340762c5822407ddbb8e00213cd597b29fa64f86
MD5 2b64e02bef9721edf29359db51bdee94
BLAKE2b-256 8a6faa02e10fa375deb8ef44e0fa404247d06ffa2224119d7a5bc3d8fc1d5b20

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bc9ff1e9c7aeb86babdeb6a98afceb87d4cad1e18f1e4b9637e5de9e4a94c922
MD5 19d07d4030b7b0f2d62dcb698a028f18
BLAKE2b-256 dee20ba421d2d7f0f4eed68ee8a334b7985dae8be17f50fc0f2c48fa9438acad

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8e64f45205b1c301c8cb67cbe9554dbfa2278d32c89bece6aab1f0073cdf81f8
MD5 c9209437aa641d71fc4800070056cc94
BLAKE2b-256 589049d0d412f3d8073a6e2cd227d78874e4923b100e39172d1c42557a06d12e

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0a2b154d16ecc1d72d3bb558aabf4b195caa6016fda0d7e257eac1927fa9d5d1
MD5 2b42986b2a16e752f12161c61a1d757a
BLAKE2b-256 01d0515e2851ee9d6bbdea2ef97086855fa653990b3005f3c52976e6497604fc

See more details on using hashes here.

File details

Details for the file crackle_codec-0.39.0-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for crackle_codec-0.39.0-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 be9d60da1e8e05c801d52c23a65ea33d02df8344d26bb7b0d2cda5168c26b2ed
MD5 0de1737d60bb239cc1e1cab7f4128266
BLAKE2b-256 d7f397524a57651a061a0d4a2c56c45bc68bdc3c9ffb8ee249f33d16b246f2a3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page