Skip to main content

Python bindings for general-sam and some utilities

Project description

general-sam-py

PyPI version License Build status

Python bindings for general-sam and some utilities.

flowchart LR
  init((ε))
  a((a))
  b((b))
  ab((ab))
  bc(((bc)))
  abc((abc))
  abcb((abcb))
  abcbc(((abcbc)))

  init -- a --> a
  init -- b --> b
  a -- b --> ab
  b -- c --> bc
  init -- c --> bc
  ab -- c --> abc
  bc -- b --> abcb
  abc -- b --> abcb
  abcb -- c --> abcbc

The suffix automaton of abcbc.

Installation

pip install general-sam

Usage

GeneralSam

from general_sam import GeneralSam

sam = GeneralSam.from_bytes(b"abcbc")

# "cbc" is a suffix of "abcbc"
state = sam.get_root_state()
state.feed_bytes(b"cbc")
assert state.is_accepting()

# "bcb" is not a suffix of "abcbc"
state = sam.get_root_state()
state.feed_bytes(b"bcb")
assert not state.is_accepting()
from general_sam import GeneralSam

sam = GeneralSam.from_chars("abcbc")
state = sam.get_root_state()

# "b" is not a suffix but at least a substring of "abcbc"
state.feed_chars("b")
assert not state.is_accepting()

# "bc" is a suffix of "abcbc"
state.feed_chars("c")
assert state.is_accepting()

# "bcbc" is a suffix of "abcbc"
state.feed_chars("bc")
assert state.is_accepting()

# "bcbcbc" is not a substring, much less a suffix of "abcbc"
state.feed_chars("bc")
assert not state.is_accepting() and state.is_nil()
from general_sam import GeneralSam, GeneralSamState, build_trie_from_chars

trie, _ = build_trie_from_chars(["hello", "Chielo"])
sam = GeneralSam.from_trie(trie)


def fetch_state(s: str) -> GeneralSamState:
    state = sam.get_root_state()
    state.feed_chars(s)
    return state


assert fetch_state("lo").is_accepting()
assert fetch_state("ello").is_accepting()
assert fetch_state("elo").is_accepting()

state = fetch_state("el")
assert not state.is_accepting() and not state.is_nil()

state = fetch_state("bye")
assert not state.is_accepting() and state.is_nil()

VocabPrefixAutomaton

from general_sam import CountInfo, VocabPrefixAutomaton

vocab = ["歌曲", "聆听歌曲", "播放歌曲", "歌词", "查看歌词"]
automaton = VocabPrefixAutomaton(vocab, bytes_or_chars="chars")

# NOTE: CountInfo instances are actually related to the sorted `vocab`:
_ = ["播放歌曲", "查看歌词", "歌曲", "歌词", "聆听歌曲"]

# Case 1:
#   一起 | 聆 | 听 | 歌
state = automaton.get_root_state()

# prepend '歌'
cnt_info = automaton.prepend_feed(state, "歌")
assert cnt_info is not None and cnt_info == CountInfo(
    str_cnt=2, tot_cnt_lower=2, tot_cnt_upper=4
)

# found '歌曲' at the index 0 and '歌词' at the index 3 prefixed with '歌'
selected_idx = automaton.get_order_slice(cnt_info)
assert frozenset(selected_idx) == {0, 3}
selected_vocab = [vocab[i] for i in selected_idx]
assert frozenset(selected_vocab) == {"歌曲", "歌词"}

# prepend 听
cnt_info = automaton.prepend_feed(state, "听")
# found nothing prefixed with '听歌'
assert cnt_info is None
assert not state.is_nil()

# prepend 聆
cnt_info = automaton.prepend_feed(state, "聆")
assert cnt_info is not None and cnt_info == CountInfo(
    str_cnt=1, tot_cnt_lower=4, tot_cnt_upper=5
)

