diff --git a/Cargo.lock b/Cargo.lock index 61619c24..f3e1a25c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1049,6 +1049,7 @@ dependencies = [ "enum-as-inner 0.6.0", "fxhash", "js-sys", + "leb128", "loro-rle 0.16.2", "nonmax", "serde", diff --git a/crates/loro-common/Cargo.toml b/crates/loro-common/Cargo.toml index 8db666b4..a5a4554e 100644 --- a/crates/loro-common/Cargo.toml +++ b/crates/loro-common/Cargo.toml @@ -25,6 +25,7 @@ arbitrary = { version = "1.3.0", features = ["derive"] } js-sys = { version = "0.3.60", optional = true } serde_columnar = { workspace = true } nonmax = "0.5.5" +leb128 = "0.2.5" [features] wasm = ["wasm-bindgen", "js-sys"] diff --git a/crates/loro-common/src/lib.rs b/crates/loro-common/src/lib.rs index b38417dc..600d9fbc 100644 --- a/crates/loro-common/src/lib.rs +++ b/crates/loro-common/src/lib.rs @@ -1,4 +1,4 @@ -use std::{fmt::Display, sync::Arc}; +use std::{fmt::Display, io::Write, sync::Arc}; use arbitrary::Arbitrary; use enum_as_inner::EnumAsInner; @@ -158,6 +158,87 @@ pub enum ContainerID { }, } +/// Root is less than Normal. +/// The same ContainerType should be grouped together. +impl Ord for ContainerID { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match (self, other) { + ( + Self::Root { + name, + container_type, + }, + Self::Root { + name: name2, + container_type: container_type2, + }, + ) => { + if container_type == container_type2 { + name.cmp(name2) + } else { + container_type.cmp(container_type2) + } + } + ( + Self::Normal { + peer, + counter, + container_type, + }, + Self::Normal { + peer: peer2, + counter: counter2, + container_type: container_type2, + }, + ) => { + if container_type == container_type2 { + if peer == peer2 { + counter.cmp(counter2) + } else { + peer.cmp(peer2) + } + } else { + container_type.cmp(container_type2) + } + } + (Self::Root { .. }, Self::Normal { .. }) => std::cmp::Ordering::Less, + (Self::Normal { .. }, Self::Root { .. }) => std::cmp::Ordering::Greater, + } + } +} + +impl PartialOrd for ContainerID { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl ContainerID { + pub fn encode(&self, writer: &mut W) -> Result<(), std::io::Error> { + match self { + Self::Root { + name, + container_type, + } => { + writer.write_all(&[0, container_type.to_u8()])?; + leb128::write::unsigned(writer, name.len() as u64)?; + writer.write_all(name.as_bytes())?; + } + Self::Normal { + peer, + counter, + container_type, + } => { + writer.write_all(&[1, container_type.to_u8()])?; + writer.write_all(&peer.to_le_bytes())?; + leb128::write::unsigned(writer, *counter as u64)?; + } + } + + Ok(()) + } +} + impl std::fmt::Debug for ContainerID { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/crates/loro-internal/src/oplog/change_store.rs b/crates/loro-internal/src/oplog/change_store.rs index c691b927..e283bcde 100644 --- a/crates/loro-internal/src/oplog/change_store.rs +++ b/crates/loro-internal/src/oplog/change_store.rs @@ -1,19 +1,16 @@ use bytes::Bytes; use itertools::Itertools; use loro_common::{ - Counter, HasId, HasIdSpan, HasLamportSpan, IdLp, IdSpan, Lamport, LoroError, LoroResult, - PeerID, ID, + Counter, HasId, HasIdSpan, IdLp, IdSpan, Lamport, LoroError, LoroResult, PeerID, ID, }; use once_cell::sync::OnceCell; -use rle::{HasLength, Mergable, RleCollection, RlePush}; +use rle::{HasLength, Mergable}; use std::{ cmp::Ordering, collections::{BTreeMap, VecDeque}, - io::Read, ops::Deref, sync::{atomic::AtomicI64, Arc, Mutex}, }; -use tracing::trace; mod block_encode; mod delta_rle_encode; use crate::{ @@ -47,7 +44,7 @@ impl ChangeStore { match block.push_change( change, self.merge_interval - .load(std::sync::atomic::Ordering::Acquire) as i64, + .load(std::sync::atomic::Ordering::Acquire), ) { Ok(_) => { return; @@ -64,7 +61,7 @@ impl ChangeStore { } pub fn block_num(&self) -> usize { - let mut kv = self.kv.lock().unwrap(); + let kv = self.kv.lock().unwrap(); kv.len() } @@ -75,7 +72,6 @@ impl ChangeStore { .iter_mut() .map(|(id, block)| (*id, block.bytes(&self.arena))); for (_, block) in iter { - println!("block size {}", block.bytes.len()); leb128::write::unsigned(&mut bytes, block.bytes.len() as u64).unwrap(); bytes.extend(&block.bytes); } diff --git a/crates/loro-internal/src/oplog/change_store/block_encode.rs b/crates/loro-internal/src/oplog/change_store/block_encode.rs index 0696c10a..c89e78ce 100644 --- a/crates/loro-internal/src/oplog/change_store/block_encode.rs +++ b/crates/loro-internal/src/oplog/change_store/block_encode.rs @@ -87,7 +87,7 @@ use serde_columnar::{ }; #[derive(Serialize, Deserialize)] -struct EncodedDoc<'a> { +struct EncodedBlock<'a> { version: u16, n_changes: u32, first_counter: u32, @@ -248,7 +248,7 @@ pub fn encode_block(block: &[Change], arena: &SharedArena) -> Vec { // └────────────────┴─────────────────────────────────────────────┘ let value_bytes = value_writer.finish(); - let out = EncodedDoc { + let out = EncodedBlock { version: VERSION, n_changes: block.len() as u32, first_counter: block[0].id.counter as u32, @@ -343,8 +343,8 @@ pub fn decode_header(m_bytes: &[u8]) -> LoroResult { decode_header_from_doc(&doc) } -fn decode_header_from_doc(doc: &EncodedDoc) -> Result { - let EncodedDoc { +fn decode_header_from_doc(doc: &EncodedBlock) -> Result { + let EncodedBlock { n_changes, first_counter, peers: peers_bytes, @@ -499,7 +499,7 @@ pub fn decode_block( header_on_stack = Some(decode_header_from_doc(&doc).unwrap()); &header_on_stack.as_ref().unwrap() }); - let EncodedDoc { + let EncodedBlock { version, n_changes, first_counter, diff --git a/crates/loro-internal/src/state.rs b/crates/loro-internal/src/state.rs index a499b48c..2a76b13b 100644 --- a/crates/loro-internal/src/state.rs +++ b/crates/loro-internal/src/state.rs @@ -26,6 +26,7 @@ use crate::{ ContainerDiff, ContainerType, DocDiff, InternalString, LoroValue, OpLog, }; +mod container_store; #[cfg(feature = "counter")] mod counter_state; mod list_state; diff --git a/crates/loro-internal/src/state/container_store.rs b/crates/loro-internal/src/state/container_store.rs new file mode 100644 index 00000000..5f5c4693 --- /dev/null +++ b/crates/loro-internal/src/state/container_store.rs @@ -0,0 +1,129 @@ +use crate::{arena::SharedArena, container::idx::ContainerIdx}; +use bytes::Bytes; +use fxhash::FxHashMap; +use loro_common::{ContainerID, LoroValue}; +use once_cell::sync::OnceCell; + +use super::{ContainerState, State}; + +/// ```log +/// +/// Encoding Schema for Container Store +/// +/// ┌───────────────────────────────────────────────────┐ +/// │ N CID + Offsets │ +/// │ (EncodedBy DeltaRLE) │ +/// └───────────────────────────────────────────────────┘ +/// ┌───────────────────────────────────────────────────┐ +/// │ │ +/// │ │ +/// │ │ +/// │ All Containers' Binary │ +/// │ │ +/// │ │ +/// │ │ +/// └───────────────────────────────────────────────────┘ +/// +/// +/// ─ ─ ─ ─ ─ ─ ─ For Each Container Type ─ ─ ─ ─ ─ ─ ─ ─ +/// +/// ┌────────────────┬──────────────────────────────────┐ +/// │ u16 Depth │ ParentID │ +/// └────────────────┴──────────────────────────────────┘ +/// ┌───────────────────────────────────────────────────┐ +/// │ ┌───────────────────────────────────────────────┐ │ +/// │ │ Into │ │ +/// │ └───────────────────────────────────────────────┘ │ +/// │ │ +/// │ Container Specific Encode │ +/// │ │ +/// │ │ +/// │ │ +/// │ │ +/// └───────────────────────────────────────────────────┘ +/// ``` +pub(crate) struct ContainerStore { + arena: SharedArena, + store: FxHashMap, +} + +impl ContainerStore { + pub fn get_container(&mut self, idx: ContainerIdx) -> Option<&mut ContainerWrapper> { + self.store.get_mut(&idx) + } + + pub fn get_value(&mut self, idx: ContainerIdx) -> Option { + self.store.get_mut(&idx).and_then(|c| c.get_value()) + } + + pub fn from_bytes(bytes: Bytes) -> Self { + todo!("decode all containers into bytes") + } + + pub fn encode(&self) -> Bytes { + todo!("encode all containers into bytes") + } +} + +pub(crate) enum ContainerWrapper { + Bytes(Bytes), + PartialParsed { bytes: Bytes, value: LoroValue }, + Parsed { bytes: Bytes, state: State }, + State(State), +} + +impl ContainerWrapper { + pub fn get_state(&mut self) -> Option<&State> { + match self { + ContainerWrapper::Bytes(_) => todo!(), + ContainerWrapper::PartialParsed { bytes, value } => todo!(), + ContainerWrapper::Parsed { bytes, state } => todo!(), + ContainerWrapper::State(_) => todo!(), + } + } + + pub fn get_value(&mut self) -> Option { + match self { + ContainerWrapper::Bytes(bytes) => todo!("partial parse"), + ContainerWrapper::PartialParsed { bytes, value } => Some(value.clone()), + ContainerWrapper::Parsed { bytes, state } => Some(state.get_value()), + ContainerWrapper::State(s) => Some(s.get_value()), + } + } +} + +mod encode { + use loro_common::ContainerID; + use serde::{Deserialize, Serialize}; + use std::borrow::Cow; + + #[derive(Serialize, Deserialize)] + struct EncodedStateStore<'a> { + #[serde(borrow)] + cids: Cow<'a, [u8]>, + #[serde(borrow)] + bytes: Cow<'a, [u8]>, + } + + pub(super) struct CidOffsetEncoder {} + + impl CidOffsetEncoder { + pub fn push(&mut self, cid: &ContainerID, offset: usize) { + todo!() + } + + pub fn finish(self) -> Vec { + todo!() + } + } + + pub(super) struct CidOffsetDecoder {} + + impl Iterator for CidOffsetDecoder { + type Item = (ContainerID, usize); + + fn next(&mut self) -> Option { + todo!() + } + } +} diff --git a/crates/loro-wasm/deno.lock b/crates/loro-wasm/deno.lock index ef38bfde..68ca1b3e 100644 --- a/crates/loro-wasm/deno.lock +++ b/crates/loro-wasm/deno.lock @@ -1,6 +1,8 @@ { "version": "3", "redirects": { + "https://deno.land/std/archive/mod.ts": "https://deno.land/std@0.224.0/archive/mod.ts", + "https://deno.land/std/encoding/base64.ts": "https://deno.land/std@0.224.0/encoding/base64.ts", "https://x.nest.land/std@0.73.0/path/mod.ts": "https://lra6z45nakk5lnu3yjchp7tftsdnwwikwr65ocha5eojfnlgu4sa.arweave.net/XEHs860CldW2m8JEd_5lnIbbWQq0fdcI4OkckrVmpyQ/path/mod.ts" }, "remote": { @@ -15,6 +17,120 @@ "https://deno.land/std@0.105.0/path/posix.ts": "b81974c768d298f8dcd2c720229639b3803ca4a241fa9a355c762fa2bc5ef0c1", "https://deno.land/std@0.105.0/path/separator.ts": "8fdcf289b1b76fd726a508f57d3370ca029ae6976fcde5044007f062e643ff1c", "https://deno.land/std@0.105.0/path/win32.ts": "f4a3d4a3f2c9fe894da046d5eac48b5e789a0ebec5152b2c0985efe96a9f7ae1", + "https://deno.land/std@0.129.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.129.0/_util/os.ts": "49b92edea1e82ba295ec946de8ffd956ed123e2948d9bd1d3e901b04e4307617", + "https://deno.land/std@0.129.0/archive/tar.ts": "35ea1baddec7988cc4034765a2cee7613bc8074bd40940d3f5e98f63070a716a", + "https://deno.land/std@0.129.0/async/abortable.ts": "a896ac6b0d4237bd2d2d248217cfa1f0d85ccda93cb25ebda55e33850e526be6", + "https://deno.land/std@0.129.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0", + "https://deno.land/std@0.129.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620", + "https://deno.land/std@0.129.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a", + "https://deno.land/std@0.129.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c", + "https://deno.land/std@0.129.0/async/mod.ts": "2240c6841157738414331f47dee09bb8c0482c5b1980b6e3234dd03515c8132f", + "https://deno.land/std@0.129.0/async/mux_async_iterator.ts": "f4d1d259b0c694d381770ddaaa4b799a94843eba80c17f4a2ec2949168e52d1e", + "https://deno.land/std@0.129.0/async/pool.ts": "97b0dd27c69544e374df857a40902e74e39532f226005543eabacb551e277082", + "https://deno.land/std@0.129.0/async/tee.ts": "1341feb1f5b1a96f8628d0f8fc07d8c43d3813423f18a63bf1b4785568d21b1f", + "https://deno.land/std@0.129.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d", + "https://deno.land/std@0.129.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9", + "https://deno.land/std@0.129.0/bytes/mod.ts": "d3b455c0dbd4804644159d1e25946ade5ee385d2359894de49e2c6101b18b7a9", + "https://deno.land/std@0.129.0/encoding/base64.ts": "c8c16b4adaa60d7a8eee047c73ece26844435e8f7f1328d74593dbb2dd58ea4f", + "https://deno.land/std@0.129.0/encoding/base64url.ts": "55f9d13df02efac10c6f96169daa3e702606a64e8aa27c0295f645f198c27130", + "https://deno.land/std@0.129.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37", + "https://deno.land/std@0.129.0/fmt/printf.ts": "e2c0f72146aed1efecf0c39ab928b26ae493a2278f670a871a0fbdcf36ff3379", + "https://deno.land/std@0.129.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f", + "https://deno.land/std@0.129.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d", + "https://deno.land/std@0.129.0/fs/ensure_file.ts": "7d353e64fee3d4d1e7c6b6726a2a5e987ba402c15fb49566309042887349c545", + "https://deno.land/std@0.129.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", + "https://deno.land/std@0.129.0/io/files.ts": "d199ef64e918a256320ba8d8d44ae91de87c9077df8f8d6cca013f1b9fbbe285", + "https://deno.land/std@0.129.0/io/readers.ts": "679471f3b9929b54393c9cd75b6bd178b4bc6d9aab5c0f1f9538f862cf4746fe", + "https://deno.land/std@0.129.0/io/util.ts": "078da53bba767bec0d45f7da44411f6dbf269e51ef7fcfea5e3714e04681c674", + "https://deno.land/std@0.129.0/node/_buffer.mjs": "f4a7df481d4eed06dc0151b833177d8ef74fc3a96dd4d2b073e690b6ced9474d", + "https://deno.land/std@0.129.0/node/_core.ts": "568d277be2e086af996cbdd599fec569f5280e9a494335ca23ad392b130d7bb9", + "https://deno.land/std@0.129.0/node/_events.mjs": "c0e3e0e290a8b81fee9d2973a529c8dcd5ebb4406782d1f91085274e2cb8490f", + "https://deno.land/std@0.129.0/node/_fixed_queue.ts": "455b3c484de48e810b13bdf95cd1658ecb1ba6bcb8b9315ffe994efcde3ba5f5", + "https://deno.land/std@0.129.0/node/_next_tick.ts": "64c361f6bca21df2a72dd77b84bd49d80d97a694dd3080703bc78f52146351d1", + "https://deno.land/std@0.129.0/node/_process/exiting.ts": "bc9694769139ffc596f962087155a8bfef10101d03423b9dcbc51ce6e1f88fce", + "https://deno.land/std@0.129.0/node/_util/_util_callbackify.ts": "79928ad80df3e469f7dcdb198118a7436d18a9f6c08bd7a4382332ad25a718cf", + "https://deno.land/std@0.129.0/node/_utils.ts": "c2c352e83c4c96f5ff994b1c8246bff2abcb21bfc3f1c06162cb3af1d201e615", + "https://deno.land/std@0.129.0/node/buffer.ts": "fbecbf3f237fa49bec96e97ecf56a7b92d48037b3d11219288e68943cc921600", + "https://deno.land/std@0.129.0/node/events.ts": "a1d40fc0dbccc944379ef968b80ea08f9fce579e88b5057fdb64e4f0812476dd", + "https://deno.land/std@0.129.0/node/internal/buffer.mjs": "6662fe7fe517329453545be34cea27a24f8ccd6d09afd4f609f11ade2b6dfca7", + "https://deno.land/std@0.129.0/node/internal/crypto/keys.ts": "16ce7b15a9fc5e4e3dee8fde75dae12f3d722558d5a1a6e65a9b4f86d64a21e9", + "https://deno.land/std@0.129.0/node/internal/crypto/util.mjs": "1de55a47fdbed6721b467a77ba48fdd1550c10b5eee77bbdb602eaffee365a5e", + "https://deno.land/std@0.129.0/node/internal/error_codes.ts": "ac03c4eae33de3a69d6c98e8678003207eecf75a6900eb847e3fea3c8c9e6d8f", + "https://deno.land/std@0.129.0/node/internal/errors.ts": "0d3a1eb03b654beb29b8354759a6902f45a840d4f957e9a3c632a24ce4c32632", + "https://deno.land/std@0.129.0/node/internal/hide_stack_frames.ts": "a91962ec84610bc7ec86022c4593cdf688156a5910c07b5bcd71994225c13a03", + "https://deno.land/std@0.129.0/node/internal/normalize_encoding.mjs": "3779ec8a7adf5d963b0224f9b85d1bc974a2ec2db0e858396b5d3c2c92138a0a", + "https://deno.land/std@0.129.0/node/internal/util.mjs": "684653b962fae84fd2bc08997291b1a50bed09b95dcfa7d35e3c4143163e879a", + "https://deno.land/std@0.129.0/node/internal/util/comparisons.ts": "680b55fe8bdf1613633bc469fa0440f43162c76dbe36af9aa2966310e1bb9f6e", + "https://deno.land/std@0.129.0/node/internal/util/debuglog.ts": "99e91bdf26f6c67861031f684817e1705a5bc300e81346585b396f413387edfb", + "https://deno.land/std@0.129.0/node/internal/util/inspect.mjs": "d1c2569c66a3dab45eec03208f22ad4351482527859c0011a28a6c797288a0aa", + "https://deno.land/std@0.129.0/node/internal/util/types.ts": "b2dacb8f1f5d28a51c4da5c5b75172b7fcf694073ce95ca141323657e18b0c60", + "https://deno.land/std@0.129.0/node/internal/validators.mjs": "a7e82eafb7deb85c332d5f8d9ffef052f46a42d4a121eada4a54232451acc49a", + "https://deno.land/std@0.129.0/node/internal_binding/_libuv_winerror.ts": "801e05c2742ae6cd42a5f0fd555a255a7308a65732551e962e5345f55eedc519", + "https://deno.land/std@0.129.0/node/internal_binding/_node.ts": "e4075ba8a37aef4eb5b592c8e3807c39cb49ca8653faf8e01a43421938076c1b", + "https://deno.land/std@0.129.0/node/internal_binding/_utils.ts": "1c50883b5751a9ea1b38951e62ed63bacfdc9d69ea665292edfa28e1b1c5bd94", + "https://deno.land/std@0.129.0/node/internal_binding/_winerror.ts": "8811d4be66f918c165370b619259c1f35e8c3e458b8539db64c704fbde0a7cd2", + "https://deno.land/std@0.129.0/node/internal_binding/buffer.ts": "722c62b85f966e0777b2d98c021b60e75d7f2c2dabc43413ef37d60dbd13a5d9", + "https://deno.land/std@0.129.0/node/internal_binding/constants.ts": "aff06aac49eda4234bd3a2b0b8e1fbfc67824e281c532ff9960831ab503014cc", + "https://deno.land/std@0.129.0/node/internal_binding/string_decoder.ts": "5cb1863763d1e9b458bc21d6f976f16d9c18b3b3f57eaf0ade120aee38fba227", + "https://deno.land/std@0.129.0/node/internal_binding/types.ts": "4c26fb74ba2e45de553c15014c916df6789529a93171e450d5afb016b4c765e7", + "https://deno.land/std@0.129.0/node/internal_binding/util.ts": "90364292e2bd598ab5d105b48ca49817b6708f2d1d9cbaf08b2b3ab5ca4c90a7", + "https://deno.land/std@0.129.0/node/internal_binding/uv.ts": "3821bc5e676d6955d68f581988c961d77dd28190aba5a9c59f16001a4deb34ba", + "https://deno.land/std@0.129.0/node/util.ts": "7fd6933b37af89a8e64d73dc6ee1732455a59e7e6d0965311fbd73cd634ea630", + "https://deno.land/std@0.129.0/node/util/types.mjs": "f9288198cacd374b41bae7e92a23179d3160f4c0eaf14e19be3a4e7057219a60", + "https://deno.land/std@0.129.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.129.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.129.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.129.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.129.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.129.0/path/mod.ts": "4275129bb766f0e475ecc5246aa35689eeade419d72a48355203f31802640be7", + "https://deno.land/std@0.129.0/path/posix.ts": "663e4a6fe30a145f56aa41a22d95114c4c5582d8b57d2d7c9ed27ad2c47636bb", + "https://deno.land/std@0.129.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.129.0/path/win32.ts": "e7bdf63e8d9982b4d8a01ef5689425c93310ece950e517476e22af10f41a136e", + "https://deno.land/std@0.129.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", + "https://deno.land/std@0.129.0/testing/_diff.ts": "9d849cd6877694152e01775b2d93f9d6b7aef7e24bfe3bfafc4d7a1ac8e9f392", + "https://deno.land/std@0.129.0/testing/asserts.ts": "0a95d9e8076dd3e7f0eeb605a67c148078b4b11f4abcd5eef115b0361b0736a2", + "https://deno.land/std@0.224.0/archive/_common.ts": "5fcad5f7280cec1d20540b4a6e43ea9a6fd63daf9c4cf8a58c6321d07c32e317", + "https://deno.land/std@0.224.0/archive/mod.ts": "db33ebaf625ec4a7489ab383a22a24bcebdb4de1522d995863cff62c462fff33", + "https://deno.land/std@0.224.0/archive/tar.ts": "14ab32955e8dc15713436ff676b4cf141a73a6d7594489d2866c7d76e18922bd", + "https://deno.land/std@0.224.0/archive/untar.ts": "bd39dbeda737f6fd9409b5923d7172f8abd7826508f09c4a1c38886574f6da4a", + "https://deno.land/std@0.224.0/assert/assert.ts": "09d30564c09de846855b7b071e62b5974b001bb72a4b797958fe0660e7849834", + "https://deno.land/std@0.224.0/assert/assertion_error.ts": "ba8752bd27ebc51f723702fac2f54d3e94447598f54264a6653d6413738a8917", + "https://deno.land/std@0.224.0/bytes/concat.ts": "86161274b5546a02bdb3154652418efe7af8c9310e8d54107a68aaa148e0f5ed", + "https://deno.land/std@0.224.0/bytes/copy.ts": "08d85062240a7223e6ec4e2af193ad1a50c59a43f0d86ac3a7b16f3e0d77c028", + "https://deno.land/std@0.224.0/encoding/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376", + "https://deno.land/std@0.224.0/encoding/base64.ts": "dd59695391584c8ffc5a296ba82bcdba6dd8a84d41a6a539fbee8e5075286eaf", + "https://deno.land/std@0.224.0/io/_constants.ts": "3c7ad4695832e6e4a32e35f218c70376b62bc78621ef069a4a0a3d55739f8856", + "https://deno.land/std@0.224.0/io/buf_reader.ts": "aa6d589e567c964c8ba1f582648f3feac45e88ab2e3d2cc2c9f84fd73c05d051", + "https://deno.land/std@0.224.0/io/buffer.ts": "4d1f805f350433e418002accec798bc6c33ce18f614afa65f987c202d7b2234e", + "https://deno.land/std@0.224.0/io/multi_reader.ts": "dd8f06d50adec0e1befb92a1d354fcf28733a4b1669b23bf534ace161ce61b1c", + "https://deno.land/std@0.224.0/io/read_all.ts": "876c1cb20adea15349c72afc86cecd3573335845ae778967aefb5e55fe5a8a4a", + "https://deno.land/x/compress@v0.4.5/deps.ts": "096395daebc7ed8a18f0484e4ffcc3a7f70e50946735f7df9611a7fcfd8272cc", + "https://deno.land/x/compress@v0.4.5/gzip/gzip.ts": "4bf22e9cd3368332928324dd9443ef72cabd05e9234e5a37dd7b3517d50e945e", + "https://deno.land/x/compress@v0.4.5/gzip/gzip_file.ts": "b044ec0df4266c084baa033a4ab5394882e44a86d09d5616636467dcb39c671d", + "https://deno.land/x/compress@v0.4.5/gzip/gzip_stream.ts": "6781cf0e47648e3e5631cba4cc2cd018a24935ce09fdaa86e0cabcf78b5012df", + "https://deno.land/x/compress@v0.4.5/gzip/mod.ts": "4ade8edbe01b54a84f289351e137ebdfc040a74cd616636770cf1724fbf522d1", + "https://deno.land/x/compress@v0.4.5/gzip/writer_gunzip.ts": "5aba34394820b835c414048ac2e15f52d443f1f773ebe61fd2517c938572d616", + "https://deno.land/x/compress@v0.4.5/gzip/writer_gzip.ts": "c7aad0c51ab4f5952c068088186339cfc79a2ee1e057d6e16731b1175f342645", + "https://deno.land/x/compress@v0.4.5/mod.ts": "ae8b15826334021583a5bd1978c63840f85156ea3635f5941bfc6733aad247e5", + "https://deno.land/x/compress@v0.4.5/tar/mod.ts": "6d9073005e678479908047cbe9e4716e484f80d1f2a1e15d3d6ac92213ffaeba", + "https://deno.land/x/compress@v0.4.5/tgz/mod.ts": "2fd4e99f26b57b0055d4d2f87721682304541ed1ca41bbb49c034d121f936f00", + "https://deno.land/x/compress@v0.4.5/utils/uint8.ts": "9c82e09c065f1f4bc648e3b14df441b43a7960fc7bdb29e9fb8d3a69c7e9d425", + "https://deno.land/x/compress@v0.4.5/zlib/deflate.ts": "e1e3b406dcc3e20021e53cde427b4b9ced752b72df820de73fec17c6e5ba999e", + "https://deno.land/x/compress@v0.4.5/zlib/inflate.ts": "618cc3dd25d202bf6b89d92f3ab2865e7495884cafce950638c77cbc1537aeb1", + "https://deno.land/x/compress@v0.4.5/zlib/mod.ts": "4dca9c1e934b7ab27f31c318abd7bfd39b09be96fd76ba27bd46f3a4e73b4ad0", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/adler32.ts": "e34c7596d63a655755c4b0a44a40d4f9c1d1c4d3b891e5c1f3f840f8939e1940", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/crc32.ts": "b9bc4adaf327d32585205d1176bd52f6453c06dd1040544611d4c869e638119c", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/deflate.ts": "8d1dd88630279313e50deed4fe5feefe8128307cc48fa560e659b5234ab09d83", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/gzheader.ts": "11e6da7383447aae9791308dc2350a809fa341a876a2da396b03a2a31408c20c", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/inffast.ts": "282daf5ea16bb876d26e342f3c24fe1a8ec84640e713a970b02232955a853f86", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/inflate.ts": "76751c1a5b18d70a929fa31ce4959db0bde1b9097bfa1b5ea3b4d1fba2ab92fa", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/inftrees.ts": "8a6d765a5c42bf3b6990060cabbe52e88493f8ce6d082e6e35d97756914cfb8e", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/messages.ts": "c82229bd67ccc3b6162f3aca1c5e7f936e546aa91ac9a9ac4fcfefc3a9dc5ac8", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/status.ts": "5987864d2d43d59bbbfa2e6ef4d5a07284c1d10489cc5843ddf41ac547957ac3", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/trees.ts": "6b65a767646e031e87e7b725ffad0c511fe701f393a01652e1e7ee8884f60fee", + "https://deno.land/x/compress@v0.4.5/zlib/zlib/zstream.ts": "c110fd5919235e317d64933852e24a1bba0126202be592e90e58f7b19315ad93", + "https://deno.land/x/crc32@v0.2.0/mod.ts": "de7a3fa2d4ef24b96fc21e1cc4d2d65d1d2b1dcea92f63960e3e11bfa82df0fa", "https://deno.land/x/dirname@1.1.2/types.ts": "c1ed1667545bc4b1d69bdb2fc26a5fa8edae3a56e3081209c16a408a322a2319", "https://lra6z45nakk5lnu3yjchp7tftsdnwwikwr65ocha5eojfnlgu4sa.arweave.net/XEHs860CldW2m8JEd_5lnIbbWQq0fdcI4OkckrVmpyQ/_util/assert.ts": "e1f76e77c5ccb5a8e0dbbbe6cce3a56d2556c8cb5a9a8802fc9565af72462149", "https://lra6z45nakk5lnu3yjchp7tftsdnwwikwr65ocha5eojfnlgu4sa.arweave.net/XEHs860CldW2m8JEd_5lnIbbWQq0fdcI4OkckrVmpyQ/path/_constants.ts": "aba480c4a2c098b6374fdd5951fea13ecc8aaaf8b8aa4dae1871baa50243d676",