# found '聆听歌曲' at the index 1 prefixed with '聆听歌'
selected_idx = automaton.get_order_slice(cnt_info)
assert frozenset(selected_idx) == {1}
selected_vocab = [vocab[i] for i in selected_idx]
assert frozenset(selected_vocab) == {"聆听歌曲"}

# prepend 一起
assert not state.is_nil()
# found nothing prefixed with '一起聆听歌'
cnt_info = automaton.prepend_feed(state, "一起")
assert state.is_nil()

# Case 2:
#   来 | 查看 | 歌词
state = automaton.get_root_state()

# prepend 歌词
cnt_info = automaton.prepend_feed(state, "歌词")
assert cnt_info is not None and cnt_info == CountInfo(
    str_cnt=1, tot_cnt_lower=3, tot_cnt_upper=4
)

# found '歌词' at the index 3 prefixed with '歌词'
selected_idx = automaton.get_order_slice(cnt_info)
assert frozenset(selected_idx) == {3}
selected_vocab = [vocab[i] for i in selected_idx]
assert frozenset(selected_vocab) == {"歌词"}

# prepend 查看
cnt_info = automaton.prepend_feed(state, "查看")
assert cnt_info is not None and cnt_info == CountInfo(
    str_cnt=1, tot_cnt_lower=1, tot_cnt_upper=2
)

# found '查看歌词' at the index 4 prefixed with '查看歌词'
selected_idx = automaton.get_order_slice(cnt_info)
assert frozenset(selected_idx) == {4}
selected_vocab = [vocab[i] for i in selected_idx]
assert frozenset(selected_vocab) == {"查看歌词"}

# prepend 来
assert not state.is_nil()
# found nothing prefixed with '来查看歌词'
cnt_info = automaton.prepend_feed(state, "来")
assert state.is_nil()

GreedyTokenizer

from general_sam import GeneralSam, GreedyTokenizer, build_trie_from_chars

vocab = ["a", "ab", "b", "bc", "c", "d", "e", "f", "cd", "abcde"]
trie, token_to_trie_node = build_trie_from_chars(vocab)

trie_node_to_token = [-1] * trie.num_of_nodes()
for i, j in enumerate(token_to_trie_node):
    trie_node_to_token[j] = i

sam = GeneralSam.from_trie(trie)
tokenizer = GreedyTokenizer.from_sam_and_trie(sam, trie)


def tokenize(s: str):
    return [(trie_node_to_token[i], j) for i, j in tokenizer.tokenize_str(s)]


assert tokenize("abcde") == [(9, 5)]
assert tokenize("abcdf") == [(1, 2), (8, 2), (7, 1)]
assert tokenize("abca") == [(1, 2), (4, 1), (0, 1)]

License

This project is licensed under either of

at your option.

The SPDX license identifier for this project is MIT OR Apache-2.0.

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

general_sam-1.0.1.tar.gz (20.9 kB view details)

Uploaded Source

Built Distributions

general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (260.2 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (243.3 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (249.3 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

general_sam-1.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl (226.9 kB view details)

Uploaded PyPy macOS 11.0+ ARM64

general_sam-1.0.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl (238.2 kB view details)

Uploaded PyPy macOS 10.12+ x86-64

general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (260.2 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (243.5 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (249.5 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

general_sam-1.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl (227.0 kB view details)

Uploaded PyPy macOS 11.0+ ARM64

general_sam-1.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl (238.3 kB view details)

Uploaded PyPy macOS 10.12+ x86-64

general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (260.5 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (243.7 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARMv7l

general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (249.8 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

general_sam-1.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl (227.1 kB view details)

Uploaded PyPy macOS 11.0+ ARM64

general_sam-1.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl (238.5 kB view details)

Uploaded PyPy macOS 10.12+ x86-64

general_sam-1.0.1-cp38-abi3-win_amd64.whl (169.2 kB view details)

Uploaded CPython 3.8+ Windows x86-64

general_sam-1.0.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (263.3 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ x86-64

general_sam-1.0.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (245.6 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARMv7l

general_sam-1.0.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (251.6 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARM64

general_sam-1.0.1-cp38-abi3-macosx_11_0_arm64.whl (229.9 kB view details)

Uploaded CPython 3.8+ macOS 11.0+ ARM64

general_sam-1.0.1-cp38-abi3-macosx_10_12_x86_64.whl (241.3 kB view details)

Uploaded CPython 3.8+ macOS 10.12+ x86-64

File details

Details for the file general_sam-1.0.1.tar.gz.

File metadata

  • Download URL: general_sam-1.0.1.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.7.4

File hashes

Hashes for general_sam-1.0.1.tar.gz
Algorithm Hash digest
SHA256 1daa21e4c3d2e3202f1d088b3a0c81f8d7fac1af0522cd75d72529dcd262fb78
MD5 346cd9172c0f48e8552d72e4b0c3cb9b
BLAKE2b-256 802c269b86962aa0291956a0b32952a85708dedcb47907c24affc6de57fa57bc

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cb098a3c076cca9ebeaad756b4e59bfc6a6aa75f685529b5d6dd642bd3298499
MD5 ad98d59e727ebe04be97b3a14f5c6bd8
BLAKE2b-256 1268d7f6536e4b8ca4c9b7094ffebe247e5c7096c013655925cc0a6c6830dc72

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 69eb4f5f402ea857536f1331cb079a87b98a581a79dbfb81c350831d51e182ec
MD5 2c563ee67a51227c403054e5bd1a1388
BLAKE2b-256 47e9b61e775983fc882a341d54dc3be38c7af55588c18fcc39d092f060fc8189

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bb3b05dfdb9b156f735a55c436de68ae0b249fed1edf7179b56ae8e139c5f424
MD5 ee3d96600d59f57fa946d5484fd0b938
BLAKE2b-256 9bd027c16107cf4de4567df5564d1c5910e4998217712418188729f11d38d406

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4e2cf1cfb9c48e2aa68abe8055bf3471456428efb232aeebb40641d306f87383
MD5 651ee8f94b21bd4e42393ffcde8024f0
BLAKE2b-256 ff48b83e146051f67303f1287ebe570e3cf3d30f119ec9afd159c5489a6705ca

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6dc71465213a0c25723040b2c1e518e153460323aeb708924dc69d0c7ff1633c
MD5 2ade37751480528b1713fceecb3fe292
BLAKE2b-256 85629f9d3a5fd24acc3724cac91f456cee86aac1b07db74de6d81be37b288b88

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5433c0c2a31a3cff9d54444f6d786ae54400d1a6f3c0eafb53f8cf6f6c529a57
MD5 925d735b488a7eafe9b9e518e708a8ed
BLAKE2b-256 64972b86954337468e6c61e9a2cd4404c58220d0f1921d943637f9ae47990cb2

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 51cc4d5434a236750042ef1393a637e694df97f6c2feec814ac486a571deddb9
MD5 4564e12ba117b9e119a7256d0382745c
BLAKE2b-256 e8dfbcdca87d1406940eb47043264478dd2890c42774551411f7693d373c8cd3

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e6dbce32fe38a3cc7405aea73666e86719f82c4d1fc0ab13261792d0f9ee9a48
MD5 052e36418b21aa57a6036e89d560879c
BLAKE2b-256 a84fde196688b5e2bbec2e1d4c35b8f36284f568d4b6ac8203da981691b32cb6

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bec22995d4d5ff33aa41528468a0425232b393c56e74ff8a4dafbdd6dda00b16
MD5 510b40f23486083fcfd19e75c66292e2
BLAKE2b-256 ead9eabfb21c2c7442bc441392af83c43c4b7269671042d4b1c5f365c17bc626

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4cedbb0761b4e37a931619f6a617108378259d47ac5d0c05243463ddb9f86bd0
MD5 b1bf7d0741c77ac0c41be4ba36163de7
BLAKE2b-256 a17fd7a9e65c97beb9d363e501a9098f09d590af04b13f4ed337a6beca447672

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cc1eaa8c0b131fa5ff370b0c5ed92556227a83f424ee6600fa590c5893d8dd2a
MD5 be2dc47871fef0cb69cc93398760bff2
BLAKE2b-256 338c4623cc6826e87965b295c25622dcc1554fcfc936d504f1acabe93745a40f

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 8c4036064ef0136a0ae38792e90a266d60c38d8c9fa22cd4afd82d1a87dca1b9
MD5 319eb61aacaa18edde3b09fd9cc641ad
BLAKE2b-256 3d0c9f8cc73d7a45c61679c2d36db48f216dbe3532f0a0a9bcbe1072cadff4a6

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c2d4dbb7b74a0d63db8c611b937451145f4a4855558706cbf4672e83c5474795
MD5 e7916a4e5eba8dc2bbe9c51489cd139d
BLAKE2b-256 2326cfc60a9dff77b7262678e7dba0f4d5f1d763ddf6b4623101ca5c7ab45a85

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5e109fa7b91190088f4073602f2eb71b9f8cd42cbd653f57bf5444cecbd2192a
MD5 fd2ccc796abb2216279fc9b737f5b61e
BLAKE2b-256 a7df84606e4cddfc147748a8f48020b5d1c5d91e60991b5bab7fa307610f2cfe

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 84be021933e9122a16326816978a23b7fa122ecbfe8ed13851fa7e9c9c167a2b
MD5 f8be29ffccd5ec47634fb5cc8fed3b68
BLAKE2b-256 fe95d6e87f4d9d47519739842b0f49779fce15d6442613c641d041b4facc9196

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 702fbddeae255e8e5b86c0be9dd960ed4c03de69cfde82b8eb75b2eae0d171fa
MD5 62b9c317411c00cb8e137b9f9599c90e
BLAKE2b-256 9fa8ab5dfaa15cb5c5ec1de31cf41529965eb78c9cd586829cd4b713caef4ca0

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 bcb61751c71425450d3c2e539bdd59ef44d13b6e0a8ab8383d83e8ad756c108b
MD5 e31606b4921f5b002089691d0b1a5014
BLAKE2b-256 6feef2cce58a7c3c770b4263873c55c4300d22440054c5b49d7b3eac3b898928

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 7742395838fdd22fa34d3f24e20c4a84cb3ddb9ab250b9cca1b4862ab3ab859f
MD5 2e1bfe2312244ee0993a7bd660f8b3a4
BLAKE2b-256 0189629b1bebf801ce284e10a8abd79ef3af86ec31d25c9178415d91ab90d1dd

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c52034ca75e6244be9a162988e98f5b6b816995e60090373e74c81319c1d8e1d
MD5 792f1b362d53530d7daa8573cbff6739
BLAKE2b-256 beddd29847d42f6c66d00f3df07886b2e4f250c86b65ff60b5db4304f91d1804

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7be4b7bd20fafb35e4c6c88416f227b806b0bc7c85deeb6c26607498c33ddb31
MD5 3c99a5e8c38c3d11013baa64d2cfe1b8
BLAKE2b-256 f272e62fb3d138f2110beb6cd930fcc9d14bb347c7b5dded624999edca5db9e3

See more details on using hashes here.

File details

Details for the file general_sam-1.0.1-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for general_sam-1.0.1-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 228d23f33cbe03a9231ca2e2e9d6e4b0588debba83391f677a9e15bed207c363
MD5 121ea5ddd6ad2e4d3ad77cd64693ce66
BLAKE2b-256 91722a74598d8562d4993c32f42cf00f5ae6f138018fcc4a20b9d4e8689bbf7c

See more details on using hashes here.

Supported by

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